From d2a831256f3880af90f65e6301a6a6919824d1ee Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 1 Dec 2025 17:23:01 +0000 Subject: [PATCH 001/108] Add basic project configuration --- .devcontainer/Dockerfile | 30 +++++++++ .devcontainer/devcontainer.json | 36 +++++++++++ .devcontainer/res/.bash_aliases | 1 + .devcontainer/res/.bashrc | 29 +++++++++ .devcontainer/res/post_create_command.bash | 8 +++ .gitignore | 5 ++ .pre-commit-config.yaml | 71 ++++++++++++++++++++++ Changelog.md | 9 +++ justfile | 16 +++++ 9 files changed, 205 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/res/.bash_aliases create mode 100644 .devcontainer/res/.bashrc create mode 100644 .devcontainer/res/post_create_command.bash create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 Changelog.md create mode 100644 justfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..0a9b140 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,30 @@ +# ------------------------------------------------------------------------ +# This file contains the definition of a docker image used in course +# of the development process. The image built from this config contains +# the basic dependencies one needs in order to be able to setup the whole +# environment without installing anything locally on the system. +# ------------------------------------------------------------------------ + +FROM ubuntu:noble + +SHELL ["/bin/bash", "-c"] + +ARG DEBIAN_FRONTEND=noninteractive + +RUN if id ubuntu &>/dev/null; then \ + userdel -r ubuntu || true; \ + groupdel ubuntu || true; \ + fi + +RUN groupadd -g 1000 devcontainer \ + && useradd devcontainer -u 1000 -g 1000 -ms /bin/bash \ + && echo "devcontainer:devcontainer" | chpasswd \ + && usermod -a -G sudo devcontainer + +# Installing the main packages required for a new project's user +# They're necessary to correctly use the project's content +RUN apt update && apt install -y just wget sudo git + +RUN git config --system core.sshCommand /usr/bin/ssh + +RUN chown -R devcontainer:devcontainer /home/devcontainer diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..762d807 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,36 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "Ubuntu_latest", + "build": { + "dockerfile": "Dockerfile" + }, + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" + ], + "workspaceMount": "source=${localWorkspaceFolder}/,target=/home/devcontainer/workspace,type=bind", + "workspaceFolder": "/home/devcontainer/workspace", + "postCreateCommand": "/bin/bash .devcontainer/res/post_create_command.bash", + "customizations": { + "vscode": { + "extensions": [ + "skellock.just", + "ms-python.python", + "ms-python.pylint", + "ms-python.autopep8", + "tamasfe.even-better-toml", + "VisualStudioExptTeam.vscodeintellicode" + ] + } + }, + "runArgs": [ + "--network=host", + "--privileged", + "--volume=/home/${localEnv:USER}/.ssh:/home/devcontainer/.ssh", + ], + "overrideCommand": true, + "remoteUser": "devcontainer", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + } +} \ No newline at end of file diff --git a/.devcontainer/res/.bash_aliases b/.devcontainer/res/.bash_aliases new file mode 100644 index 0000000..d033a0f --- /dev/null +++ b/.devcontainer/res/.bash_aliases @@ -0,0 +1 @@ +alias gitgrlog='git log --pretty=format:"%C(yellow)%h%C(reset) %C(magenta)%cd%C(reset) %C(auto)%d%C(reset) %s" --graph --date=format:"%Y.%m.%d" --decorate=auto' diff --git a/.devcontainer/res/.bashrc b/.devcontainer/res/.bashrc new file mode 100644 index 0000000..5fecf2c --- /dev/null +++ b/.devcontainer/res/.bashrc @@ -0,0 +1,29 @@ + +# -------------------------------------------------------------------------------------- +# Borrowed from the .bashrc configuration of mcr.microsoft.com/devcontainers/base:jammy +# -------------------------------------------------------------------------------------- + +__bash_prompt() { + local userpart='`export XIT=$? \ + && [ ! -z "${GITHUB_USER}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER} " || echo -n "\[\033[0;32m\]\u " \ + && [ "$XIT" -ne "0" ] && echo -n "\[\033[1;31m\]➜" || echo -n "\[\033[0m\]➜"`' + local gitbranch='`\ + if [ "$(git config --get devcontainers-theme.hide-status 2>/dev/null)" != 1 ] && [ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ]; then \ + export BRANCH=$(git --no-optional-locks symbolic-ref --short HEAD 2>/dev/null || git --no-optional-locks rev-parse --short HEAD 2>/dev/null); \ + if [ "${BRANCH}" != "" ]; then \ + echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \ + && if [ "$(git config --get devcontainers-theme.show-dirty 2>/dev/null)" = 1 ] && \ + git --no-optional-locks ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \ + echo -n " \[\033[1;33m\]✗"; \ + fi \ + && echo -n "\[\033[0;36m\]) "; \ + fi; \ + fi`' + local lightblue='\[\033[1;34m\]' + local removecolor='\[\033[0m\]' + PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ " + unset -f __bash_prompt +} +__bash_prompt + +export PATH=/home/$USER/.local/bin:$PATH diff --git a/.devcontainer/res/post_create_command.bash b/.devcontainer/res/post_create_command.bash new file mode 100644 index 0000000..607883b --- /dev/null +++ b/.devcontainer/res/post_create_command.bash @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script should be run after the devcontainer is created. +# It's role is to establish the necessary environment for the +# user to start developing. + +cat .devcontainer/res/.bash_aliases >> ~/.bash_aliases +cat .devcontainer/res/.bashrc >> ~/.bashrc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7313dff --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vscode/ +**/__pycache__/ +persistent_data/ +.venv/ +.mypy_cache/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f424500 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,71 @@ +--- +# ---------------------------------------------------------------------------------- +# This file contains pre-commit hooks containing rules under which the project files +# should be checked. +# ---------------------------------------------------------------------------------- + +exclude: .*/torchkan\.py +repos: + # A set of pre-commit hooks checking various file's features. + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-docstring-first + - id: check-added-large-files + - id: check-yaml + - id: debug-statements + - id: double-quote-string-fixer + - id: check-executables-have-shebangs + + # Checks whether the python code's syntax conforms to the conventions of newer python versions. + - repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 + hooks: + - id: pyupgrade + + # Makes sure the python code's format conforms to the PEP8 style guide. + - repo: local + hooks: + - id: autopep8 + name: autopep8 + entry: autopep8 + language: system + types: [python] + + # Makes sure the python variables are used according to their types. + - repo: local + hooks: + - id: mypy + name: mypy + entry: mypy + language: system + types: [python] + args: [--python-executable, .venv/bin/python] + + # Checks whether the code is accepted by the pylint checker. + - repo: local + hooks: + - id: pylint + name: pylint + entry: pylint + language: system + types: [python] + args: + - --rcfile=pyproject.toml + + # Checks whether the python import statements are properly sorted. + - repo: https://github.com/asottile/reorder-python-imports + rev: v3.12.0 + hooks: + - id: reorder-python-imports + args: + - --application-directories=.:src + + # Ensures yaml files are formatted + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt + rev: 0.2.3 + hooks: + - id: yamlfmt + args: [--mapping, '2', --sequence, '4', --offset, '2'] diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..875b717 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,9 @@ +# Changelog + +### 0.1 + +- Established initial project structure +- Introduced first modules: + - web application + - entrypoint backend +- Added development configuration diff --git a/justfile b/justfile new file mode 100644 index 0000000..f7edd83 --- /dev/null +++ b/justfile @@ -0,0 +1,16 @@ +# -------------------------------------------------- +# This file contains setup scripts for the project. +# For more info, see: https://github.com/casey/just +# -------------------------------------------------- + +set shell := ["bash", "-c"] + +# Run static repository checks +run-pre-commit: + uv run pre-commit run --all-files + +# Set up environment and install dependencies +setup-dev: + uv venv + uv sync --project . --extra dev + From 097596c003a568a1e77325f3f4fd8127af1b89c1 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Mon, 1 Dec 2025 19:46:41 +0100 Subject: [PATCH 002/108] added first sub devcontainer --- .devcontainer/Dockerfile | 30 --------- .devcontainer/api-gateway/Dockerfile | 24 +++++++ .devcontainer/api-gateway/devcontainer.json | 34 ++++++++++ .devcontainer/base/Dockerfile | 23 +++++++ .devcontainer/devcontainer.json | 70 ++++++++++----------- .devcontainer/scripts/base-setup.sh | 49 +++++++++++++++ services/api-gateway/app/main.py | 40 ++++++++++++ services/api-gateway/requirements.txt | 4 ++ 8 files changed, 209 insertions(+), 65 deletions(-) delete mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/api-gateway/Dockerfile create mode 100644 .devcontainer/api-gateway/devcontainer.json create mode 100644 .devcontainer/base/Dockerfile create mode 100755 .devcontainer/scripts/base-setup.sh create mode 100644 services/api-gateway/app/main.py create mode 100644 services/api-gateway/requirements.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 0a9b140..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -# ------------------------------------------------------------------------ -# This file contains the definition of a docker image used in course -# of the development process. The image built from this config contains -# the basic dependencies one needs in order to be able to setup the whole -# environment without installing anything locally on the system. -# ------------------------------------------------------------------------ - -FROM ubuntu:noble - -SHELL ["/bin/bash", "-c"] - -ARG DEBIAN_FRONTEND=noninteractive - -RUN if id ubuntu &>/dev/null; then \ - userdel -r ubuntu || true; \ - groupdel ubuntu || true; \ - fi - -RUN groupadd -g 1000 devcontainer \ - && useradd devcontainer -u 1000 -g 1000 -ms /bin/bash \ - && echo "devcontainer:devcontainer" | chpasswd \ - && usermod -a -G sudo devcontainer - -# Installing the main packages required for a new project's user -# They're necessary to correctly use the project's content -RUN apt update && apt install -y just wget sudo git - -RUN git config --system core.sshCommand /usr/bin/ssh - -RUN chown -R devcontainer:devcontainer /home/devcontainer diff --git a/.devcontainer/api-gateway/Dockerfile b/.devcontainer/api-gateway/Dockerfile new file mode 100644 index 0000000..50de3d6 --- /dev/null +++ b/.devcontainer/api-gateway/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:noble + +SHELL ["/bin/bash", "-c"] + +ARG USERNAME=devcontainer +ARG USER_UID=1000 +ARG USER_GID=1000 + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN chmod +x /tmp/base-setup.sh && \ + USERNAME=${USERNAME} USER_UID=${USER_UID} USER_GID=${USER_GID} /tmp/base-setup.sh && \ + rm /tmp/base-setup.sh + +USER root +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + python3 \ + python3-pip && \ + rm -rf /var/lib/apt/lists/* + +USER ${USERNAME} +WORKDIR /home/${USERNAME}/workspace +ENV PATH="/home/devcontainer/.local/bin:${PATH}" + diff --git a/.devcontainer/api-gateway/devcontainer.json b/.devcontainer/api-gateway/devcontainer.json new file mode 100644 index 0000000..5f49a9a --- /dev/null +++ b/.devcontainer/api-gateway/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "api-gateway", + "build": { + "dockerfile": "Dockerfile", + "context": "../.." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/home/devcontainer/workspace,type=bind", + "workspaceFolder": "/home/devcontainer/workspace/services/api-gateway", + + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/devcontainer/.ssh,readonly=true" + ], + + "runArgs": [ + "--name=api-gateway" + ], + + "remoteUser": "devcontainer", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + + "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", + "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + + + "forwardPorts": [8000] +} + diff --git a/.devcontainer/base/Dockerfile b/.devcontainer/base/Dockerfile new file mode 100644 index 0000000..f6f1992 --- /dev/null +++ b/.devcontainer/base/Dockerfile @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------ +# This file contains the definition of a docker image used in course +# of the development process. The image built from this config contains +# the basic dependencies one needs in order to be able to setup the whole +# environment without installing anything locally on the system. +# ------------------------------------------------------------------------ + +FROM ubuntu:noble + +SHELL ["/bin/bash", "-c"] + +ARG USERNAME=devcontainer +ARG USER_UID=1000 +ARG USER_GID=1000 + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh + +RUN chmod +x /tmp/base-setup.sh && \ + USERNAME=${USERNAME} USER_UID=${USER_UID} USER_GID=${USER_GID} /tmp/base-setup.sh && \ + rm /tmp/base-setup.sh + +WORKDIR /home/${USERNAME}/workspace +USER ${USERNAME} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 762d807..9c4542d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,36 +1,36 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu { - "name": "Ubuntu_latest", - "build": { - "dockerfile": "Dockerfile" - }, - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" - ], - "workspaceMount": "source=${localWorkspaceFolder}/,target=/home/devcontainer/workspace,type=bind", - "workspaceFolder": "/home/devcontainer/workspace", - "postCreateCommand": "/bin/bash .devcontainer/res/post_create_command.bash", - "customizations": { - "vscode": { - "extensions": [ - "skellock.just", - "ms-python.python", - "ms-python.pylint", - "ms-python.autopep8", - "tamasfe.even-better-toml", - "VisualStudioExptTeam.vscodeintellicode" - ] - } - }, - "runArgs": [ - "--network=host", - "--privileged", - "--volume=/home/${localEnv:USER}/.ssh:/home/devcontainer/.ssh", - ], - "overrideCommand": true, - "remoteUser": "devcontainer", - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - } -} \ No newline at end of file + "name": "base", + "build": { + "dockerfile": "base/Dockerfile", // <== we’ll create this next + "context": ".." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/home/devcontainer/workspace,type=bind", + "workspaceFolder": "/home/devcontainer/workspace", + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/devcontainer/.ssh,readonly=true" + ], + + "remoteUser": "devcontainer", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + "postCreateCommand": "/bin/bash .devcontainer/res/post_create_command.bash", + + "customizations": { + "vscode": { + "extensions": [ + "skellock.just", + "ms-python.python", + "ms-python.pylint", + "ms-python.autopep8", + "tamasfe.even-better-toml", + "VisualStudioExptTeam.vscodeintellicode" + ] + } + } +} diff --git a/.devcontainer/scripts/base-setup.sh b/.devcontainer/scripts/base-setup.sh new file mode 100755 index 0000000..6c3d51b --- /dev/null +++ b/.devcontainer/scripts/base-setup.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -euo pipefail + +USERNAME="${USERNAME:-devcontainer}" +USER_UID="${USER_UID:-1000}" +USER_GID="${USER_GID:-1000}" + +export DEBIAN_FRONTEND=noninteractive + +# Basic sanity: remove default ubuntu user if present +if id ubuntu &>/dev/null; then + userdel -r ubuntu || true + groupdel ubuntu || true +fi + +# Create group & user +if ! getent group "${USER_GID}" >/dev/null 2>&1; then + groupadd -g "${USER_GID}" "${USERNAME}" +fi + +if ! id "${USERNAME}" >/dev/null 2>&1; then + useradd -m -s /bin/bash -u "${USER_UID}" -g "${USER_GID}" "${USERNAME}" +fi + +# sudo, but no password prompts inside the container +apt-get update +apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + wget \ + git \ + sudo \ + just \ + openssh-client \ + jq \ + python3 \ + python3-pip + +rm -rf /var/lib/apt/lists/* + +usermod -aG sudo "${USERNAME}" +echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/${USERNAME}" +chmod 440 "/etc/sudoers.d/${USERNAME}" + +git config --system core.sshCommand /usr/bin/ssh + +chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}" +mkdir -p "/home/${USERNAME}/workspace" +chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}/workspace" diff --git a/services/api-gateway/app/main.py b/services/api-gateway/app/main.py new file mode 100644 index 0000000..94c8791 --- /dev/null +++ b/services/api-gateway/app/main.py @@ -0,0 +1,40 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +import httpx + +CORE_SERVICE_URL = "http://core-service:8000/query" + + +class AskRequest(BaseModel): + query: str + + +class AskResponse(BaseModel): + answer: str + + +app = FastAPI(title="API Gateway") + + +@app.get("/health") +async def health() -> dict: + return {"status": "ok"} + + +@app.post("/ask", response_model=AskResponse) +async def ask(payload: AskRequest) -> AskResponse: + try: + async with httpx.AsyncClient() as client: + response = await client.post(CORE_SERVICE_URL, json=payload.dict()) + response.raise_for_status() + except httpx.HTTPError as exc: # pragma: no cover - placeholder error handling + raise HTTPException(status_code=502, detail=f"core-service error: {exc}") from exc + + data = response.json() + return AskResponse(answer=data.get("answer", "")) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/api-gateway/requirements.txt b/services/api-gateway/requirements.txt new file mode 100644 index 0000000..55e411b --- /dev/null +++ b/services/api-gateway/requirements.txt @@ -0,0 +1,4 @@ +fastapi +uvicorn +pydantic +httpx From 55d0ece9f316dc4ceb884106e8a71089e3794b5d Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Mon, 1 Dec 2025 21:11:07 +0100 Subject: [PATCH 003/108] fix persistent dependencies --- .devcontainer/api-gateway/Dockerfile | 17 ++++++++++++++--- .devcontainer/api-gateway/devcontainer.json | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.devcontainer/api-gateway/Dockerfile b/.devcontainer/api-gateway/Dockerfile index 50de3d6..da82aea 100644 --- a/.devcontainer/api-gateway/Dockerfile +++ b/.devcontainer/api-gateway/Dockerfile @@ -15,10 +15,21 @@ USER root RUN apt-get update && \ apt-get install -y --no-install-recommends \ python3 \ - python3-pip && \ - rm -rf /var/lib/apt/lists/* + python3-pip \ + python3-venv \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /home/${USERNAME}/workspace/services/api-gateway + +COPY services/api-gateway/requirements.txt ./requirements.txt + +RUN python3 -m venv /opt/venv \ + && /opt/venv/bin/pip install --no-cache-dir -r requirements.txt + +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:${PATH}" USER ${USERNAME} WORKDIR /home/${USERNAME}/workspace -ENV PATH="/home/devcontainer/.local/bin:${PATH}" +ENV PATH="/home/devcontainer/.local/bin:${PATH}" diff --git a/.devcontainer/api-gateway/devcontainer.json b/.devcontainer/api-gateway/devcontainer.json index 5f49a9a..abcaaf0 100644 --- a/.devcontainer/api-gateway/devcontainer.json +++ b/.devcontainer/api-gateway/devcontainer.json @@ -25,7 +25,7 @@ "overrideCommand": true, - "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", + "postCreateCommand": "", "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", From eb1bbb52b3f795ffbab44f6e3e8cff4fc05bb9d2 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Fri, 5 Dec 2025 12:55:26 +0100 Subject: [PATCH 004/108] services dev config --- .devcontainer/api-gateway/Dockerfile | 35 --------------- .devcontainer/api-gateway/devcontainer.json | 22 ++++------ .devcontainer/base/Dockerfile | 44 ++++++++++++------- .devcontainer/core-service/devcontainer.json | 28 ++++++++++++ .devcontainer/devcontainer.json | 2 +- .../embedder-service/devcontainer.json | 30 +++++++++++++ .../ingestion-service/devcontainer.json | 30 +++++++++++++ .devcontainer/llm-proxy/devcontainer.json | 30 +++++++++++++ .devcontainer/scripts/base-setup.sh | 43 ++---------------- docker-compose.yml | 28 ++++++++++++ services/api-gateway/Dockerfile | 13 ++++++ services/core-service/Dockerfile | 13 ++++++ services/core-service/app/main.py | 29 ++++++++++++ services/core-service/requirements.txt | 3 ++ services/embedder-service/Dockerfile | 13 ++++++ services/embedder-service/app/main.py | 26 +++++++++++ services/embedder-service/requirements.txt | 3 ++ services/ingestion-service/Dockerfile | 13 ++++++ services/ingestion-service/app/main.py | 32 ++++++++++++++ services/ingestion-service/requirements.txt | 3 ++ services/llm-proxy/Dockerfile | 13 ++++++ services/llm-proxy/app/main.py | 24 ++++++++++ services/llm-proxy/requirements.txt | 3 ++ 23 files changed, 377 insertions(+), 103 deletions(-) delete mode 100644 .devcontainer/api-gateway/Dockerfile create mode 100644 .devcontainer/core-service/devcontainer.json create mode 100644 .devcontainer/embedder-service/devcontainer.json create mode 100644 .devcontainer/ingestion-service/devcontainer.json create mode 100644 .devcontainer/llm-proxy/devcontainer.json create mode 100644 docker-compose.yml create mode 100644 services/api-gateway/Dockerfile create mode 100644 services/core-service/Dockerfile create mode 100644 services/core-service/app/main.py create mode 100644 services/core-service/requirements.txt create mode 100644 services/embedder-service/Dockerfile create mode 100644 services/embedder-service/app/main.py create mode 100644 services/embedder-service/requirements.txt create mode 100644 services/ingestion-service/Dockerfile create mode 100644 services/ingestion-service/app/main.py create mode 100644 services/ingestion-service/requirements.txt create mode 100644 services/llm-proxy/Dockerfile create mode 100644 services/llm-proxy/app/main.py create mode 100644 services/llm-proxy/requirements.txt diff --git a/.devcontainer/api-gateway/Dockerfile b/.devcontainer/api-gateway/Dockerfile deleted file mode 100644 index da82aea..0000000 --- a/.devcontainer/api-gateway/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM ubuntu:noble - -SHELL ["/bin/bash", "-c"] - -ARG USERNAME=devcontainer -ARG USER_UID=1000 -ARG USER_GID=1000 - -COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh -RUN chmod +x /tmp/base-setup.sh && \ - USERNAME=${USERNAME} USER_UID=${USER_UID} USER_GID=${USER_GID} /tmp/base-setup.sh && \ - rm /tmp/base-setup.sh - -USER root -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - python3 \ - python3-pip \ - python3-venv \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /home/${USERNAME}/workspace/services/api-gateway - -COPY services/api-gateway/requirements.txt ./requirements.txt - -RUN python3 -m venv /opt/venv \ - && /opt/venv/bin/pip install --no-cache-dir -r requirements.txt - -ENV VIRTUAL_ENV=/opt/venv -ENV PATH="$VIRTUAL_ENV/bin:${PATH}" - -USER ${USERNAME} -WORKDIR /home/${USERNAME}/workspace - -ENV PATH="/home/devcontainer/.local/bin:${PATH}" diff --git a/.devcontainer/api-gateway/devcontainer.json b/.devcontainer/api-gateway/devcontainer.json index abcaaf0..66d1902 100644 --- a/.devcontainer/api-gateway/devcontainer.json +++ b/.devcontainer/api-gateway/devcontainer.json @@ -1,34 +1,30 @@ { "name": "api-gateway", + "build": { - "dockerfile": "Dockerfile", + "dockerfile": "../base/Dockerfile", "context": "../.." }, - "workspaceMount": "source=${localWorkspaceFolder},target=/home/devcontainer/workspace,type=bind", - "workspaceFolder": "/home/devcontainer/workspace/services/api-gateway", - + "workspaceMount": "source=${localWorkspaceFolder},target=/home/base/workspace,type=bind", + "workspaceFolder": "/home/base/workspace", "mounts": [ "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/devcontainer/.ssh,readonly=true" + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/base/.ssh,readonly=true", + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" ], - "runArgs": [ - "--name=api-gateway" - ], - - "remoteUser": "devcontainer", + "remoteUser": "base", "remoteEnv": { "SSH_AUTH_SOCK": "/ssh-agent" }, "overrideCommand": true, - "postCreateCommand": "", - "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + "postCreateCommand": "pip install --break-system-packages -r services/api-gateway/requirements.txt", + "postStartCommand": "uvicorn services.api-gateway.app.main:app --host 0.0.0.0 --port 8000", "forwardPorts": [8000] } - diff --git a/.devcontainer/base/Dockerfile b/.devcontainer/base/Dockerfile index f6f1992..8b8d947 100644 --- a/.devcontainer/base/Dockerfile +++ b/.devcontainer/base/Dockerfile @@ -1,23 +1,37 @@ -# ------------------------------------------------------------------------ -# This file contains the definition of a docker image used in course -# of the development process. The image built from this config contains -# the basic dependencies one needs in order to be able to setup the whole -# environment without installing anything locally on the system. -# ------------------------------------------------------------------------ - FROM ubuntu:noble SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive -ARG USERNAME=devcontainer -ARG USER_UID=1000 -ARG USER_GID=1000 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + wget \ + git \ + sudo \ + just \ + openssh-client \ + jq \ + python3 \ + python3-pip \ + docker.io \ + && rm -rf /var/lib/apt/lists/* -COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN pip3 install --no-cache-dir --break-system-packages docker-compose -RUN chmod +x /tmp/base-setup.sh && \ - USERNAME=${USERNAME} USER_UID=${USER_UID} USER_GID=${USER_GID} /tmp/base-setup.sh && \ - rm /tmp/base-setup.sh +ARG USERNAME=base + +RUN if ! id "${USERNAME}" >/dev/null 2>&1; then \ + groupadd "${USERNAME}" || true; \ + useradd -m -s /bin/bash -g "${USERNAME}" "${USERNAME}"; \ + fi + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN chmod +x /tmp/base-setup.sh \ + && USERNAME="${USERNAME}" /tmp/base-setup.sh \ + && rm /tmp/base-setup.sh -WORKDIR /home/${USERNAME}/workspace USER ${USERNAME} +WORKDIR /home/${USERNAME}/workspace +ENV PATH="/home/${USERNAME}/.local/bin:${PATH}" diff --git a/.devcontainer/core-service/devcontainer.json b/.devcontainer/core-service/devcontainer.json new file mode 100644 index 0000000..4aed78e --- /dev/null +++ b/.devcontainer/core-service/devcontainer.json @@ -0,0 +1,28 @@ +{ + "name": "core-service", + "build": { + "dockerfile": "../base/Dockerfile", + "context": "../.." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace/services/core-service", + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" + ], + + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + + "postCreateCommand": "pip install --break-system-packages -r requirements.txt", + + "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + + "forwardPorts": [8000] +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9c4542d..a6bb8a7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ { "name": "base", "build": { - "dockerfile": "base/Dockerfile", // <== we’ll create this next + "dockerfile": "base/Dockerfile", "context": ".." }, diff --git a/.devcontainer/embedder-service/devcontainer.json b/.devcontainer/embedder-service/devcontainer.json new file mode 100644 index 0000000..09a65cf --- /dev/null +++ b/.devcontainer/embedder-service/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "embedder-service", + "build": { + "dockerfile": "../base/Dockerfile", + "context": "../.." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace/services/embedder-service", + + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" + ], + + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + + "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", + "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + + + "forwardPorts": [8000] +} + diff --git a/.devcontainer/ingestion-service/devcontainer.json b/.devcontainer/ingestion-service/devcontainer.json new file mode 100644 index 0000000..c69fb9a --- /dev/null +++ b/.devcontainer/ingestion-service/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "ingestion-service", + "build": { + "dockerfile": "../base/Dockerfile", + "context": "../.." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace/services/ingestion-service", + + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" + ], + + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + + "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", + "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + + + "forwardPorts": [8000] +} + diff --git a/.devcontainer/llm-proxy/devcontainer.json b/.devcontainer/llm-proxy/devcontainer.json new file mode 100644 index 0000000..cd4651a --- /dev/null +++ b/.devcontainer/llm-proxy/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "llm-proxy", + "build": { + "dockerfile": "../base/Dockerfile", + "context": "../.." + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace/services/llm-proxy", + + + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", + "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" + ], + + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent" + }, + + "overrideCommand": true, + + "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", + "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", + + + "forwardPorts": [8000] +} + diff --git a/.devcontainer/scripts/base-setup.sh b/.devcontainer/scripts/base-setup.sh index 6c3d51b..868a545 100755 --- a/.devcontainer/scripts/base-setup.sh +++ b/.devcontainer/scripts/base-setup.sh @@ -1,49 +1,14 @@ -#!/usr/bin/env bash set -euo pipefail -USERNAME="${USERNAME:-devcontainer}" -USER_UID="${USER_UID:-1000}" -USER_GID="${USER_GID:-1000}" +USERNAME="${USERNAME:-base}" -export DEBIAN_FRONTEND=noninteractive - -# Basic sanity: remove default ubuntu user if present -if id ubuntu &>/dev/null; then - userdel -r ubuntu || true - groupdel ubuntu || true -fi - -# Create group & user -if ! getent group "${USER_GID}" >/dev/null 2>&1; then - groupadd -g "${USER_GID}" "${USERNAME}" -fi - -if ! id "${USERNAME}" >/dev/null 2>&1; then - useradd -m -s /bin/bash -u "${USER_UID}" -g "${USER_GID}" "${USERNAME}" +if ! id "${USERNAME}" &>/dev/null; then + echo "User '${USERNAME}' does not exist. Create it in the Dockerfile before running this script." >&2 + exit 1 fi -# sudo, but no password prompts inside the container -apt-get update -apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - wget \ - git \ - sudo \ - just \ - openssh-client \ - jq \ - python3 \ - python3-pip - -rm -rf /var/lib/apt/lists/* - usermod -aG sudo "${USERNAME}" echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/${USERNAME}" chmod 440 "/etc/sudoers.d/${USERNAME}" git config --system core.sshCommand /usr/bin/ssh - -chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}" -mkdir -p "/home/${USERNAME}/workspace" -chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}/workspace" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..10e7f15 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +version: "3.9" + +services: + core-service: + build: + context: . + dockerfile: services/core-service/Dockerfile + container_name: core-service + ports: + - "8001:8000" + networks: + - rag-net + + api-gateway: + build: + context: . + dockerfile: services/api-gateway/Dockerfile + container_name: api-gateway + ports: + - "8080:8000" + depends_on: + - core-service + networks: + - rag-net + +networks: + rag-net: + driver: bridge diff --git a/services/api-gateway/Dockerfile b/services/api-gateway/Dockerfile new file mode 100644 index 0000000..aab9551 --- /dev/null +++ b/services/api-gateway/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential + +COPY services/api-gateway/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY services/api-gateway/app /app/app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/core-service/Dockerfile b/services/core-service/Dockerfile new file mode 100644 index 0000000..2d532c0 --- /dev/null +++ b/services/core-service/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential + +COPY services/core-service/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY services/core-service/app /app/app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/core-service/app/main.py b/services/core-service/app/main.py new file mode 100644 index 0000000..a20b23c --- /dev/null +++ b/services/core-service/app/main.py @@ -0,0 +1,29 @@ +from fastapi import FastAPI +from pydantic import BaseModel + + +class QueryRequest(BaseModel): + query: str + + +class QueryResponse(BaseModel): + answer: str + + +def run_query(query: str) -> str: + return f"dummy answer for: {query}" + + +app = FastAPI(title="Core Service") + + +@app.post("/query", response_model=QueryResponse) +async def query(payload: QueryRequest) -> QueryResponse: + answer = run_query(payload.query) + return QueryResponse(answer=answer) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/core-service/requirements.txt b/services/core-service/requirements.txt new file mode 100644 index 0000000..c9b6004 --- /dev/null +++ b/services/core-service/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +pydantic diff --git a/services/embedder-service/Dockerfile b/services/embedder-service/Dockerfile new file mode 100644 index 0000000..55d468d --- /dev/null +++ b/services/embedder-service/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential + +COPY services/embedder-service/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY services/embedder-service/app /app/app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/embedder-service/app/main.py b/services/embedder-service/app/main.py new file mode 100644 index 0000000..bf52c4e --- /dev/null +++ b/services/embedder-service/app/main.py @@ -0,0 +1,26 @@ +from typing import List +from fastapi import FastAPI +from pydantic import BaseModel + + +class EmbedRequest(BaseModel): + texts: List[str] + + +class EmbedResponse(BaseModel): + embeddings: List[List[float]] + + +app = FastAPI(title="Embedder Service") + + +@app.post("/embed", response_model=EmbedResponse) +async def embed(payload: EmbedRequest) -> EmbedResponse: + embeddings = [[float(len(text))] for text in payload.texts] + return EmbedResponse(embeddings=embeddings) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/embedder-service/requirements.txt b/services/embedder-service/requirements.txt new file mode 100644 index 0000000..c9b6004 --- /dev/null +++ b/services/embedder-service/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +pydantic diff --git a/services/ingestion-service/Dockerfile b/services/ingestion-service/Dockerfile new file mode 100644 index 0000000..c04f8c8 --- /dev/null +++ b/services/ingestion-service/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential + +COPY services/ingestion-service/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY services/ingestion-service/app /app/app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/ingestion-service/app/main.py b/services/ingestion-service/app/main.py new file mode 100644 index 0000000..f8d39ec --- /dev/null +++ b/services/ingestion-service/app/main.py @@ -0,0 +1,32 @@ +import logging +from typing import List +from fastapi import FastAPI +from pydantic import BaseModel + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +class IngestRequest(BaseModel): + documents: List[str] + + +class IngestResponse(BaseModel): + ingested: int + status: str + + +app = FastAPI(title="Ingestion Service") + + +@app.post("/ingest", response_model=IngestResponse) +async def ingest(payload: IngestRequest) -> IngestResponse: + count = len(payload.documents) + logger.info("Received %s documents for ingestion", count) + return IngestResponse(ingested=count, status="ok") + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/ingestion-service/requirements.txt b/services/ingestion-service/requirements.txt new file mode 100644 index 0000000..c9b6004 --- /dev/null +++ b/services/ingestion-service/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +pydantic diff --git a/services/llm-proxy/Dockerfile b/services/llm-proxy/Dockerfile new file mode 100644 index 0000000..8aaa0cf --- /dev/null +++ b/services/llm-proxy/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential + +COPY services/llm-proxy/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY services/llm-proxy/app /app/app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/llm-proxy/app/main.py b/services/llm-proxy/app/main.py new file mode 100644 index 0000000..f05569d --- /dev/null +++ b/services/llm-proxy/app/main.py @@ -0,0 +1,24 @@ +from fastapi import FastAPI +from pydantic import BaseModel + + +class GenerateRequest(BaseModel): + prompt: str + + +class GenerateResponse(BaseModel): + output: str + + +app = FastAPI(title="LLM Proxy") + + +@app.post("/generate", response_model=GenerateResponse) +async def generate(payload: GenerateRequest) -> GenerateResponse: + return GenerateResponse(output=f"LLM output for: {payload.prompt}") + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/llm-proxy/requirements.txt b/services/llm-proxy/requirements.txt new file mode 100644 index 0000000..c9b6004 --- /dev/null +++ b/services/llm-proxy/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +pydantic From 5cb197072d023b0302cceefc727f1845cfa8ec32 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 12:11:59 +0100 Subject: [PATCH 005/108] Add changes to the root Devcontainer Modified the docker setup configuration Updated pre-commit hooks and added pyproject.toml config --- .devcontainer/base/Dockerfile | 27 ++------- .devcontainer/{ => base}/devcontainer.json | 23 +++++--- .devcontainer/scripts/base-setup.sh | 4 +- .pre-commit-config.yaml | 65 +++++++++++----------- Changelog.md | 8 --- pyproject.toml | 23 ++++++++ 6 files changed, 79 insertions(+), 71 deletions(-) rename .devcontainer/{ => base}/devcontainer.json (61%) create mode 100644 pyproject.toml diff --git a/.devcontainer/base/Dockerfile b/.devcontainer/base/Dockerfile index 8b8d947..42ae3fe 100644 --- a/.devcontainer/base/Dockerfile +++ b/.devcontainer/base/Dockerfile @@ -5,33 +5,16 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y --no-install-recommends \ - ca-certificates \ curl \ wget \ git \ - sudo \ - just \ openssh-client \ - jq \ - python3 \ - python3-pip \ - docker.io \ - && rm -rf /var/lib/apt/lists/* - -RUN pip3 install --no-cache-dir --break-system-packages docker-compose - -ARG USERNAME=base - -RUN if ! id "${USERNAME}" >/dev/null 2>&1; then \ - groupadd "${USERNAME}" || true; \ - useradd -m -s /bin/bash -g "${USERNAME}" "${USERNAME}"; \ - fi + sudo \ + just COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh RUN chmod +x /tmp/base-setup.sh \ - && USERNAME="${USERNAME}" /tmp/base-setup.sh \ - && rm /tmp/base-setup.sh + && USERNAME="ubuntu" /tmp/base-setup.sh -USER ${USERNAME} -WORKDIR /home/${USERNAME}/workspace -ENV PATH="/home/${USERNAME}/.local/bin:${PATH}" +USER ubuntu +WORKDIR /home/ubuntu/workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/base/devcontainer.json similarity index 61% rename from .devcontainer/devcontainer.json rename to .devcontainer/base/devcontainer.json index a6bb8a7..46414d9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/base/devcontainer.json @@ -1,21 +1,28 @@ { "name": "base", "build": { - "dockerfile": "base/Dockerfile", - "context": ".." + "dockerfile": "Dockerfile", + "context": "../.." }, - "workspaceMount": "source=${localWorkspaceFolder},target=/home/devcontainer/workspace,type=bind", - "workspaceFolder": "/home/devcontainer/workspace", + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "version": "latest", + "moby": false + } + }, + + "workspaceMount": "source=${localWorkspaceFolder},target=/home/ubuntu/workspace,type=bind", + "workspaceFolder": "/home/ubuntu/workspace", "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/devcontainer/.ssh,readonly=true" + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" ], - "remoteUser": "devcontainer", + "remoteUser": "ubuntu", "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" + "SSH_AUTH_SOCK": "/ssh-agent", + "GIT_CONFIG_GLOBAL": "/home/ubuntu/.gitconfig" }, "overrideCommand": true, diff --git a/.devcontainer/scripts/base-setup.sh b/.devcontainer/scripts/base-setup.sh index 868a545..094ce75 100755 --- a/.devcontainer/scripts/base-setup.sh +++ b/.devcontainer/scripts/base-setup.sh @@ -1,6 +1,6 @@ -set -euo pipefail +#!/bin/bash -USERNAME="${USERNAME:-base}" +set -euo pipefail if ! id "${USERNAME}" &>/dev/null; then echo "User '${USERNAME}' does not exist. Create it in the Dockerfile before running this script." >&2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f424500..e710fb5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,6 @@ --- -# ---------------------------------------------------------------------------------- -# This file contains pre-commit hooks containing rules under which the project files -# should be checked. -# ---------------------------------------------------------------------------------- - -exclude: .*/torchkan\.py repos: - # A set of pre-commit hooks checking various file's features. + # Official pre-commit hooks - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: @@ -18,14 +12,10 @@ repos: - id: debug-statements - id: double-quote-string-fixer - id: check-executables-have-shebangs + - id: detect-private-key + - id: check-case-conflict - # Checks whether the python code's syntax conforms to the conventions of newer python versions. - - repo: https://github.com/asottile/pyupgrade - rev: v3.21.2 - hooks: - - id: pyupgrade - - # Makes sure the python code's format conforms to the PEP8 style guide. + # Ensures Python files are formatted using autopep8 formatter - repo: local hooks: - id: autopep8 @@ -33,18 +23,25 @@ repos: entry: autopep8 language: system types: [python] + args: + - "--in-place" + - "--aggressive" + - "--exit-code" + - "--max-line-length=100" - # Makes sure the python variables are used according to their types. - - repo: local + # Ensures python files are written using modern syntax + - repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 hooks: - - id: mypy - name: mypy - entry: mypy - language: system - types: [python] - args: [--python-executable, .venv/bin/python] + - id: pyupgrade - # Checks whether the code is accepted by the pylint checker. + # Ensures python imports are sorted according to (std, external, own) rule + - repo: https://github.com/asottile/reorder-python-imports + rev: v3.16.0 + hooks: + - id: reorder-python-imports + + # Ensures python files pass pylint checks - repo: local hooks: - id: pylint @@ -52,16 +49,16 @@ repos: entry: pylint language: system types: [python] - args: - - --rcfile=pyproject.toml + args: [-rn, -sn] - # Checks whether the python import statements are properly sorted. - - repo: https://github.com/asottile/reorder-python-imports - rev: v3.12.0 + # Performs Python static type check + - repo: local hooks: - - id: reorder-python-imports - args: - - --application-directories=.:src + - id: mypy + name: mypy + entry: mypy + language: system + types: [python] # Ensures yaml files are formatted - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt @@ -69,3 +66,9 @@ repos: hooks: - id: yamlfmt args: [--mapping, '2', --sequence, '4', --offset, '2'] + + # Ensures json files are valid. Supports Json with Comments + - repo: https://gitlab.com/bmares/check-json5 + rev: v1.0.0 + hooks: + - id: check-json5 diff --git a/Changelog.md b/Changelog.md index 875b717..825c32f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,9 +1 @@ # Changelog - -### 0.1 - -- Established initial project structure -- Introduced first modules: - - web application - - entrypoint backend -- Added development configuration diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..51947fc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,23 @@ +[project] +name = "rag-app" +version = "0.1.0" +requires-python=">=3.12" + +[tool.mypy] +disable_error_code = "import-untyped" + +[tool.autopep8] +aggressive = true +max-line-length = 100 +in-place = true + +[tool.pylint."messages control"] +disable = [ + "fixme", + "too-few-public-methods", + "too-many-instance-attributes", + "too-many-arguments", + "too-many-positional-arguments", + "too-many-locals", + "R0801" +] From dbfa9a91376d3d13ecf9aac11c659ca76bbd8e23 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 12:12:26 +0100 Subject: [PATCH 006/108] Add fist working version of web-app --- .devcontainer/web-app/Dockerfile | 25 + .devcontainer/web-app/devcontainer.json | 34 + services/web-app/.gitignore | 3 + services/web-app/cfg/main.yaml | 5 + services/web-app/cfg/mock_backend.yaml | 3 + services/web-app/justfile | 25 + services/web-app/main_dev.py | 59 + services/web-app/mock_backend.py | 101 ++ services/web-app/pyproject.toml | 23 + services/web-app/src/web/__init__.py | 3 + .../web-app/src/web/backend_communication.py | 98 ++ services/web-app/src/web/gui.py | 110 ++ services/web-app/uv.lock | 1426 +++++++++++++++++ services/web-app/web.Dockerfile | 12 + 14 files changed, 1927 insertions(+) create mode 100644 .devcontainer/web-app/Dockerfile create mode 100644 .devcontainer/web-app/devcontainer.json create mode 100644 services/web-app/.gitignore create mode 100644 services/web-app/cfg/main.yaml create mode 100644 services/web-app/cfg/mock_backend.yaml create mode 100644 services/web-app/justfile create mode 100644 services/web-app/main_dev.py create mode 100644 services/web-app/mock_backend.py create mode 100644 services/web-app/pyproject.toml create mode 100644 services/web-app/src/web/__init__.py create mode 100644 services/web-app/src/web/backend_communication.py create mode 100644 services/web-app/src/web/gui.py create mode 100644 services/web-app/uv.lock create mode 100644 services/web-app/web.Dockerfile diff --git a/.devcontainer/web-app/Dockerfile b/.devcontainer/web-app/Dockerfile new file mode 100644 index 0000000..a66e5dd --- /dev/null +++ b/.devcontainer/web-app/Dockerfile @@ -0,0 +1,25 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + wget \ + git \ + openssh-client \ + sudo \ + just + +RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash +RUN chown -R appuser:appuser /home/appuser/ + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN chmod +x /tmp/base-setup.sh \ + && USERNAME="appuser" /tmp/base-setup.sh + +USER appuser +WORKDIR /home/appuser/workspace + +RUN wget -qO- https://astral.sh/uv/install.sh | sh \ No newline at end of file diff --git a/.devcontainer/web-app/devcontainer.json b/.devcontainer/web-app/devcontainer.json new file mode 100644 index 0000000..10ce2f9 --- /dev/null +++ b/.devcontainer/web-app/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "web-app", + "build": { + "dockerfile": "Dockerfile", + "context": "../.." + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/home/appuser/workspace,type=bind", + "workspaceFolder": "/home/appuser/workspace/services/web-app", + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" + ], + "remoteUser": "appuser", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent", + "GIT_CONFIG_GLOBAL": "/home/appuser/.gitconfig" + }, + "runArgs": [ + "--network=host" + ], + "overrideCommand": true, + "postCreateCommand": "cd /home/appuser/workspace && /bin/bash .devcontainer/res/post_create_command.bash", + "customizations": { + "vscode": { + "extensions": [ + "skellock.just", + "ms-python.python", + "ms-python.pylint", + "ms-python.autopep8", + "tamasfe.even-better-toml", + "VisualStudioExptTeam.vscodeintellicode" + ] + } + } +} \ No newline at end of file diff --git a/services/web-app/.gitignore b/services/web-app/.gitignore new file mode 100644 index 0000000..84df091 --- /dev/null +++ b/services/web-app/.gitignore @@ -0,0 +1,3 @@ +src/web.egg-info/ +data/ +outputs/ diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml new file mode 100644 index 0000000..cb8b0da --- /dev/null +++ b/services/web-app/cfg/main.yaml @@ -0,0 +1,5 @@ +--- +backend_entrypoint_url: http://localhost:8888 +persistent_data_path: /home/appuser/workspace/services/web-app/data/ +web_app_port: 8080 +web_app_host: localhost diff --git a/services/web-app/cfg/mock_backend.yaml b/services/web-app/cfg/mock_backend.yaml new file mode 100644 index 0000000..516a613 --- /dev/null +++ b/services/web-app/cfg/mock_backend.yaml @@ -0,0 +1,3 @@ +--- +host: localhost +port: 8888 diff --git a/services/web-app/justfile b/services/web-app/justfile new file mode 100644 index 0000000..2070603 --- /dev/null +++ b/services/web-app/justfile @@ -0,0 +1,25 @@ +# -------------------------------------------------- +# This file contains setup scripts for the project. +# For more info, see: https://github.com/casey/just +# -------------------------------------------------- + +set shell := ["bash", "-c"] + +# Setup virtual environment and install dependencies. +setup-environment: + uv python install 3.12 + uv venv + uv pip install -e .[dev] + +# Run the Gradio web application with live reloading. +run-app: + uv run gradio main_dev.py --watch-dirs . --demo-name web_app + +# Run the mock backend server. +run-mock-backend: + uv run python mock_backend.py + +# Runs static checks using global pre-commit configuration. +run-precommit: + uv run pre-commit run -c ../../.pre-commit-config.yaml \ + --files `git ls-files --cached --others --exclude-standard` diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py new file mode 100644 index 0000000..9945e34 --- /dev/null +++ b/services/web-app/main_dev.py @@ -0,0 +1,59 @@ +"""Contains the main entrypoint for the web application.""" +import logging.config + +import gradio as gr +import hydra +import omegaconf +import web + + +def _logger(): + return logging.getLogger('web_app') + + +with hydra.initialize(version_base=None, config_path='cfg'): + cfg = hydra.compose(config_name='main') + + _logger().info('Starting web application with configuration: %s', + omegaconf.OmegaConf.to_yaml(cfg)) + + +logging.config.dictConfig({ + 'version': 1, + 'loggers': { + 'root': { + 'level': 'NOTSET', + 'handlers': ['console'], + 'propagate': True + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'level': 'INFO', + 'formatter': 'default' + } + }, + 'formatters': { + 'default': { + 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + } + } +}) + +backend_service = web.backend_communication.BackendService( + backend_url=cfg.backend_entrypoint_url +) + +CUSTOM_CSS = """ +.retrieved-docs { + max-height: 30vh; + overflow-y: auto; +} +""" + +with gr.Blocks(fill_height=True, title='AGH Chat', css=CUSTOM_CSS) as web_app: + web.gui.MainController(backend_service).render_gui() + +web_app.launch(server_name=cfg.web_app_host, + server_port=cfg.web_app_port) diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py new file mode 100644 index 0000000..aa5bbdb --- /dev/null +++ b/services/web-app/mock_backend.py @@ -0,0 +1,101 @@ +"""Mock backend service for testing the web application.""" +import asyncio +import json +import logging +import random +from typing import Dict +from typing import List +from typing import Tuple + +import hydra +import omegaconf +import pydantic +import uvicorn +from fastapi import FastAPI +from fastapi.responses import StreamingResponse + + +app = FastAPI() + + +class RequestCollectContextInfo(pydantic.BaseModel): + """Request coming from the web app to collect context information.""" + user_message: str + chat_history: List[Dict[str, str]] + + +class ResponseCollectContextInfo(pydantic.BaseModel): + """Response sent back to the web app with collected context information.""" + context_docs: List[Tuple[str, str]] + + +class RequestStreamChatResponse(pydantic.BaseModel): + """Request coming from the web app after collecting the context to stream chat responses.""" + user_message: str + chat_history: List[Dict[str, str]] + context_docs: List[Tuple[str, str]] + + +@app.get('/ping') +async def read_ping(): + """Health check endpoint.""" + return {'message': 'Service is running'} + + +@app.post('/collect_context_info') +async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: + """Collects context information from database for a given query.""" + + logging.info('/collect_context_info - Message: %s', request.user_message) + + mock_docs = [ + ('doc1', 'This is the content of document 1.'), + ('doc2', 'This is the content of document 2.'), + ('doc3', 'This is the content of document 3.'), + ] + + return ResponseCollectContextInfo(context_docs=mock_docs) + + +@app.post('/stream_chat_response') +async def stream_chat_response(request: RequestStreamChatResponse): + """Streams chat response for the user query based on the provided context.""" + + mock_response = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum.""" + + mock_words = mock_response.split() + + response = ' '.join(random.sample(mock_words, len(mock_words))) + response += f'Documents used: {[doc_id for doc_id, _ in request.context_docs]}' + + async def event_generator(): + for token in response.replace(' ', ' [split_token]') .split('[split_token]'): + chunk = {'content': token} + yield json.dumps(chunk).encode('utf-8') + await asyncio.sleep(0.05) + + return StreamingResponse(event_generator(), media_type='application/json') + + +@hydra.main(version_base=None, config_path='cfg', config_name='mock_backend') +def main(cfg: omegaconf.DictConfig): + """Sets up the mock backend service.""" + + logging.info('Starting mock backend with configuration: %s', + omegaconf.OmegaConf.to_yaml(cfg)) + + uvicorn.run( + 'mock_backend:app', + host=cfg.host, + port=cfg.port, + reload=False + ) + + +if __name__ == '__main__': + main() # pylint: disable=no-value-for-parameter diff --git a/services/web-app/pyproject.toml b/services/web-app/pyproject.toml new file mode 100644 index 0000000..c776d24 --- /dev/null +++ b/services/web-app/pyproject.toml @@ -0,0 +1,23 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "web" +version = "0.1.0" +requires-python=">=3.12" +dependencies = [ + "gradio==5.33.0", + "hydra-core==1.3.2", + "requests==2.32.3" +] + +[project.optional-dependencies] +dev = [ + "uvicorn==0.34.3", + "fastapi==0.115.12", + "pylint>=4.0.4", + "autopep8>=2.3.2", + "mypy>=1.19.0", + "pre-commit>=4.5.0" +] diff --git a/services/web-app/src/web/__init__.py b/services/web-app/src/web/__init__.py new file mode 100644 index 0000000..42571ab --- /dev/null +++ b/services/web-app/src/web/__init__.py @@ -0,0 +1,3 @@ +"""Package init file.""" +from . import backend_communication +from . import gui diff --git a/services/web-app/src/web/backend_communication.py b/services/web-app/src/web/backend_communication.py new file mode 100644 index 0000000..1269999 --- /dev/null +++ b/services/web-app/src/web/backend_communication.py @@ -0,0 +1,98 @@ +"""Contains functions to communicate with the entrypoint backend service.""" +import json +import logging +from typing import Any +from typing import Dict +from typing import List +from typing import Tuple + +import httpx +import requests # type: ignore + + +def _logger(): + return logging.getLogger('web_app') + + +def _sanitize_chat_history(chat_history: List[Dict[str, str]]): + """Sanitizes the chat history to ensure it contains only relevant fields.""" + return [ + { + 'role': item['role'], + 'content': item['content'] + } + for item in chat_history + ] + + +class BackendService: + """Communicates with the entrypoint-backend.""" + + def __init__(self, backend_url: str): + + self._backend_url = backend_url + + def collect_context_info(self, + user_message: str, + chat_history: List[Dict[str, Any]]) -> List[Tuple[str, str]]: + """Collects context information based on the user's message and chat history. + + Args: + user_message: The message from the user to collect context information for. + chat_history: The history of the chat to provide context for the request. + + Raises: + requests.HTTPError: If the request to the backend fails. + + Returns: + A list of tuples where each tuple contains a document title and its content. + """ + + _logger().debug('Collecting context info with user_message: %s and chat_history: %s', + user_message, chat_history) + + chat_history = _sanitize_chat_history(chat_history) + + url = f"{self._backend_url}/collect_context_info" + payload = { + 'user_message': user_message, + 'chat_history': chat_history + } + + response = requests.post(url, json=payload, timeout=5) + response.raise_for_status() + + return response.json().get('context_docs', []) + + def stream_chat_response(self, + user_message: str, + chat_history: List[Dict[str, Any]], + context_docs: List[Tuple[str, str]]): + """Collects LLM response based on the context and streams it. + + Args: + user_message: The message from the user to generate a response for. + chat_history: The history of the chat to provide context for the request. + context_docs: The documents retrieved to provide additional context. + + Returns: + A generator that yields chunks of the chat response as they are received. + """ + + _logger().debug(('Streaming chat response with user_message: %s, ' + + 'chat_history: %s, context_docs: %s'), + user_message, chat_history, context_docs) + + chat_history = _sanitize_chat_history(chat_history) + + url = f"{self._backend_url}/stream_chat_response" + + payload = { + 'user_message': user_message, + 'chat_history': chat_history, + 'context_docs': context_docs + } + + with httpx.stream('POST', url, json=payload, timeout=5) as stream: + for chunk in stream.iter_bytes(): + yield json.loads(chunk.decode('utf-8')) diff --git a/services/web-app/src/web/gui.py b/services/web-app/src/web/gui.py new file mode 100644 index 0000000..26ee957 --- /dev/null +++ b/services/web-app/src/web/gui.py @@ -0,0 +1,110 @@ +"""Contains GUI related utils.""" +import logging +from typing import List +from typing import Tuple + +import gradio as gr +import web + + +def _logger(): + return logging.getLogger('web_app') + + +def _create_retrieved_docs_representation(docs: List[Tuple[str, str]]) -> gr.Markdown: + """Concatenates the retrieved documents and returns their Markdown representation.""" + + content = '\n'.join( + f""" + ### {title} + {content} + """ + for title, content in docs + ) + + return gr.Markdown(content) + + +class MainController: + """Renders GUI elements and handles controller-view interactions.""" + + def __init__(self, + backend_service: web.backend_communication.BackendService): + + self._backend_service = backend_service + + def render_gui(self): + """Renders the UI for application and assigns the necessary callbacks.""" + + with gr.Row(elem_id='agh_header_row', height='70vh'): + + with gr.Column(elem_id='context_column', scale=1): + gr.Markdown( + """ + # Context + """ + ) + + gr.Markdown( + """ + ## Retrieved Documents + """ + ) + + with gr.Column(elem_id='retrieved_docs', + variant='panel', + elem_classes='retrieved-docs'): + + docs_list = gr.Markdown('Retrieved documents will be displayed here.',) + + with gr.Column(elem_id='chat_column', scale=3): + + gr.ChatInterface( + self._chat_interface_callback, + chatbot=gr.Chatbot(elem_id='agh_chat', + type='messages', + height='70vh', + show_copy_button=True), + title='AGH Chat', + type='messages', + textbox=gr.Textbox( + placeholder='Type a message...', label='Your message'), + additional_outputs=[docs_list], + ) + + def _chat_interface_callback(self, + user_message, + history): + """Main callback for the chat interface.""" + + history = history or [] + + try: + context_docs = self._backend_service.collect_context_info( + user_message=user_message, + chat_history=history + ) + except Exception as e: + _logger().error('Failed to collect context info from backend.') + raise gr.Error('Failed to collect context info from backend.', duration=5) from e + + context_docs_repr = _create_retrieved_docs_representation(context_docs) + + chat_response = self._backend_service.stream_chat_response( + user_message=user_message, + chat_history=history, + context_docs=context_docs + ) + + full_text_response = '' + for chunk in chat_response: + + token = chunk.get('content', '') + full_text_response += token + + chat_message = [{ + 'role': 'assistant', + 'content': full_text_response + }] + + yield chat_message, context_docs_repr diff --git a/services/web-app/uv.lock b/services/web-app/uv.lock new file mode 100644 index 0000000..4c0f969 --- /dev/null +++ b/services/web-app/uv.lock @@ -0,0 +1,1426 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] + +[[package]] +name = "aiofiles" +version = "24.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247, upload-time = "2024-06-24T11:02:03.584Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896, upload-time = "2024-06-24T11:02:01.529Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "antlr4-python3-runtime" +version = "4.9.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034, upload-time = "2021-11-06T17:52:23.524Z" } + +[[package]] +name = "anyio" +version = "4.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, +] + +[[package]] +name = "astroid" +version = "4.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/22/97df040e15d964e592d3a180598ace67e91b7c559d8298bdb3c949dc6e42/astroid-4.0.2.tar.gz", hash = "sha256:ac8fb7ca1c08eb9afec91ccc23edbd8ac73bb22cbdd7da1d488d9fb8d6579070", size = 405714, upload-time = "2025-11-09T21:21:18.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/ac/a85b4bfb4cf53221513e27f33cc37ad158fce02ac291d18bee6b49ab477d/astroid-4.0.2-py3-none-any.whl", hash = "sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b", size = 276354, upload-time = "2025-11-09T21:21:16.54Z" }, +] + +[[package]] +name = "audioop-lts" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/53/946db57842a50b2da2e0c1e34bd37f36f5aadba1a929a3971c5d7841dbca/audioop_lts-0.2.2.tar.gz", hash = "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", size = 30686, upload-time = "2025-08-05T16:43:17.409Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/d4/94d277ca941de5a507b07f0b592f199c22454eeaec8f008a286b3fbbacd6/audioop_lts-0.2.2-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800", size = 46523, upload-time = "2025-08-05T16:42:20.836Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5a/656d1c2da4b555920ce4177167bfeb8623d98765594af59702c8873f60ec/audioop_lts-0.2.2-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", size = 27455, upload-time = "2025-08-05T16:42:22.283Z" }, + { url = "https://files.pythonhosted.org/packages/1b/83/ea581e364ce7b0d41456fb79d6ee0ad482beda61faf0cab20cbd4c63a541/audioop_lts-0.2.2-cp313-abi3-macosx_11_0_arm64.whl", hash = "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", size = 26997, upload-time = "2025-08-05T16:42:23.849Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3b/e8964210b5e216e5041593b7d33e97ee65967f17c282e8510d19c666dab4/audioop_lts-0.2.2-cp313-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", size = 85844, upload-time = "2025-08-05T16:42:25.208Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2e/0a1c52faf10d51def20531a59ce4c706cb7952323b11709e10de324d6493/audioop_lts-0.2.2-cp313-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", size = 85056, upload-time = "2025-08-05T16:42:26.559Z" }, + { url = "https://files.pythonhosted.org/packages/75/e8/cd95eef479656cb75ab05dfece8c1f8c395d17a7c651d88f8e6e291a63ab/audioop_lts-0.2.2-cp313-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", size = 93892, upload-time = "2025-08-05T16:42:27.902Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1e/a0c42570b74f83efa5cca34905b3eef03f7ab09fe5637015df538a7f3345/audioop_lts-0.2.2-cp313-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", size = 96660, upload-time = "2025-08-05T16:42:28.9Z" }, + { url = "https://files.pythonhosted.org/packages/50/d5/8a0ae607ca07dbb34027bac8db805498ee7bfecc05fd2c148cc1ed7646e7/audioop_lts-0.2.2-cp313-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", size = 79143, upload-time = "2025-08-05T16:42:29.929Z" }, + { url = "https://files.pythonhosted.org/packages/12/17/0d28c46179e7910bfb0bb62760ccb33edb5de973052cb2230b662c14ca2e/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", size = 84313, upload-time = "2025-08-05T16:42:30.949Z" }, + { url = "https://files.pythonhosted.org/packages/84/ba/bd5d3806641564f2024e97ca98ea8f8811d4e01d9b9f9831474bc9e14f9e/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", size = 93044, upload-time = "2025-08-05T16:42:31.959Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5e/435ce8d5642f1f7679540d1e73c1c42d933331c0976eb397d1717d7f01a3/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", size = 78766, upload-time = "2025-08-05T16:42:33.302Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3b/b909e76b606cbfd53875693ec8c156e93e15a1366a012f0b7e4fb52d3c34/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_s390x.whl", hash = "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", size = 87640, upload-time = "2025-08-05T16:42:34.854Z" }, + { url = "https://files.pythonhosted.org/packages/30/e7/8f1603b4572d79b775f2140d7952f200f5e6c62904585d08a01f0a70393a/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", size = 86052, upload-time = "2025-08-05T16:42:35.839Z" }, + { url = "https://files.pythonhosted.org/packages/b5/96/c37846df657ccdda62ba1ae2b6534fa90e2e1b1742ca8dcf8ebd38c53801/audioop_lts-0.2.2-cp313-abi3-win32.whl", hash = "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", size = 26185, upload-time = "2025-08-05T16:42:37.04Z" }, + { url = "https://files.pythonhosted.org/packages/34/a5/9d78fdb5b844a83da8a71226c7bdae7cc638861085fff7a1d707cb4823fa/audioop_lts-0.2.2-cp313-abi3-win_amd64.whl", hash = "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", size = 30503, upload-time = "2025-08-05T16:42:38.427Z" }, + { url = "https://files.pythonhosted.org/packages/34/25/20d8fde083123e90c61b51afb547bb0ea7e77bab50d98c0ab243d02a0e43/audioop_lts-0.2.2-cp313-abi3-win_arm64.whl", hash = "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", size = 24173, upload-time = "2025-08-05T16:42:39.704Z" }, + { url = "https://files.pythonhosted.org/packages/58/a7/0a764f77b5c4ac58dc13c01a580f5d32ae8c74c92020b961556a43e26d02/audioop_lts-0.2.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", size = 47096, upload-time = "2025-08-05T16:42:40.684Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ed/ebebedde1a18848b085ad0fa54b66ceb95f1f94a3fc04f1cd1b5ccb0ed42/audioop_lts-0.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", size = 27748, upload-time = "2025-08-05T16:42:41.992Z" }, + { url = "https://files.pythonhosted.org/packages/cb/6e/11ca8c21af79f15dbb1c7f8017952ee8c810c438ce4e2b25638dfef2b02c/audioop_lts-0.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", size = 27329, upload-time = "2025-08-05T16:42:42.987Z" }, + { url = "https://files.pythonhosted.org/packages/84/52/0022f93d56d85eec5da6b9da6a958a1ef09e80c39f2cc0a590c6af81dcbb/audioop_lts-0.2.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", size = 92407, upload-time = "2025-08-05T16:42:44.336Z" }, + { url = "https://files.pythonhosted.org/packages/87/1d/48a889855e67be8718adbc7a01f3c01d5743c325453a5e81cf3717664aad/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", size = 91811, upload-time = "2025-08-05T16:42:45.325Z" }, + { url = "https://files.pythonhosted.org/packages/98/a6/94b7213190e8077547ffae75e13ed05edc488653c85aa5c41472c297d295/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", size = 100470, upload-time = "2025-08-05T16:42:46.468Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e9/78450d7cb921ede0cfc33426d3a8023a3bda755883c95c868ee36db8d48d/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", size = 103878, upload-time = "2025-08-05T16:42:47.576Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e2/cd5439aad4f3e34ae1ee852025dc6aa8f67a82b97641e390bf7bd9891d3e/audioop_lts-0.2.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", size = 84867, upload-time = "2025-08-05T16:42:49.003Z" }, + { url = "https://files.pythonhosted.org/packages/68/4b/9d853e9076c43ebba0d411e8d2aa19061083349ac695a7d082540bad64d0/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", size = 90001, upload-time = "2025-08-05T16:42:50.038Z" }, + { url = "https://files.pythonhosted.org/packages/58/26/4bae7f9d2f116ed5593989d0e521d679b0d583973d203384679323d8fa85/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", size = 99046, upload-time = "2025-08-05T16:42:51.111Z" }, + { url = "https://files.pythonhosted.org/packages/b2/67/a9f4fb3e250dda9e9046f8866e9fa7d52664f8985e445c6b4ad6dfb55641/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", size = 84788, upload-time = "2025-08-05T16:42:52.198Z" }, + { url = "https://files.pythonhosted.org/packages/70/f7/3de86562db0121956148bcb0fe5b506615e3bcf6e63c4357a612b910765a/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", size = 94472, upload-time = "2025-08-05T16:42:53.59Z" }, + { url = "https://files.pythonhosted.org/packages/f1/32/fd772bf9078ae1001207d2df1eef3da05bea611a87dd0e8217989b2848fa/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", size = 92279, upload-time = "2025-08-05T16:42:54.632Z" }, + { url = "https://files.pythonhosted.org/packages/4f/41/affea7181592ab0ab560044632571a38edaf9130b84928177823fbf3176a/audioop_lts-0.2.2-cp313-cp313t-win32.whl", hash = "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", size = 26568, upload-time = "2025-08-05T16:42:55.627Z" }, + { url = "https://files.pythonhosted.org/packages/28/2b/0372842877016641db8fc54d5c88596b542eec2f8f6c20a36fb6612bf9ee/audioop_lts-0.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", size = 30942, upload-time = "2025-08-05T16:42:56.674Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/baf2b9cc7e96c179bb4a54f30fcd83e6ecb340031bde68f486403f943768/audioop_lts-0.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", size = 24603, upload-time = "2025-08-05T16:42:57.571Z" }, + { url = "https://files.pythonhosted.org/packages/5c/73/413b5a2804091e2c7d5def1d618e4837f1cb82464e230f827226278556b7/audioop_lts-0.2.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", size = 47104, upload-time = "2025-08-05T16:42:58.518Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/daa3308dc6593944410c2c68306a5e217f5c05b70a12e70228e7dd42dc5c/audioop_lts-0.2.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", size = 27754, upload-time = "2025-08-05T16:43:00.132Z" }, + { url = "https://files.pythonhosted.org/packages/4e/86/c2e0f627168fcf61781a8f72cab06b228fe1da4b9fa4ab39cfb791b5836b/audioop_lts-0.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", size = 27332, upload-time = "2025-08-05T16:43:01.666Z" }, + { url = "https://files.pythonhosted.org/packages/c7/bd/35dce665255434f54e5307de39e31912a6f902d4572da7c37582809de14f/audioop_lts-0.2.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", size = 92396, upload-time = "2025-08-05T16:43:02.991Z" }, + { url = "https://files.pythonhosted.org/packages/2d/d2/deeb9f51def1437b3afa35aeb729d577c04bcd89394cb56f9239a9f50b6f/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", size = 91811, upload-time = "2025-08-05T16:43:04.096Z" }, + { url = "https://files.pythonhosted.org/packages/76/3b/09f8b35b227cee28cc8231e296a82759ed80c1a08e349811d69773c48426/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", size = 100483, upload-time = "2025-08-05T16:43:05.085Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/05b48a935cf3b130c248bfdbdea71ce6437f5394ee8533e0edd7cfd93d5e/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", size = 103885, upload-time = "2025-08-05T16:43:06.197Z" }, + { url = "https://files.pythonhosted.org/packages/83/80/186b7fce6d35b68d3d739f228dc31d60b3412105854edb975aa155a58339/audioop_lts-0.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", size = 84899, upload-time = "2025-08-05T16:43:07.291Z" }, + { url = "https://files.pythonhosted.org/packages/49/89/c78cc5ac6cb5828f17514fb12966e299c850bc885e80f8ad94e38d450886/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", size = 89998, upload-time = "2025-08-05T16:43:08.335Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/6401888d0c010e586c2ca50fce4c903d70a6bb55928b16cfbdfd957a13da/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", size = 99046, upload-time = "2025-08-05T16:43:09.367Z" }, + { url = "https://files.pythonhosted.org/packages/de/f8/c874ca9bb447dae0e2ef2e231f6c4c2b0c39e31ae684d2420b0f9e97ee68/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", size = 84843, upload-time = "2025-08-05T16:43:10.749Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c0/0323e66f3daebc13fd46b36b30c3be47e3fc4257eae44f1e77eb828c703f/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", size = 94490, upload-time = "2025-08-05T16:43:12.131Z" }, + { url = "https://files.pythonhosted.org/packages/98/6b/acc7734ac02d95ab791c10c3f17ffa3584ccb9ac5c18fd771c638ed6d1f5/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", size = 92297, upload-time = "2025-08-05T16:43:13.139Z" }, + { url = "https://files.pythonhosted.org/packages/13/c3/c3dc3f564ce6877ecd2a05f8d751b9b27a8c320c2533a98b0c86349778d0/audioop_lts-0.2.2-cp314-cp314t-win32.whl", hash = "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", size = 27331, upload-time = "2025-08-05T16:43:14.19Z" }, + { url = "https://files.pythonhosted.org/packages/72/bb/b4608537e9ffcb86449091939d52d24a055216a36a8bf66b936af8c3e7ac/audioop_lts-0.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", size = 31697, upload-time = "2025-08-05T16:43:15.193Z" }, + { url = "https://files.pythonhosted.org/packages/f6/22/91616fe707a5c5510de2cac9b046a30defe7007ba8a0c04f9c08f27df312/audioop_lts-0.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", size = 25206, upload-time = "2025-08-05T16:43:16.444Z" }, +] + +[[package]] +name = "autopep8" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycodestyle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210, upload-time = "2025-01-14T14:46:18.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807, upload-time = "2025-01-14T14:46:15.466Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dill" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "fastapi" +version = "0.115.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, +] + +[[package]] +name = "ffmpy" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/d2/1c4c582d71bcc65c76fa69fab85de6257d50fdf6fd4a2317c53917e9a581/ffmpy-1.0.0.tar.gz", hash = "sha256:b12932e95435c8820f1cd041024402765f821971e4bae753b327fc02a6e12f8b", size = 5101, upload-time = "2025-11-11T06:24:23.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/56/dd3669eccebb6d8ac81e624542ebd53fe6f08e1b8f2f8d50aeb7e3b83f99/ffmpy-1.0.0-py3-none-any.whl", hash = "sha256:5640e5f0fd03fb6236d0e119b16ccf6522db1c826fdf35dcb87087b60fd7504f", size = 5614, upload-time = "2025-11-11T06:24:22.818Z" }, +] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, +] + +[[package]] +name = "gradio" +version = "5.33.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiofiles" }, + { name = "anyio" }, + { name = "audioop-lts", marker = "python_full_version >= '3.13'" }, + { name = "fastapi" }, + { name = "ffmpy" }, + { name = "gradio-client" }, + { name = "groovy" }, + { name = "httpx" }, + { name = "huggingface-hub" }, + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "numpy" }, + { name = "orjson" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "pillow" }, + { name = "pydantic" }, + { name = "pydub" }, + { name = "python-multipart" }, + { name = "pyyaml" }, + { name = "ruff", marker = "sys_platform != 'emscripten'" }, + { name = "safehttpx" }, + { name = "semantic-version" }, + { name = "starlette", marker = "sys_platform != 'emscripten'" }, + { name = "tomlkit" }, + { name = "typer", marker = "sys_platform != 'emscripten'" }, + { name = "typing-extensions" }, + { name = "urllib3", marker = "sys_platform == 'emscripten'" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b0/97/908eb543fbce7c69250d6fbe87b6ccf4ce397d31bceb360b40316357c68c/gradio-5.33.0.tar.gz", hash = "sha256:0cba3a1596fda6cb0048dd7ddc2d57e6238a047c0df9dee5a4a0e5c2a74e8e50", size = 64888401, upload-time = "2025-06-04T21:47:57.431Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/c3/c9b09b8d7efd63d83a9c8d9c53b02e1b77238e14305a7ee561e0a8990465/gradio-5.33.0-py3-none-any.whl", hash = "sha256:165e412e1510a22471901744722f99a52cb56465a7e9609f1e400cac9999e9d8", size = 54208887, upload-time = "2025-06-04T21:47:52.002Z" }, +] + +[[package]] +name = "gradio-client" +version = "1.10.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fsspec" }, + { name = "httpx" }, + { name = "huggingface-hub" }, + { name = "packaging" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/86/6684afe8691b024200fdc8983924f04b5f76bb401b9c700e5752a23595a0/gradio_client-1.10.2.tar.gz", hash = "sha256:bf71ba95714784fa77ca0cfb20189ad91c55e563c2dc71722d023a97f1815d7f", size = 321294, upload-time = "2025-05-30T13:59:55.756Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/1b/b372308c263379ae3ebc440512432979458330113bdee26cef86c89bf48e/gradio_client-1.10.2-py3-none-any.whl", hash = "sha256:6de67b6224123d264c7887caa0586b2a9e2c369ec32ca38927cf8a841694edcd", size = 323311, upload-time = "2025-05-30T13:59:54.555Z" }, +] + +[[package]] +name = "groovy" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/36/bbdede67400277bef33d3ec0e6a31750da972c469f75966b4930c753218f/groovy-0.1.2.tar.gz", hash = "sha256:25c1dc09b3f9d7e292458aa762c6beb96ea037071bf5e917fc81fb78d2231083", size = 17325, upload-time = "2025-02-28T20:24:56.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/27/3d6dcadc8a3214d8522c1e7f6a19554e33659be44546d44a2f7572ac7d2a/groovy-0.1.2-py3-none-any.whl", hash = "sha256:7f7975bab18c729a257a8b1ae9dcd70b7cafb1720481beae47719af57c35fa64", size = 14090, upload-time = "2025-02-28T20:24:55.152Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "hf-xet" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/a5/85ef910a0aa034a2abcfadc360ab5ac6f6bc4e9112349bd40ca97551cff0/hf_xet-1.2.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649", size = 2861870, upload-time = "2025-10-24T19:04:11.422Z" }, + { url = "https://files.pythonhosted.org/packages/ea/40/e2e0a7eb9a51fe8828ba2d47fe22a7e74914ea8a0db68a18c3aa7449c767/hf_xet-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813", size = 2717584, upload-time = "2025-10-24T19:04:09.586Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7d/daf7f8bc4594fdd59a8a596f9e3886133fdc68e675292218a5e4c1b7e834/hf_xet-1.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc", size = 3315004, upload-time = "2025-10-24T19:04:00.314Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ba/45ea2f605fbf6d81c8b21e4d970b168b18a53515923010c312c06cd83164/hf_xet-1.2.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5", size = 3222636, upload-time = "2025-10-24T19:03:58.111Z" }, + { url = "https://files.pythonhosted.org/packages/4a/1d/04513e3cab8f29ab8c109d309ddd21a2705afab9d52f2ba1151e0c14f086/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f", size = 3408448, upload-time = "2025-10-24T19:04:20.951Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7c/60a2756d7feec7387db3a1176c632357632fbe7849fce576c5559d4520c7/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832", size = 3503401, upload-time = "2025-10-24T19:04:22.549Z" }, + { url = "https://files.pythonhosted.org/packages/4e/64/48fffbd67fb418ab07451e4ce641a70de1c40c10a13e25325e24858ebe5a/hf_xet-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382", size = 2900866, upload-time = "2025-10-24T19:04:33.461Z" }, + { url = "https://files.pythonhosted.org/packages/e2/51/f7e2caae42f80af886db414d4e9885fac959330509089f97cccb339c6b87/hf_xet-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e", size = 2861861, upload-time = "2025-10-24T19:04:19.01Z" }, + { url = "https://files.pythonhosted.org/packages/6e/1d/a641a88b69994f9371bd347f1dd35e5d1e2e2460a2e350c8d5165fc62005/hf_xet-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8", size = 2717699, upload-time = "2025-10-24T19:04:17.306Z" }, + { url = "https://files.pythonhosted.org/packages/df/e0/e5e9bba7d15f0318955f7ec3f4af13f92e773fbb368c0b8008a5acbcb12f/hf_xet-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0", size = 3314885, upload-time = "2025-10-24T19:04:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/21/90/b7fe5ff6f2b7b8cbdf1bd56145f863c90a5807d9758a549bf3d916aa4dec/hf_xet-1.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090", size = 3221550, upload-time = "2025-10-24T19:04:05.55Z" }, + { url = "https://files.pythonhosted.org/packages/6f/cb/73f276f0a7ce46cc6a6ec7d6c7d61cbfe5f2e107123d9bbd0193c355f106/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a", size = 3408010, upload-time = "2025-10-24T19:04:28.598Z" }, + { url = "https://files.pythonhosted.org/packages/b8/1e/d642a12caa78171f4be64f7cd9c40e3ca5279d055d0873188a58c0f5fbb9/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f", size = 3503264, upload-time = "2025-10-24T19:04:30.397Z" }, + { url = "https://files.pythonhosted.org/packages/17/b5/33764714923fa1ff922770f7ed18c2daae034d21ae6e10dbf4347c854154/hf_xet-1.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc", size = 2901071, upload-time = "2025-10-24T19:04:37.463Z" }, + { url = "https://files.pythonhosted.org/packages/96/2d/22338486473df5923a9ab7107d375dbef9173c338ebef5098ef593d2b560/hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848", size = 2866099, upload-time = "2025-10-24T19:04:15.366Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8c/c5becfa53234299bc2210ba314eaaae36c2875e0045809b82e40a9544f0c/hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4", size = 2722178, upload-time = "2025-10-24T19:04:13.695Z" }, + { url = "https://files.pythonhosted.org/packages/9a/92/cf3ab0b652b082e66876d08da57fcc6fa2f0e6c70dfbbafbd470bb73eb47/hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd", size = 3320214, upload-time = "2025-10-24T19:04:03.596Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/3f7ec4a1b6a65bf45b059b6d4a5d38988f63e193056de2f420137e3c3244/hf_xet-1.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c", size = 3229054, upload-time = "2025-10-24T19:04:01.949Z" }, + { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, + { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, + { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "huggingface-hub" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "shellingham" }, + { name = "tqdm" }, + { name = "typer-slim" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/a1/397934161650e1248107fa3337f320f83f09f8113c5117ce3c2d32cfda8d/huggingface_hub-1.2.1.tar.gz", hash = "sha256:1aced061fa1bd443c0ec80a4af432b8b70041d54860f7af334ceff599611a415", size = 614603, upload-time = "2025-12-05T15:11:21.729Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/cf/ef5cc94b1ed4e1ab8a15c17937c876b9733154a746c78f4c06c2336a05e5/huggingface_hub-1.2.1-py3-none-any.whl", hash = "sha256:8c74a41a16156337dfa1090873ca11f8c1d7b6efcbac9f6673d008a740207e6a", size = 520930, upload-time = "2025-12-05T15:11:20.045Z" }, +] + +[[package]] +name = "hydra-core" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "omegaconf" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/8e/07e42bc434a847154083b315779b0a81d567154504624e181caf2c71cd98/hydra-core-1.3.2.tar.gz", hash = "sha256:8a878ed67216997c3e9d88a8e72e7b4767e81af37afb4ea3334b269a4390a824", size = 3263494, upload-time = "2023-02-23T18:33:43.03Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/50/e0edd38dcd63fb26a8547f13d28f7a008bc4a3fd4eb4ff030673f22ad41a/hydra_core-1.3.2-py3-none-any.whl", hash = "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b", size = 154547, upload-time = "2023-02-23T18:33:40.801Z" }, +] + +[[package]] +name = "identify" +version = "2.6.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "isort" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "librt" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/d9/6f3d3fcf5e5543ed8a60cc70fa7d50508ed60b8a10e9af6d2058159ab54e/librt-0.7.3.tar.gz", hash = "sha256:3ec50cf65235ff5c02c5b747748d9222e564ad48597122a361269dd3aa808798", size = 144549, upload-time = "2025-12-06T19:04:45.553Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/90/ed8595fa4e35b6020317b5ea8d226a782dcbac7a997c19ae89fb07a41c66/librt-0.7.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fa9ac2e49a6bee56e47573a6786cb635e128a7b12a0dc7851090037c0d397a3", size = 55687, upload-time = "2025-12-06T19:03:39.245Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f6/6a20702a07b41006cb001a759440cb6b5362530920978f64a2b2ae2bf729/librt-0.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e980cf1ed1a2420a6424e2ed884629cdead291686f1048810a817de07b5eb18", size = 57127, upload-time = "2025-12-06T19:03:40.3Z" }, + { url = "https://files.pythonhosted.org/packages/79/f3/b0c4703d5ffe9359b67bb2ccb86c42d4e930a363cfc72262ac3ba53cff3e/librt-0.7.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e094e445c37c57e9ec612847812c301840239d34ccc5d153a982fa9814478c60", size = 165336, upload-time = "2025-12-06T19:03:41.369Z" }, + { url = "https://files.pythonhosted.org/packages/02/69/3ba05b73ab29ccbe003856232cea4049769be5942d799e628d1470ed1694/librt-0.7.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aca73d70c3f553552ba9133d4a09e767dcfeee352d8d8d3eb3f77e38a3beb3ed", size = 174237, upload-time = "2025-12-06T19:03:42.44Z" }, + { url = "https://files.pythonhosted.org/packages/22/ad/d7c2671e7bf6c285ef408aa435e9cd3fdc06fd994601e1f2b242df12034f/librt-0.7.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c634a0a6db395fdaba0361aa78395597ee72c3aad651b9a307a3a7eaf5efd67e", size = 189017, upload-time = "2025-12-06T19:03:44.01Z" }, + { url = "https://files.pythonhosted.org/packages/f4/94/d13f57193148004592b618555f296b41d2d79b1dc814ff8b3273a0bf1546/librt-0.7.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a59a69deeb458c858b8fea6acf9e2acd5d755d76cd81a655256bc65c20dfff5b", size = 183983, upload-time = "2025-12-06T19:03:45.834Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/b612a9944ebd39fa143c7e2e2d33f2cb790205e025ddd903fb509a3a3bb3/librt-0.7.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d91e60ac44bbe3a77a67af4a4c13114cbe9f6d540337ce22f2c9eaf7454ca71f", size = 177602, upload-time = "2025-12-06T19:03:46.944Z" }, + { url = "https://files.pythonhosted.org/packages/1f/48/77bc05c4cc232efae6c5592c0095034390992edbd5bae8d6cf1263bb7157/librt-0.7.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:703456146dc2bf430f7832fd1341adac5c893ec3c1430194fdcefba00012555c", size = 199282, upload-time = "2025-12-06T19:03:48.069Z" }, + { url = "https://files.pythonhosted.org/packages/12/aa/05916ccd864227db1ffec2a303ae34f385c6b22d4e7ce9f07054dbcf083c/librt-0.7.3-cp312-cp312-win32.whl", hash = "sha256:b7c1239b64b70be7759554ad1a86288220bbb04d68518b527783c4ad3fb4f80b", size = 47879, upload-time = "2025-12-06T19:03:49.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/92/7f41c42d31ea818b3c4b9cc1562e9714bac3c676dd18f6d5dd3d0f2aa179/librt-0.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef59c938f72bdbc6ab52dc50f81d0637fde0f194b02d636987cea2ab30f8f55a", size = 54972, upload-time = "2025-12-06T19:03:50.335Z" }, + { url = "https://files.pythonhosted.org/packages/3f/dc/53582bbfb422311afcbc92adb75711f04e989cec052f08ec0152fbc36c9c/librt-0.7.3-cp312-cp312-win_arm64.whl", hash = "sha256:ff21c554304e8226bf80c3a7754be27c6c3549a9fec563a03c06ee8f494da8fc", size = 48338, upload-time = "2025-12-06T19:03:51.431Z" }, + { url = "https://files.pythonhosted.org/packages/93/7d/e0ce1837dfb452427db556e6d4c5301ba3b22fe8de318379fbd0593759b9/librt-0.7.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56f2a47beda8409061bc1c865bef2d4bd9ff9255219402c0817e68ab5ad89aed", size = 55742, upload-time = "2025-12-06T19:03:52.459Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/3564262301e507e1d5cf31c7d84cb12addf0d35e05ba53312494a2eba9a4/librt-0.7.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14569ac5dd38cfccf0a14597a88038fb16811a6fede25c67b79c6d50fc2c8fdc", size = 57163, upload-time = "2025-12-06T19:03:53.516Z" }, + { url = "https://files.pythonhosted.org/packages/be/ac/245e72b7e443d24a562f6047563c7f59833384053073ef9410476f68505b/librt-0.7.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6038ccbd5968325a5d6fd393cf6e00b622a8de545f0994b89dd0f748dcf3e19e", size = 165840, upload-time = "2025-12-06T19:03:54.918Z" }, + { url = "https://files.pythonhosted.org/packages/98/af/587e4491f40adba066ba39a450c66bad794c8d92094f936a201bfc7c2b5f/librt-0.7.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d39079379a9a28e74f4d57dc6357fa310a1977b51ff12239d7271ec7e71d67f5", size = 174827, upload-time = "2025-12-06T19:03:56.082Z" }, + { url = "https://files.pythonhosted.org/packages/78/21/5b8c60ea208bc83dd00421022a3874330685d7e856404128dc3728d5d1af/librt-0.7.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8837d5a52a2d7aa9f4c3220a8484013aed1d8ad75240d9a75ede63709ef89055", size = 189612, upload-time = "2025-12-06T19:03:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/da/2f/8b819169ef696421fb81cd04c6cdf225f6e96f197366001e9d45180d7e9e/librt-0.7.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:399bbd7bcc1633c3e356ae274a1deb8781c7bf84d9c7962cc1ae0c6e87837292", size = 184584, upload-time = "2025-12-06T19:03:58.686Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fc/af9d225a9395b77bd7678362cb055d0b8139c2018c37665de110ca388022/librt-0.7.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8d8cf653e798ee4c4e654062b633db36984a1572f68c3aa25e364a0ddfbbb910", size = 178269, upload-time = "2025-12-06T19:03:59.769Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d8/7b4fa1683b772966749d5683aa3fd605813defffe157833a8fa69cc89207/librt-0.7.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2f03484b54bf4ae80ab2e504a8d99d20d551bfe64a7ec91e218010b467d77093", size = 199852, upload-time = "2025-12-06T19:04:00.901Z" }, + { url = "https://files.pythonhosted.org/packages/77/e8/4598413aece46ca38d9260ef6c51534bd5f34b5c21474fcf210ce3a02123/librt-0.7.3-cp313-cp313-win32.whl", hash = "sha256:44b3689b040df57f492e02cd4f0bacd1b42c5400e4b8048160c9d5e866de8abe", size = 47936, upload-time = "2025-12-06T19:04:02.054Z" }, + { url = "https://files.pythonhosted.org/packages/af/80/ac0e92d5ef8c6791b3e2c62373863827a279265e0935acdf807901353b0e/librt-0.7.3-cp313-cp313-win_amd64.whl", hash = "sha256:6b407c23f16ccc36614c136251d6b32bf30de7a57f8e782378f1107be008ddb0", size = 54965, upload-time = "2025-12-06T19:04:03.224Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fd/042f823fcbff25c1449bb4203a29919891ca74141b68d3a5f6612c4ce283/librt-0.7.3-cp313-cp313-win_arm64.whl", hash = "sha256:abfc57cab3c53c4546aee31859ef06753bfc136c9d208129bad23e2eca39155a", size = 48350, upload-time = "2025-12-06T19:04:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ae/c6ecc7bb97134a71b5241e8855d39964c0e5f4d96558f0d60593892806d2/librt-0.7.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:120dd21d46ff875e849f1aae19346223cf15656be489242fe884036b23d39e93", size = 55175, upload-time = "2025-12-06T19:04:05.308Z" }, + { url = "https://files.pythonhosted.org/packages/cf/bc/2cc0cb0ab787b39aa5c7645cd792433c875982bdf12dccca558b89624594/librt-0.7.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1617bea5ab31266e152871208502ee943cb349c224846928a1173c864261375e", size = 56881, upload-time = "2025-12-06T19:04:06.674Z" }, + { url = "https://files.pythonhosted.org/packages/8e/87/397417a386190b70f5bf26fcedbaa1515f19dce33366e2684c6b7ee83086/librt-0.7.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93b2a1f325fefa1482516ced160c8c7b4b8d53226763fa6c93d151fa25164207", size = 163710, upload-time = "2025-12-06T19:04:08.437Z" }, + { url = "https://files.pythonhosted.org/packages/c9/37/7338f85b80e8a17525d941211451199845093ca242b32efbf01df8531e72/librt-0.7.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d4801db8354436fd3936531e7f0e4feb411f62433a6b6cb32bb416e20b529f", size = 172471, upload-time = "2025-12-06T19:04:10.124Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e0/741704edabbfae2c852fedc1b40d9ed5a783c70ed3ed8e4fe98f84b25d13/librt-0.7.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11ad45122bbed42cfc8b0597450660126ef28fd2d9ae1a219bc5af8406f95678", size = 186804, upload-time = "2025-12-06T19:04:11.586Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d1/0a82129d6ba242f3be9af34815be089f35051bc79619f5c27d2c449ecef6/librt-0.7.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6b4e7bff1d76dd2b46443078519dc75df1b5e01562345f0bb740cea5266d8218", size = 181817, upload-time = "2025-12-06T19:04:12.802Z" }, + { url = "https://files.pythonhosted.org/packages/4f/32/704f80bcf9979c68d4357c46f2af788fbf9d5edda9e7de5786ed2255e911/librt-0.7.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:d86f94743a11873317094326456b23f8a5788bad9161fd2f0e52088c33564620", size = 175602, upload-time = "2025-12-06T19:04:14.004Z" }, + { url = "https://files.pythonhosted.org/packages/f7/6d/4355cfa0fae0c062ba72f541d13db5bc575770125a7ad3d4f46f4109d305/librt-0.7.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:754a0d09997095ad764ccef050dd5bf26cbf457aab9effcba5890dad081d879e", size = 196497, upload-time = "2025-12-06T19:04:15.487Z" }, + { url = "https://files.pythonhosted.org/packages/2e/eb/ac6d8517d44209e5a712fde46f26d0055e3e8969f24d715f70bd36056230/librt-0.7.3-cp314-cp314-win32.whl", hash = "sha256:fbd7351d43b80d9c64c3cfcb50008f786cc82cba0450e8599fdd64f264320bd3", size = 44678, upload-time = "2025-12-06T19:04:16.688Z" }, + { url = "https://files.pythonhosted.org/packages/e9/93/238f026d141faf9958da588c761a0812a1a21c98cc54a76f3608454e4e59/librt-0.7.3-cp314-cp314-win_amd64.whl", hash = "sha256:d376a35c6561e81d2590506804b428fc1075fcc6298fc5bb49b771534c0ba010", size = 51689, upload-time = "2025-12-06T19:04:17.726Z" }, + { url = "https://files.pythonhosted.org/packages/52/44/43f462ad9dcf9ed7d3172fe2e30d77b980956250bd90e9889a9cca93df2a/librt-0.7.3-cp314-cp314-win_arm64.whl", hash = "sha256:cbdb3f337c88b43c3b49ca377731912c101178be91cb5071aac48faa898e6f8e", size = 44662, upload-time = "2025-12-06T19:04:18.771Z" }, + { url = "https://files.pythonhosted.org/packages/1d/35/fed6348915f96b7323241de97f26e2af481e95183b34991df12fd5ce31b1/librt-0.7.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9f0e0927efe87cd42ad600628e595a1a0aa1c64f6d0b55f7e6059079a428641a", size = 57347, upload-time = "2025-12-06T19:04:19.812Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f2/045383ccc83e3fea4fba1b761796584bc26817b6b2efb6b8a6731431d16f/librt-0.7.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:020c6db391268bcc8ce75105cb572df8cb659a43fd347366aaa407c366e5117a", size = 59223, upload-time = "2025-12-06T19:04:20.862Z" }, + { url = "https://files.pythonhosted.org/packages/77/3f/c081f8455ab1d7f4a10dbe58463ff97119272ff32494f21839c3b9029c2c/librt-0.7.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7af7785f5edd1f418da09a8cdb9ec84b0213e23d597413e06525340bcce1ea4f", size = 183861, upload-time = "2025-12-06T19:04:21.963Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f5/73c5093c22c31fbeaebc25168837f05ebfd8bf26ce00855ef97a5308f36f/librt-0.7.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ccadf260bb46a61b9c7e89e2218f6efea9f3eeaaab4e3d1f58571890e54858e", size = 194594, upload-time = "2025-12-06T19:04:23.14Z" }, + { url = "https://files.pythonhosted.org/packages/78/b8/d5f17d4afe16612a4a94abfded94c16c5a033f183074fb130dfe56fc1a42/librt-0.7.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9883b2d819ce83f87ba82a746c81d14ada78784db431e57cc9719179847376e", size = 206759, upload-time = "2025-12-06T19:04:24.328Z" }, + { url = "https://files.pythonhosted.org/packages/36/2e/021765c1be85ee23ffd5b5b968bb4cba7526a4db2a0fc27dcafbdfc32da7/librt-0.7.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:59cb0470612d21fa1efddfa0dd710756b50d9c7fb6c1236bbf8ef8529331dc70", size = 203210, upload-time = "2025-12-06T19:04:25.544Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/9923656e42da4fd18c594bd08cf6d7e152d4158f8b808e210d967f0dcceb/librt-0.7.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:1fe603877e1865b5fd047a5e40379509a4a60204aa7aa0f72b16f7a41c3f0712", size = 196708, upload-time = "2025-12-06T19:04:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/fc/0b/0708b886ac760e64d6fbe7e16024e4be3ad1a3629d19489a97e9cf4c3431/librt-0.7.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5460d99ed30f043595bbdc888f542bad2caeb6226b01c33cda3ae444e8f82d42", size = 217212, upload-time = "2025-12-06T19:04:27.892Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7f/12a73ff17bca4351e73d585dd9ebf46723c4a8622c4af7fe11a2e2d011ff/librt-0.7.3-cp314-cp314t-win32.whl", hash = "sha256:d09f677693328503c9e492e33e9601464297c01f9ebd966ea8fc5308f3069bfd", size = 45586, upload-time = "2025-12-06T19:04:29.116Z" }, + { url = "https://files.pythonhosted.org/packages/e2/df/8decd032ac9b995e4f5606cde783711a71094128d88d97a52e397daf2c89/librt-0.7.3-cp314-cp314t-win_amd64.whl", hash = "sha256:25711f364c64cab2c910a0247e90b51421e45dbc8910ceeb4eac97a9e132fc6f", size = 53002, upload-time = "2025-12-06T19:04:30.173Z" }, + { url = "https://files.pythonhosted.org/packages/de/0c/6605b6199de8178afe7efc77ca1d8e6db00453bc1d3349d27605c0f42104/librt-0.7.3-cp314-cp314t-win_arm64.whl", hash = "sha256:a9f9b661f82693eb56beb0605156c7fca57f535704ab91837405913417d6990b", size = 45647, upload-time = "2025-12-06T19:04:31.302Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mypy" +version = "1.19.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "librt" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/b5/b58cdc25fadd424552804bf410855d52324183112aa004f0732c5f6324cf/mypy-1.19.0.tar.gz", hash = "sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528", size = 3579025, upload-time = "2025-11-28T15:49:01.26Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/7e/1afa8fb188b876abeaa14460dc4983f909aaacaa4bf5718c00b2c7e0b3d5/mypy-1.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d", size = 13207728, upload-time = "2025-11-28T15:46:26.463Z" }, + { url = "https://files.pythonhosted.org/packages/b2/13/f103d04962bcbefb1644f5ccb235998b32c337d6c13145ea390b9da47f3e/mypy-1.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760", size = 12202945, upload-time = "2025-11-28T15:48:49.143Z" }, + { url = "https://files.pythonhosted.org/packages/e4/93/a86a5608f74a22284a8ccea8592f6e270b61f95b8588951110ad797c2ddd/mypy-1.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6", size = 12718673, upload-time = "2025-11-28T15:47:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/3d/58/cf08fff9ced0423b858f2a7495001fda28dc058136818ee9dffc31534ea9/mypy-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2", size = 13608336, upload-time = "2025-11-28T15:48:32.625Z" }, + { url = "https://files.pythonhosted.org/packages/64/ed/9c509105c5a6d4b73bb08733102a3ea62c25bc02c51bca85e3134bf912d3/mypy-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431", size = 13833174, upload-time = "2025-11-28T15:45:48.091Z" }, + { url = "https://files.pythonhosted.org/packages/cd/71/01939b66e35c6f8cb3e6fdf0b657f0fd24de2f8ba5e523625c8e72328208/mypy-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018", size = 10112208, upload-time = "2025-11-28T15:46:41.702Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0d/a1357e6bb49e37ce26fcf7e3cc55679ce9f4ebee0cd8b6ee3a0e301a9210/mypy-1.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e", size = 13191993, upload-time = "2025-11-28T15:47:22.336Z" }, + { url = "https://files.pythonhosted.org/packages/5d/75/8e5d492a879ec4490e6ba664b5154e48c46c85b5ac9785792a5ec6a4d58f/mypy-1.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d", size = 12174411, upload-time = "2025-11-28T15:44:55.492Z" }, + { url = "https://files.pythonhosted.org/packages/71/31/ad5dcee9bfe226e8eaba777e9d9d251c292650130f0450a280aec3485370/mypy-1.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba", size = 12727751, upload-time = "2025-11-28T15:44:14.169Z" }, + { url = "https://files.pythonhosted.org/packages/77/06/b6b8994ce07405f6039701f4b66e9d23f499d0b41c6dd46ec28f96d57ec3/mypy-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364", size = 13593323, upload-time = "2025-11-28T15:46:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/68/b1/126e274484cccdf099a8e328d4fda1c7bdb98a5e888fa6010b00e1bbf330/mypy-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee", size = 13818032, upload-time = "2025-11-28T15:46:18.286Z" }, + { url = "https://files.pythonhosted.org/packages/f8/56/53a8f70f562dfc466c766469133a8a4909f6c0012d83993143f2a9d48d2d/mypy-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53", size = 10120644, upload-time = "2025-11-28T15:47:43.99Z" }, + { url = "https://files.pythonhosted.org/packages/b0/f4/7751f32f56916f7f8c229fe902cbdba3e4dd3f3ea9e8b872be97e7fc546d/mypy-1.19.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d", size = 13185236, upload-time = "2025-11-28T15:45:20.696Z" }, + { url = "https://files.pythonhosted.org/packages/35/31/871a9531f09e78e8d145032355890384f8a5b38c95a2c7732d226b93242e/mypy-1.19.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18", size = 12213902, upload-time = "2025-11-28T15:46:10.117Z" }, + { url = "https://files.pythonhosted.org/packages/58/b8/af221910dd40eeefa2077a59107e611550167b9994693fc5926a0b0f87c0/mypy-1.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7", size = 12738600, upload-time = "2025-11-28T15:44:22.521Z" }, + { url = "https://files.pythonhosted.org/packages/11/9f/c39e89a3e319c1d9c734dedec1183b2cc3aefbab066ec611619002abb932/mypy-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f", size = 13592639, upload-time = "2025-11-28T15:48:08.55Z" }, + { url = "https://files.pythonhosted.org/packages/97/6d/ffaf5f01f5e284d9033de1267e6c1b8f3783f2cf784465378a86122e884b/mypy-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835", size = 13799132, upload-time = "2025-11-28T15:47:06.032Z" }, + { url = "https://files.pythonhosted.org/packages/fe/b0/c33921e73aaa0106224e5a34822411bea38046188eb781637f5a5b07e269/mypy-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1", size = 10269832, upload-time = "2025-11-28T15:47:29.392Z" }, + { url = "https://files.pythonhosted.org/packages/09/0e/fe228ed5aeab470c6f4eb82481837fadb642a5aa95cc8215fd2214822c10/mypy-1.19.0-py3-none-any.whl", hash = "sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9", size = 2469714, upload-time = "2025-11-28T15:45:33.22Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, +] + +[[package]] +name = "omegaconf" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/48/6388f1bb9da707110532cb70ec4d2822858ddfb44f1cdf1233c20a80ea4b/omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7", size = 3298120, upload-time = "2022-12-08T20:59:22.753Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, +] + +[[package]] +name = "orjson" +version = "3.11.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/b8/333fdb27840f3bf04022d21b654a35f58e15407183aeb16f3b41aa053446/orjson-3.11.5.tar.gz", hash = "sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5", size = 5972347, upload-time = "2025-12-06T15:55:39.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a4/8052a029029b096a78955eadd68ab594ce2197e24ec50e6b6d2ab3f4e33b/orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d", size = 245347, upload-time = "2025-12-06T15:54:22.061Z" }, + { url = "https://files.pythonhosted.org/packages/64/67/574a7732bd9d9d79ac620c8790b4cfe0717a3d5a6eb2b539e6e8995e24a0/orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626", size = 129435, upload-time = "2025-12-06T15:54:23.615Z" }, + { url = "https://files.pythonhosted.org/packages/52/8d/544e77d7a29d90cf4d9eecd0ae801c688e7f3d1adfa2ebae5e1e94d38ab9/orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f", size = 132074, upload-time = "2025-12-06T15:54:24.694Z" }, + { url = "https://files.pythonhosted.org/packages/6e/57/b9f5b5b6fbff9c26f77e785baf56ae8460ef74acdb3eae4931c25b8f5ba9/orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85", size = 130520, upload-time = "2025-12-06T15:54:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6d/d34970bf9eb33f9ec7c979a262cad86076814859e54eb9a059a52f6dc13d/orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9", size = 136209, upload-time = "2025-12-06T15:54:27.264Z" }, + { url = "https://files.pythonhosted.org/packages/e7/39/bc373b63cc0e117a105ea12e57280f83ae52fdee426890d57412432d63b3/orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626", size = 139837, upload-time = "2025-12-06T15:54:28.75Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7c4818c8d7d324da220f4f1af55c343956003aa4d1ce1857bdc1d396ba69/orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa", size = 137307, upload-time = "2025-12-06T15:54:29.856Z" }, + { url = "https://files.pythonhosted.org/packages/46/bf/0993b5a056759ba65145effe3a79dd5a939d4a070eaa5da2ee3180fbb13f/orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477", size = 139020, upload-time = "2025-12-06T15:54:31.024Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/83a6c95db3039e504eda60fc388f9faedbb4f6472f5aba7084e06552d9aa/orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e", size = 141099, upload-time = "2025-12-06T15:54:32.196Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b4/24fdc024abfce31c2f6812973b0a693688037ece5dc64b7a60c1ce69e2f2/orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69", size = 413540, upload-time = "2025-12-06T15:54:33.361Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/01c0ec95d55ed0c11e4cae3e10427e479bba40c77312b63e1f9665e0737d/orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3", size = 151530, upload-time = "2025-12-06T15:54:34.6Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d4/f9ebc57182705bb4bbe63f5bbe14af43722a2533135e1d2fb7affa0c355d/orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca", size = 141863, upload-time = "2025-12-06T15:54:35.801Z" }, + { url = "https://files.pythonhosted.org/packages/0d/04/02102b8d19fdcb009d72d622bb5781e8f3fae1646bf3e18c53d1bc8115b5/orjson-3.11.5-cp312-cp312-win32.whl", hash = "sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98", size = 135255, upload-time = "2025-12-06T15:54:37.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fb/f05646c43d5450492cb387de5549f6de90a71001682c17882d9f66476af5/orjson-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875", size = 133252, upload-time = "2025-12-06T15:54:38.401Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/7b8c0b26ba18c793533ac1cd145e131e46fcf43952aa94c109b5b913c1f0/orjson-3.11.5-cp312-cp312-win_arm64.whl", hash = "sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe", size = 126777, upload-time = "2025-12-06T15:54:39.515Z" }, + { url = "https://files.pythonhosted.org/packages/10/43/61a77040ce59f1569edf38f0b9faadc90c8cf7e9bec2e0df51d0132c6bb7/orjson-3.11.5-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629", size = 245271, upload-time = "2025-12-06T15:54:40.878Z" }, + { url = "https://files.pythonhosted.org/packages/55/f9/0f79be617388227866d50edd2fd320cb8fb94dc1501184bb1620981a0aba/orjson-3.11.5-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3", size = 129422, upload-time = "2025-12-06T15:54:42.403Z" }, + { url = "https://files.pythonhosted.org/packages/77/42/f1bf1549b432d4a78bfa95735b79b5dac75b65b5bb815bba86ad406ead0a/orjson-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39", size = 132060, upload-time = "2025-12-06T15:54:43.531Z" }, + { url = "https://files.pythonhosted.org/packages/25/49/825aa6b929f1a6ed244c78acd7b22c1481fd7e5fda047dc8bf4c1a807eb6/orjson-3.11.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f", size = 130391, upload-time = "2025-12-06T15:54:45.059Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/de55391858b49e16e1aa8f0bbbb7e5997b7345d8e984a2dec3746d13065b/orjson-3.11.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51", size = 135964, upload-time = "2025-12-06T15:54:46.576Z" }, + { url = "https://files.pythonhosted.org/packages/1c/40/820bc63121d2d28818556a2d0a09384a9f0262407cf9fa305e091a8048df/orjson-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8", size = 139817, upload-time = "2025-12-06T15:54:48.084Z" }, + { url = "https://files.pythonhosted.org/packages/09/c7/3a445ca9a84a0d59d26365fd8898ff52bdfcdcb825bcc6519830371d2364/orjson-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706", size = 137336, upload-time = "2025-12-06T15:54:49.426Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b3/dc0d3771f2e5d1f13368f56b339c6782f955c6a20b50465a91acb79fe961/orjson-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f", size = 138993, upload-time = "2025-12-06T15:54:50.939Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a2/65267e959de6abe23444659b6e19c888f242bf7725ff927e2292776f6b89/orjson-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863", size = 141070, upload-time = "2025-12-06T15:54:52.414Z" }, + { url = "https://files.pythonhosted.org/packages/63/c9/da44a321b288727a322c6ab17e1754195708786a04f4f9d2220a5076a649/orjson-3.11.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228", size = 413505, upload-time = "2025-12-06T15:54:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/7f/17/68dc14fa7000eefb3d4d6d7326a190c99bb65e319f02747ef3ebf2452f12/orjson-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2", size = 151342, upload-time = "2025-12-06T15:54:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c5/ccee774b67225bed630a57478529fc026eda33d94fe4c0eac8fe58d4aa52/orjson-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05", size = 141823, upload-time = "2025-12-06T15:54:56.331Z" }, + { url = "https://files.pythonhosted.org/packages/67/80/5d00e4155d0cd7390ae2087130637671da713959bb558db9bac5e6f6b042/orjson-3.11.5-cp313-cp313-win32.whl", hash = "sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef", size = 135236, upload-time = "2025-12-06T15:54:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/95/fe/792cc06a84808dbdc20ac6eab6811c53091b42f8e51ecebf14b540e9cfe4/orjson-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583", size = 133167, upload-time = "2025-12-06T15:54:58.71Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/d158bd8b50e3b1cfdcf406a7e463f6ffe3f0d167b99634717acdaf5e299f/orjson-3.11.5-cp313-cp313-win_arm64.whl", hash = "sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287", size = 126712, upload-time = "2025-12-06T15:54:59.892Z" }, + { url = "https://files.pythonhosted.org/packages/c2/60/77d7b839e317ead7bb225d55bb50f7ea75f47afc489c81199befc5435b50/orjson-3.11.5-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0", size = 245252, upload-time = "2025-12-06T15:55:01.127Z" }, + { url = "https://files.pythonhosted.org/packages/f1/aa/d4639163b400f8044cef0fb9aa51b0337be0da3a27187a20d1166e742370/orjson-3.11.5-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81", size = 129419, upload-time = "2025-12-06T15:55:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/30/94/9eabf94f2e11c671111139edf5ec410d2f21e6feee717804f7e8872d883f/orjson-3.11.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f", size = 132050, upload-time = "2025-12-06T15:55:03.918Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c8/ca10f5c5322f341ea9a9f1097e140be17a88f88d1cfdd29df522970d9744/orjson-3.11.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e", size = 130370, upload-time = "2025-12-06T15:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/25/d4/e96824476d361ee2edd5c6290ceb8d7edf88d81148a6ce172fc00278ca7f/orjson-3.11.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7", size = 136012, upload-time = "2025-12-06T15:55:06.402Z" }, + { url = "https://files.pythonhosted.org/packages/85/8e/9bc3423308c425c588903f2d103cfcfe2539e07a25d6522900645a6f257f/orjson-3.11.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb", size = 139809, upload-time = "2025-12-06T15:55:07.656Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3c/b404e94e0b02a232b957c54643ce68d0268dacb67ac33ffdee24008c8b27/orjson-3.11.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4", size = 137332, upload-time = "2025-12-06T15:55:08.961Z" }, + { url = "https://files.pythonhosted.org/packages/51/30/cc2d69d5ce0ad9b84811cdf4a0cd5362ac27205a921da524ff42f26d65e0/orjson-3.11.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad", size = 138983, upload-time = "2025-12-06T15:55:10.595Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/de3223944a3e297d4707d2fe3b1ffb71437550e165eaf0ca8bbe43ccbcb1/orjson-3.11.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829", size = 141069, upload-time = "2025-12-06T15:55:11.832Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/81d5087ae74be33bcae3ff2d80f5ccaa4a8fedc6d39bf65a427a95b8977f/orjson-3.11.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac", size = 413491, upload-time = "2025-12-06T15:55:13.314Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6f/f6058c21e2fc1efaf918986dbc2da5cd38044f1a2d4b7b91ad17c4acf786/orjson-3.11.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d", size = 151375, upload-time = "2025-12-06T15:55:14.715Z" }, + { url = "https://files.pythonhosted.org/packages/54/92/c6921f17d45e110892899a7a563a925b2273d929959ce2ad89e2525b885b/orjson-3.11.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439", size = 141850, upload-time = "2025-12-06T15:55:15.94Z" }, + { url = "https://files.pythonhosted.org/packages/88/86/cdecb0140a05e1a477b81f24739da93b25070ee01ce7f7242f44a6437594/orjson-3.11.5-cp314-cp314-win32.whl", hash = "sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499", size = 135278, upload-time = "2025-12-06T15:55:17.202Z" }, + { url = "https://files.pythonhosted.org/packages/e4/97/b638d69b1e947d24f6109216997e38922d54dcdcdb1b11c18d7efd2d3c59/orjson-3.11.5-cp314-cp314-win_amd64.whl", hash = "sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310", size = 133170, upload-time = "2025-12-06T15:55:18.468Z" }, + { url = "https://files.pythonhosted.org/packages/8f/dd/f4fff4a6fe601b4f8f3ba3aa6da8ac33d17d124491a3b804c662a70e1636/orjson-3.11.5-cp314-cp314-win_arm64.whl", hash = "sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5", size = 126713, upload-time = "2025-12-06T15:55:19.738Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pillow" +version = "11.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, + { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, + { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, + { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, + { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, + { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, + { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, + { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, + { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, + { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, + { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, + { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, + { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, + { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, + { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, + { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, + { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, + { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, + { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/9b/6a4ffb4ed980519da959e1cf3122fc6cb41211daa58dbae1c73c0e519a37/pre_commit-4.5.0.tar.gz", hash = "sha256:dc5a065e932b19fc1d4c653c6939068fe54325af8e741e74e88db4d28a4dd66b", size = 198428, upload-time = "2025-11-22T21:02:42.304Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/c4/b2d28e9d2edf4f1713eb3c29307f1a63f3d67cf09bdda29715a36a68921a/pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1", size = 226429, upload-time = "2025-11-22T21:02:40.836Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, +] + +[[package]] +name = "pydantic" +version = "2.11.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.33.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, +] + +[[package]] +name = "pydub" +version = "0.25.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/9a/e6bca0eed82db26562c73b5076539a4a08d3cffd19c3cc5913a3e61145fd/pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f", size = 38326, upload-time = "2021-03-10T02:09:54.659Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", size = 32327, upload-time = "2021-03-10T02:09:53.503Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pylint" +version = "4.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d2/b081da1a8930d00e3fc06352a1d449aaf815d4982319fab5d8cdb2e9ab35/pylint-4.0.4.tar.gz", hash = "sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2", size = 1571735, upload-time = "2025-11-30T13:29:04.315Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/92/d40f5d937517cc489ad848fc4414ecccc7592e4686b9071e09e64f5e378e/pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0", size = 536425, upload-time = "2025-11-30T13:29:02.53Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/d9/f7a0c4b3a2bf2556cd5d99b05372c29980249ef71e8e32669ba77428c82c/ruff-0.14.8.tar.gz", hash = "sha256:774ed0dd87d6ce925e3b8496feb3a00ac564bea52b9feb551ecd17e0a23d1eed", size = 5765385, upload-time = "2025-12-04T15:06:17.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/b8/9537b52010134b1d2b72870cc3f92d5fb759394094741b09ceccae183fbe/ruff-0.14.8-py3-none-linux_armv6l.whl", hash = "sha256:ec071e9c82eca417f6111fd39f7043acb53cd3fde9b1f95bbed745962e345afb", size = 13441540, upload-time = "2025-12-04T15:06:14.896Z" }, + { url = "https://files.pythonhosted.org/packages/24/00/99031684efb025829713682012b6dd37279b1f695ed1b01725f85fd94b38/ruff-0.14.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8cdb162a7159f4ca36ce980a18c43d8f036966e7f73f866ac8f493b75e0c27e9", size = 13669384, upload-time = "2025-12-04T15:06:51.809Z" }, + { url = "https://files.pythonhosted.org/packages/72/64/3eb5949169fc19c50c04f28ece2c189d3b6edd57e5b533649dae6ca484fe/ruff-0.14.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e2fcbefe91f9fad0916850edf0854530c15bd1926b6b779de47e9ab619ea38f", size = 12806917, upload-time = "2025-12-04T15:06:08.925Z" }, + { url = "https://files.pythonhosted.org/packages/c4/08/5250babb0b1b11910f470370ec0cbc67470231f7cdc033cee57d4976f941/ruff-0.14.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d70721066a296f45786ec31916dc287b44040f553da21564de0ab4d45a869b", size = 13256112, upload-time = "2025-12-04T15:06:23.498Z" }, + { url = "https://files.pythonhosted.org/packages/78/4c/6c588e97a8e8c2d4b522c31a579e1df2b4d003eddfbe23d1f262b1a431ff/ruff-0.14.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c87e09b3cd9d126fc67a9ecd3b5b1d3ded2b9c7fce3f16e315346b9d05cfb52", size = 13227559, upload-time = "2025-12-04T15:06:33.432Z" }, + { url = "https://files.pythonhosted.org/packages/23/ce/5f78cea13eda8eceac71b5f6fa6e9223df9b87bb2c1891c166d1f0dce9f1/ruff-0.14.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d62cb310c4fbcb9ee4ac023fe17f984ae1e12b8a4a02e3d21489f9a2a5f730c", size = 13896379, upload-time = "2025-12-04T15:06:02.687Z" }, + { url = "https://files.pythonhosted.org/packages/cf/79/13de4517c4dadce9218a20035b21212a4c180e009507731f0d3b3f5df85a/ruff-0.14.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1af35c2d62633d4da0521178e8a2641c636d2a7153da0bac1b30cfd4ccd91344", size = 15372786, upload-time = "2025-12-04T15:06:29.828Z" }, + { url = "https://files.pythonhosted.org/packages/00/06/33df72b3bb42be8a1c3815fd4fae83fa2945fc725a25d87ba3e42d1cc108/ruff-0.14.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25add4575ffecc53d60eed3f24b1e934493631b48ebbc6ebaf9d8517924aca4b", size = 14990029, upload-time = "2025-12-04T15:06:36.812Z" }, + { url = "https://files.pythonhosted.org/packages/64/61/0f34927bd90925880394de0e081ce1afab66d7b3525336f5771dcf0cb46c/ruff-0.14.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c943d847b7f02f7db4201a0600ea7d244d8a404fbb639b439e987edcf2baf9a", size = 14407037, upload-time = "2025-12-04T15:06:39.979Z" }, + { url = "https://files.pythonhosted.org/packages/96/bc/058fe0aefc0fbf0d19614cb6d1a3e2c048f7dc77ca64957f33b12cfdc5ef/ruff-0.14.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb6e8bf7b4f627548daa1b69283dac5a296bfe9ce856703b03130732e20ddfe2", size = 14102390, upload-time = "2025-12-04T15:06:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/af/a4/e4f77b02b804546f4c17e8b37a524c27012dd6ff05855d2243b49a7d3cb9/ruff-0.14.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:7aaf2974f378e6b01d1e257c6948207aec6a9b5ba53fab23d0182efb887a0e4a", size = 14230793, upload-time = "2025-12-04T15:06:20.497Z" }, + { url = "https://files.pythonhosted.org/packages/3f/52/bb8c02373f79552e8d087cedaffad76b8892033d2876c2498a2582f09dcf/ruff-0.14.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e5758ca513c43ad8a4ef13f0f081f80f08008f410790f3611a21a92421ab045b", size = 13160039, upload-time = "2025-12-04T15:06:49.06Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ad/b69d6962e477842e25c0b11622548df746290cc6d76f9e0f4ed7456c2c31/ruff-0.14.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f74f7ba163b6e85a8d81a590363bf71618847e5078d90827749bfda1d88c9cdf", size = 13205158, upload-time = "2025-12-04T15:06:54.574Z" }, + { url = "https://files.pythonhosted.org/packages/06/63/54f23da1315c0b3dfc1bc03fbc34e10378918a20c0b0f086418734e57e74/ruff-0.14.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eed28f6fafcc9591994c42254f5a5c5ca40e69a30721d2ab18bb0bb3baac3ab6", size = 13469550, upload-time = "2025-12-04T15:05:59.209Z" }, + { url = "https://files.pythonhosted.org/packages/70/7d/a4d7b1961e4903bc37fffb7ddcfaa7beb250f67d97cfd1ee1d5cddb1ec90/ruff-0.14.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:21d48fa744c9d1cb8d71eb0a740c4dd02751a5de9db9a730a8ef75ca34cf138e", size = 14211332, upload-time = "2025-12-04T15:06:06.027Z" }, + { url = "https://files.pythonhosted.org/packages/5d/93/2a5063341fa17054e5c86582136e9895db773e3c2ffb770dde50a09f35f0/ruff-0.14.8-py3-none-win32.whl", hash = "sha256:15f04cb45c051159baebb0f0037f404f1dc2f15a927418f29730f411a79bc4e7", size = 13151890, upload-time = "2025-12-04T15:06:11.668Z" }, + { url = "https://files.pythonhosted.org/packages/02/1c/65c61a0859c0add13a3e1cbb6024b42de587456a43006ca2d4fd3d1618fe/ruff-0.14.8-py3-none-win_amd64.whl", hash = "sha256:9eeb0b24242b5bbff3011409a739929f497f3fb5fe3b5698aba5e77e8c833097", size = 14537826, upload-time = "2025-12-04T15:06:26.409Z" }, + { url = "https://files.pythonhosted.org/packages/6d/63/8b41cea3afd7f58eb64ac9251668ee0073789a3bc9ac6f816c8c6fef986d/ruff-0.14.8-py3-none-win_arm64.whl", hash = "sha256:965a582c93c63fe715fd3e3f8aa37c4b776777203d8e1d8aa3cc0c14424a4b99", size = 13634522, upload-time = "2025-12-04T15:06:43.212Z" }, +] + +[[package]] +name = "safehttpx" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/d1/4282284d9cf1ee873607a46442da977fc3c985059315ab23610be31d5885/safehttpx-0.1.7.tar.gz", hash = "sha256:db201c0978c41eddb8bb480f3eee59dd67304fdd91646035e9d9a720049a9d23", size = 10385, upload-time = "2025-10-24T18:30:09.783Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/a3/0f0b7d78e2f1eb9e8e1afbff1d2bff8d60144aee17aca51c065b516743dd/safehttpx-0.1.7-py3-none-any.whl", hash = "sha256:c4f4a162db6993464d7ca3d7cc4af0ffc6515a606dfd220b9f82c6945d869cde", size = 8959, upload-time = "2025-10-24T18:30:08.733Z" }, +] + +[[package]] +name = "semantic-version" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/31/f2289ce78b9b473d582568c234e104d2a342fd658cc288a7553d83bb8595/semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c", size = 52289, upload-time = "2022-05-26T13:35:23.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177", size = 15552, upload-time = "2022-05-26T13:35:21.206Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "starlette" +version = "0.46.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[package]] +name = "typer-slim" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/45/81b94a52caed434b94da65729c03ad0fb7665fab0f7db9ee54c94e541403/typer_slim-0.20.0.tar.gz", hash = "sha256:9fc6607b3c6c20f5c33ea9590cbeb17848667c51feee27d9e314a579ab07d1a3", size = 106561, upload-time = "2025-10-20T17:03:46.642Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/dd/5cbf31f402f1cc0ab087c94d4669cfa55bd1e818688b910631e131d74e75/typer_slim-0.20.0-py3-none-any.whl", hash = "sha256:f42a9b7571a12b97dddf364745d29f12221865acef7a2680065f9bb29c7dc89d", size = 47087, upload-time = "2025-10-20T17:03:44.546Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/43/554c2569b62f49350597348fc3ac70f786e3c32e7f19d266e19817812dd3/urllib3-2.6.0.tar.gz", hash = "sha256:cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1", size = 432585, upload-time = "2025-12-05T15:08:47.885Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl", hash = "sha256:c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f", size = 131083, upload-time = "2025-12-05T15:08:45.983Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.34.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.35.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, +] + +[[package]] +name = "web" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "gradio" }, + { name = "hydra-core" }, + { name = "requests" }, +] + +[package.optional-dependencies] +dev = [ + { name = "autopep8" }, + { name = "fastapi" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pylint" }, + { name = "uvicorn" }, +] + +[package.metadata] +requires-dist = [ + { name = "autopep8", marker = "extra == 'dev'", specifier = ">=2.3.2" }, + { name = "fastapi", marker = "extra == 'dev'", specifier = "==0.115.12" }, + { name = "gradio", specifier = "==5.33.0" }, + { name = "hydra-core", specifier = "==1.3.2" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, + { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, + { name = "requests", specifier = "==2.32.3" }, + { name = "uvicorn", marker = "extra == 'dev'", specifier = "==0.34.3" }, +] +provides-extras = ["dev"] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, +] diff --git a/services/web-app/web.Dockerfile b/services/web-app/web.Dockerfile new file mode 100644 index 0000000..9e36ed5 --- /dev/null +++ b/services/web-app/web.Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +WORKDIR /home/appuser/app + +RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash + +RUN chown -R appuser:appuser /home/appuser/ + +USER appuser + +CMD ["/bin/bash", "./entrypoint.dev.bash"] From 97121b01ebb248563fea9930fde7f8e2229ffd20 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 12:12:36 +0100 Subject: [PATCH 007/108] Run pre-commit --- .gitignore | 2 +- docker-compose.yml | 7 ++++--- justfile | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 7313dff..bcbf3a7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ **/__pycache__/ persistent_data/ .venv/ -.mypy_cache/ \ No newline at end of file +.mypy_cache/ diff --git a/docker-compose.yml b/docker-compose.yml index 10e7f15..f474576 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ -version: "3.9" +--- +version: '3.9' services: core-service: @@ -7,7 +8,7 @@ services: dockerfile: services/core-service/Dockerfile container_name: core-service ports: - - "8001:8000" + - 8001:8000 networks: - rag-net @@ -17,7 +18,7 @@ services: dockerfile: services/api-gateway/Dockerfile container_name: api-gateway ports: - - "8080:8000" + - 8080:8000 depends_on: - core-service networks: diff --git a/justfile b/justfile index f7edd83..a0b6b12 100644 --- a/justfile +++ b/justfile @@ -13,4 +13,3 @@ run-pre-commit: setup-dev: uv venv uv sync --project . --extra dev - From bad7cfea006af03ebb920ee9832f15d382db8f9e Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 12:14:09 +0100 Subject: [PATCH 008/108] Temporarily delete all unimplemented services --- .devcontainer/api-gateway/devcontainer.json | 30 -------------- .devcontainer/core-service/devcontainer.json | 28 ------------- .../embedder-service/devcontainer.json | 30 -------------- .../ingestion-service/devcontainer.json | 30 -------------- .devcontainer/llm-proxy/devcontainer.json | 30 -------------- services/api-gateway/Dockerfile | 13 ------ services/api-gateway/app/main.py | 40 ------------------- services/api-gateway/requirements.txt | 4 -- services/core-service/Dockerfile | 13 ------ services/core-service/app/main.py | 29 -------------- services/core-service/requirements.txt | 3 -- services/embedder-service/Dockerfile | 13 ------ services/embedder-service/app/main.py | 26 ------------ services/embedder-service/requirements.txt | 3 -- services/ingestion-service/Dockerfile | 13 ------ services/ingestion-service/app/main.py | 32 --------------- services/ingestion-service/requirements.txt | 3 -- services/llm-proxy/Dockerfile | 13 ------ services/llm-proxy/app/main.py | 24 ----------- services/llm-proxy/requirements.txt | 3 -- 20 files changed, 380 deletions(-) delete mode 100644 .devcontainer/api-gateway/devcontainer.json delete mode 100644 .devcontainer/core-service/devcontainer.json delete mode 100644 .devcontainer/embedder-service/devcontainer.json delete mode 100644 .devcontainer/ingestion-service/devcontainer.json delete mode 100644 .devcontainer/llm-proxy/devcontainer.json delete mode 100644 services/api-gateway/Dockerfile delete mode 100644 services/api-gateway/app/main.py delete mode 100644 services/api-gateway/requirements.txt delete mode 100644 services/core-service/Dockerfile delete mode 100644 services/core-service/app/main.py delete mode 100644 services/core-service/requirements.txt delete mode 100644 services/embedder-service/Dockerfile delete mode 100644 services/embedder-service/app/main.py delete mode 100644 services/embedder-service/requirements.txt delete mode 100644 services/ingestion-service/Dockerfile delete mode 100644 services/ingestion-service/app/main.py delete mode 100644 services/ingestion-service/requirements.txt delete mode 100644 services/llm-proxy/Dockerfile delete mode 100644 services/llm-proxy/app/main.py delete mode 100644 services/llm-proxy/requirements.txt diff --git a/.devcontainer/api-gateway/devcontainer.json b/.devcontainer/api-gateway/devcontainer.json deleted file mode 100644 index 66d1902..0000000 --- a/.devcontainer/api-gateway/devcontainer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "api-gateway", - - "build": { - "dockerfile": "../base/Dockerfile", - "context": "../.." - }, - - "workspaceMount": "source=${localWorkspaceFolder},target=/home/base/workspace,type=bind", - "workspaceFolder": "/home/base/workspace", - - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/base/.ssh,readonly=true", - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - - "remoteUser": "base", - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - }, - - "overrideCommand": true, - - "postCreateCommand": "pip install --break-system-packages -r services/api-gateway/requirements.txt", - - "postStartCommand": "uvicorn services.api-gateway.app.main:app --host 0.0.0.0 --port 8000", - - "forwardPorts": [8000] -} diff --git a/.devcontainer/core-service/devcontainer.json b/.devcontainer/core-service/devcontainer.json deleted file mode 100644 index 4aed78e..0000000 --- a/.devcontainer/core-service/devcontainer.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "core-service", - "build": { - "dockerfile": "../base/Dockerfile", - "context": "../.." - }, - - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", - "workspaceFolder": "/workspace/services/core-service", - - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - }, - - "overrideCommand": true, - - "postCreateCommand": "pip install --break-system-packages -r requirements.txt", - - "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", - - "forwardPorts": [8000] -} diff --git a/.devcontainer/embedder-service/devcontainer.json b/.devcontainer/embedder-service/devcontainer.json deleted file mode 100644 index 09a65cf..0000000 --- a/.devcontainer/embedder-service/devcontainer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "embedder-service", - "build": { - "dockerfile": "../base/Dockerfile", - "context": "../.." - }, - - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", - "workspaceFolder": "/workspace/services/embedder-service", - - - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - }, - - "overrideCommand": true, - - "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", - "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", - - - "forwardPorts": [8000] -} - diff --git a/.devcontainer/ingestion-service/devcontainer.json b/.devcontainer/ingestion-service/devcontainer.json deleted file mode 100644 index c69fb9a..0000000 --- a/.devcontainer/ingestion-service/devcontainer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "ingestion-service", - "build": { - "dockerfile": "../base/Dockerfile", - "context": "../.." - }, - - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", - "workspaceFolder": "/workspace/services/ingestion-service", - - - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - }, - - "overrideCommand": true, - - "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", - "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", - - - "forwardPorts": [8000] -} - diff --git a/.devcontainer/llm-proxy/devcontainer.json b/.devcontainer/llm-proxy/devcontainer.json deleted file mode 100644 index cd4651a..0000000 --- a/.devcontainer/llm-proxy/devcontainer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "llm-proxy", - "build": { - "dockerfile": "../base/Dockerfile", - "context": "../.." - }, - - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", - "workspaceFolder": "/workspace/services/llm-proxy", - - - "mounts": [ - "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent", - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly=true", - "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" - ], - - "remoteEnv": { - "SSH_AUTH_SOCK": "/ssh-agent" - }, - - "overrideCommand": true, - - "postCreateCommand": "pip install --user --break-system-packages -r requirements.txt", - "postStartCommand": "uvicorn app.main:app --host 0.0.0.0 --port 8000", - - - "forwardPorts": [8000] -} - diff --git a/services/api-gateway/Dockerfile b/services/api-gateway/Dockerfile deleted file mode 100644 index aab9551..0000000 --- a/services/api-gateway/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential - -COPY services/api-gateway/requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt - -COPY services/api-gateway/app /app/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/api-gateway/app/main.py b/services/api-gateway/app/main.py deleted file mode 100644 index 94c8791..0000000 --- a/services/api-gateway/app/main.py +++ /dev/null @@ -1,40 +0,0 @@ -from fastapi import FastAPI, HTTPException -from pydantic import BaseModel -import httpx - -CORE_SERVICE_URL = "http://core-service:8000/query" - - -class AskRequest(BaseModel): - query: str - - -class AskResponse(BaseModel): - answer: str - - -app = FastAPI(title="API Gateway") - - -@app.get("/health") -async def health() -> dict: - return {"status": "ok"} - - -@app.post("/ask", response_model=AskResponse) -async def ask(payload: AskRequest) -> AskResponse: - try: - async with httpx.AsyncClient() as client: - response = await client.post(CORE_SERVICE_URL, json=payload.dict()) - response.raise_for_status() - except httpx.HTTPError as exc: # pragma: no cover - placeholder error handling - raise HTTPException(status_code=502, detail=f"core-service error: {exc}") from exc - - data = response.json() - return AskResponse(answer=data.get("answer", "")) - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/api-gateway/requirements.txt b/services/api-gateway/requirements.txt deleted file mode 100644 index 55e411b..0000000 --- a/services/api-gateway/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -fastapi -uvicorn -pydantic -httpx diff --git a/services/core-service/Dockerfile b/services/core-service/Dockerfile deleted file mode 100644 index 2d532c0..0000000 --- a/services/core-service/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential - -COPY services/core-service/requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt - -COPY services/core-service/app /app/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/core-service/app/main.py b/services/core-service/app/main.py deleted file mode 100644 index a20b23c..0000000 --- a/services/core-service/app/main.py +++ /dev/null @@ -1,29 +0,0 @@ -from fastapi import FastAPI -from pydantic import BaseModel - - -class QueryRequest(BaseModel): - query: str - - -class QueryResponse(BaseModel): - answer: str - - -def run_query(query: str) -> str: - return f"dummy answer for: {query}" - - -app = FastAPI(title="Core Service") - - -@app.post("/query", response_model=QueryResponse) -async def query(payload: QueryRequest) -> QueryResponse: - answer = run_query(payload.query) - return QueryResponse(answer=answer) - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/core-service/requirements.txt b/services/core-service/requirements.txt deleted file mode 100644 index c9b6004..0000000 --- a/services/core-service/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -fastapi -uvicorn -pydantic diff --git a/services/embedder-service/Dockerfile b/services/embedder-service/Dockerfile deleted file mode 100644 index 55d468d..0000000 --- a/services/embedder-service/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential - -COPY services/embedder-service/requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt - -COPY services/embedder-service/app /app/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/embedder-service/app/main.py b/services/embedder-service/app/main.py deleted file mode 100644 index bf52c4e..0000000 --- a/services/embedder-service/app/main.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import List -from fastapi import FastAPI -from pydantic import BaseModel - - -class EmbedRequest(BaseModel): - texts: List[str] - - -class EmbedResponse(BaseModel): - embeddings: List[List[float]] - - -app = FastAPI(title="Embedder Service") - - -@app.post("/embed", response_model=EmbedResponse) -async def embed(payload: EmbedRequest) -> EmbedResponse: - embeddings = [[float(len(text))] for text in payload.texts] - return EmbedResponse(embeddings=embeddings) - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/embedder-service/requirements.txt b/services/embedder-service/requirements.txt deleted file mode 100644 index c9b6004..0000000 --- a/services/embedder-service/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -fastapi -uvicorn -pydantic diff --git a/services/ingestion-service/Dockerfile b/services/ingestion-service/Dockerfile deleted file mode 100644 index c04f8c8..0000000 --- a/services/ingestion-service/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential - -COPY services/ingestion-service/requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt - -COPY services/ingestion-service/app /app/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/ingestion-service/app/main.py b/services/ingestion-service/app/main.py deleted file mode 100644 index f8d39ec..0000000 --- a/services/ingestion-service/app/main.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging -from typing import List -from fastapi import FastAPI -from pydantic import BaseModel - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -class IngestRequest(BaseModel): - documents: List[str] - - -class IngestResponse(BaseModel): - ingested: int - status: str - - -app = FastAPI(title="Ingestion Service") - - -@app.post("/ingest", response_model=IngestResponse) -async def ingest(payload: IngestRequest) -> IngestResponse: - count = len(payload.documents) - logger.info("Received %s documents for ingestion", count) - return IngestResponse(ingested=count, status="ok") - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/ingestion-service/requirements.txt b/services/ingestion-service/requirements.txt deleted file mode 100644 index c9b6004..0000000 --- a/services/ingestion-service/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -fastapi -uvicorn -pydantic diff --git a/services/llm-proxy/Dockerfile b/services/llm-proxy/Dockerfile deleted file mode 100644 index 8aaa0cf..0000000 --- a/services/llm-proxy/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential - -COPY services/llm-proxy/requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt - -COPY services/llm-proxy/app /app/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/llm-proxy/app/main.py b/services/llm-proxy/app/main.py deleted file mode 100644 index f05569d..0000000 --- a/services/llm-proxy/app/main.py +++ /dev/null @@ -1,24 +0,0 @@ -from fastapi import FastAPI -from pydantic import BaseModel - - -class GenerateRequest(BaseModel): - prompt: str - - -class GenerateResponse(BaseModel): - output: str - - -app = FastAPI(title="LLM Proxy") - - -@app.post("/generate", response_model=GenerateResponse) -async def generate(payload: GenerateRequest) -> GenerateResponse: - return GenerateResponse(output=f"LLM output for: {payload.prompt}") - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/services/llm-proxy/requirements.txt b/services/llm-proxy/requirements.txt deleted file mode 100644 index c9b6004..0000000 --- a/services/llm-proxy/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -fastapi -uvicorn -pydantic From a241d9fac4f8c00b6bbe05ed5fe3817b3e34d4e5 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 22:11:39 +0000 Subject: [PATCH 009/108] Add "strict" option to mypy config --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 51947fc..aa13d50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ requires-python=">=3.12" [tool.mypy] disable_error_code = "import-untyped" +strict = true [tool.autopep8] aggressive = true From 73f8598a474c2c4b92b6c73c5302e40dd99e88c3 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 22:11:58 +0000 Subject: [PATCH 010/108] Run pre-commit on web-app files --- services/web-app/main_dev.py | 2 +- services/web-app/mock_backend.py | 9 +++++---- .../web-app/src/web/backend_communication.py | 18 ++++++++++++------ services/web-app/src/web/gui.py | 11 +++++++---- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 9945e34..0f397dc 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -7,7 +7,7 @@ import web -def _logger(): +def _logger() -> logging.Logger: return logging.getLogger('web_app') diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index aa5bbdb..d15c1c2 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -3,6 +3,7 @@ import json import logging import random +from typing import AsyncGenerator from typing import Dict from typing import List from typing import Tuple @@ -37,7 +38,7 @@ class RequestStreamChatResponse(pydantic.BaseModel): @app.get('/ping') -async def read_ping(): +async def read_ping() -> Dict[str, str]: """Health check endpoint.""" return {'message': 'Service is running'} @@ -58,7 +59,7 @@ async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCo @app.post('/stream_chat_response') -async def stream_chat_response(request: RequestStreamChatResponse): +async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingResponse: """Streams chat response for the user query based on the provided context.""" mock_response = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod @@ -73,7 +74,7 @@ async def stream_chat_response(request: RequestStreamChatResponse): response = ' '.join(random.sample(mock_words, len(mock_words))) response += f'Documents used: {[doc_id for doc_id, _ in request.context_docs]}' - async def event_generator(): + async def event_generator() -> AsyncGenerator[bytes]: for token in response.replace(' ', ' [split_token]') .split('[split_token]'): chunk = {'content': token} yield json.dumps(chunk).encode('utf-8') @@ -83,7 +84,7 @@ async def event_generator(): @hydra.main(version_base=None, config_path='cfg', config_name='mock_backend') -def main(cfg: omegaconf.DictConfig): +def main(cfg: omegaconf.DictConfig) -> None: """Sets up the mock backend service.""" logging.info('Starting mock backend with configuration: %s', diff --git a/services/web-app/src/web/backend_communication.py b/services/web-app/src/web/backend_communication.py index 1269999..ef67a47 100644 --- a/services/web-app/src/web/backend_communication.py +++ b/services/web-app/src/web/backend_communication.py @@ -3,18 +3,22 @@ import logging from typing import Any from typing import Dict +from typing import Iterator from typing import List from typing import Tuple +from typing import TypeAlias import httpx -import requests # type: ignore +import requests +ChatHistoryType: TypeAlias = List[Dict[str, str]] -def _logger(): + +def _logger() -> logging.Logger: return logging.getLogger('web_app') -def _sanitize_chat_history(chat_history: List[Dict[str, str]]): +def _sanitize_chat_history(chat_history: ChatHistoryType) -> ChatHistoryType: """Sanitizes the chat history to ensure it contains only relevant fields.""" return [ { @@ -62,12 +66,14 @@ def collect_context_info(self, response = requests.post(url, json=payload, timeout=5) response.raise_for_status() - return response.json().get('context_docs', []) + response_data = response.json() + + return list((title, content) for title, content in response_data['context_docs']) def stream_chat_response(self, user_message: str, - chat_history: List[Dict[str, Any]], - context_docs: List[Tuple[str, str]]): + chat_history: ChatHistoryType, + context_docs: List[Tuple[str, str]]) -> Iterator[Dict[str, str]]: """Collects LLM response based on the context and streams it. Args: diff --git a/services/web-app/src/web/gui.py b/services/web-app/src/web/gui.py index 26ee957..ee426e7 100644 --- a/services/web-app/src/web/gui.py +++ b/services/web-app/src/web/gui.py @@ -1,13 +1,15 @@ """Contains GUI related utils.""" import logging +from typing import Iterator from typing import List from typing import Tuple import gradio as gr import web +from web.backend_communication import ChatHistoryType -def _logger(): +def _logger() -> logging.Logger: return logging.getLogger('web_app') @@ -33,7 +35,7 @@ def __init__(self, self._backend_service = backend_service - def render_gui(self): + def render_gui(self) -> None: """Renders the UI for application and assigns the necessary callbacks.""" with gr.Row(elem_id='agh_header_row', height='70vh'): @@ -73,8 +75,9 @@ def render_gui(self): ) def _chat_interface_callback(self, - user_message, - history): + user_message: str, + history: ChatHistoryType + ) -> Iterator[Tuple[ChatHistoryType, gr.Markdown]]: """Main callback for the chat interface.""" history = history or [] From 949ad350b24e85d6d0273714c381af070510f9f4 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 8 Dec 2025 22:33:06 +0000 Subject: [PATCH 011/108] Rename "web" python package to "web_app" --- services/web-app/.gitignore | 2 +- services/web-app/justfile | 2 +- services/web-app/main_dev.py | 12 ++++++------ services/web-app/mock_backend.py | 4 ++-- services/web-app/pyproject.toml | 2 +- services/web-app/src/{web => web_app}/__init__.py | 0 .../src/{web => web_app}/backend_communication.py | 0 services/web-app/src/{web => web_app}/gui.py | 6 +++--- services/web-app/uv.lock | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) rename services/web-app/src/{web => web_app}/__init__.py (100%) rename services/web-app/src/{web => web_app}/backend_communication.py (100%) rename services/web-app/src/{web => web_app}/gui.py (95%) diff --git a/services/web-app/.gitignore b/services/web-app/.gitignore index 84df091..69ef917 100644 --- a/services/web-app/.gitignore +++ b/services/web-app/.gitignore @@ -1,3 +1,3 @@ -src/web.egg-info/ +src/web_app.egg-info/ data/ outputs/ diff --git a/services/web-app/justfile b/services/web-app/justfile index 2070603..3173801 100644 --- a/services/web-app/justfile +++ b/services/web-app/justfile @@ -13,7 +13,7 @@ setup-environment: # Run the Gradio web application with live reloading. run-app: - uv run gradio main_dev.py --watch-dirs . --demo-name web_app + uv run gradio main_dev.py --watch-dirs . --demo-name web_application # Run the mock backend server. run-mock-backend: diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 0f397dc..703cd08 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -4,7 +4,7 @@ import gradio as gr import hydra import omegaconf -import web +import web_app def _logger() -> logging.Logger: @@ -41,7 +41,7 @@ def _logger() -> logging.Logger: } }) -backend_service = web.backend_communication.BackendService( +backend_service = web_app.backend_communication.BackendService( backend_url=cfg.backend_entrypoint_url ) @@ -52,8 +52,8 @@ def _logger() -> logging.Logger: } """ -with gr.Blocks(fill_height=True, title='AGH Chat', css=CUSTOM_CSS) as web_app: - web.gui.MainController(backend_service).render_gui() +with gr.Blocks(fill_height=True, title='AGH Chat', css=CUSTOM_CSS) as web_application: + web_app.gui.MainController(backend_service).render_gui() -web_app.launch(server_name=cfg.web_app_host, - server_port=cfg.web_app_port) +web_application.launch(server_name=cfg.web_app_host, + server_port=cfg.web_app_port) diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index d15c1c2..76812cd 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -3,7 +3,7 @@ import json import logging import random -from typing import AsyncGenerator +from typing import AsyncIterator from typing import Dict from typing import List from typing import Tuple @@ -74,7 +74,7 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR response = ' '.join(random.sample(mock_words, len(mock_words))) response += f'Documents used: {[doc_id for doc_id, _ in request.context_docs]}' - async def event_generator() -> AsyncGenerator[bytes]: + async def event_generator() -> AsyncIterator[bytes]: for token in response.replace(' ', ' [split_token]') .split('[split_token]'): chunk = {'content': token} yield json.dumps(chunk).encode('utf-8') diff --git a/services/web-app/pyproject.toml b/services/web-app/pyproject.toml index c776d24..8b5f97a 100644 --- a/services/web-app/pyproject.toml +++ b/services/web-app/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "web" +name = "web_app" version = "0.1.0" requires-python=">=3.12" dependencies = [ diff --git a/services/web-app/src/web/__init__.py b/services/web-app/src/web_app/__init__.py similarity index 100% rename from services/web-app/src/web/__init__.py rename to services/web-app/src/web_app/__init__.py diff --git a/services/web-app/src/web/backend_communication.py b/services/web-app/src/web_app/backend_communication.py similarity index 100% rename from services/web-app/src/web/backend_communication.py rename to services/web-app/src/web_app/backend_communication.py diff --git a/services/web-app/src/web/gui.py b/services/web-app/src/web_app/gui.py similarity index 95% rename from services/web-app/src/web/gui.py rename to services/web-app/src/web_app/gui.py index ee426e7..18291c3 100644 --- a/services/web-app/src/web/gui.py +++ b/services/web-app/src/web_app/gui.py @@ -5,8 +5,8 @@ from typing import Tuple import gradio as gr -import web -from web.backend_communication import ChatHistoryType +import web_app +from web_app.backend_communication import ChatHistoryType def _logger() -> logging.Logger: @@ -31,7 +31,7 @@ class MainController: """Renders GUI elements and handles controller-view interactions.""" def __init__(self, - backend_service: web.backend_communication.BackendService): + backend_service: web_app.backend_communication.BackendService): self._backend_service = backend_service diff --git a/services/web-app/uv.lock b/services/web-app/uv.lock index 4c0f969..fb6b205 100644 --- a/services/web-app/uv.lock +++ b/services/web-app/uv.lock @@ -1361,7 +1361,7 @@ wheels = [ ] [[package]] -name = "web" +name = "web-app" version = "0.1.0" source = { editable = "." } dependencies = [ From 6928b1eb77dc6006dfd13add7139d115c73ebd01 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Dec 2025 18:26:45 +0000 Subject: [PATCH 012/108] Replace main backend service with services corresponding to specific endpoints --- services/web-app/cfg/main.yaml | 5 +- services/web-app/main_dev.py | 19 +++- services/web-app/mock_backend.py | 34 +++--- services/web-app/src/web_app/__init__.py | 2 +- .../web-app/src/web_app/backend/__init__.py | 0 .../src/web_app/backend/context_retriever.py | 56 ++++++++++ .../web-app/src/web_app/backend/llm_proxy.py | 56 ++++++++++ services/web-app/src/web_app/backend/utils.py | 18 +++ .../src/web_app/backend_communication.py | 104 ------------------ services/web-app/src/web_app/gui.py | 18 +-- 10 files changed, 175 insertions(+), 137 deletions(-) create mode 100644 services/web-app/src/web_app/backend/__init__.py create mode 100644 services/web-app/src/web_app/backend/context_retriever.py create mode 100644 services/web-app/src/web_app/backend/llm_proxy.py create mode 100644 services/web-app/src/web_app/backend/utils.py delete mode 100644 services/web-app/src/web_app/backend_communication.py diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml index cb8b0da..875c23d 100644 --- a/services/web-app/cfg/main.yaml +++ b/services/web-app/cfg/main.yaml @@ -1,5 +1,6 @@ --- -backend_entrypoint_url: http://localhost:8888 -persistent_data_path: /home/appuser/workspace/services/web-app/data/ +context_retriever_url: http://localhost:8888 +llm_proxy_url: http://localhost:8888 +persist_data_path: data/ web_app_port: 8080 web_app_host: localhost diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 703cd08..76a6594 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -1,10 +1,14 @@ """Contains the main entrypoint for the web application.""" import logging.config +import os +from datetime import datetime import gradio as gr import hydra import omegaconf -import web_app + +from web_app.backend import (context_retriever, llm_proxy) +from web_app import gui def _logger() -> logging.Logger: @@ -14,9 +18,10 @@ def _logger() -> logging.Logger: with hydra.initialize(version_base=None, config_path='cfg'): cfg = hydra.compose(config_name='main') - _logger().info('Starting web application with configuration: %s', + _logger().info('Starting web application with configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) +os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) logging.config.dictConfig({ 'version': 1, @@ -41,8 +46,12 @@ def _logger() -> logging.Logger: } }) -backend_service = web_app.backend_communication.BackendService( - backend_url=cfg.backend_entrypoint_url +context_retriever_service = context_retriever.ContextRetrieverService( + cfg.context_retriever_url +) + +llm_proxy_service = llm_proxy.LLMProxyService( + cfg.llm_proxy_url ) CUSTOM_CSS = """ @@ -53,7 +62,7 @@ def _logger() -> logging.Logger: """ with gr.Blocks(fill_height=True, title='AGH Chat', css=CUSTOM_CSS) as web_application: - web_app.gui.MainController(backend_service).render_gui() + gui.MainController(context_retriever_service, llm_proxy_service).render_gui() web_application.launch(server_name=cfg.web_app_host, server_port=cfg.web_app_port) diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index 76812cd..a790324 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -19,30 +19,23 @@ app = FastAPI() +@app.get('/ping') +async def read_ping() -> Dict[str, str]: + """Health check endpoint.""" + return {'message': 'Service is running'} + + class RequestCollectContextInfo(pydantic.BaseModel): - """Request coming from the web app to collect context information.""" + """Request from web-app to context-retriever to collect context documents.""" user_message: str chat_history: List[Dict[str, str]] class ResponseCollectContextInfo(pydantic.BaseModel): - """Response sent back to the web app with collected context information.""" - context_docs: List[Tuple[str, str]] - - -class RequestStreamChatResponse(pydantic.BaseModel): - """Request coming from the web app after collecting the context to stream chat responses.""" - user_message: str - chat_history: List[Dict[str, str]] + """Response from context-retriever to web-app with collected context docs.""" context_docs: List[Tuple[str, str]] -@app.get('/ping') -async def read_ping() -> Dict[str, str]: - """Health check endpoint.""" - return {'message': 'Service is running'} - - @app.post('/collect_context_info') async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: """Collects context information from database for a given query.""" @@ -55,7 +48,14 @@ async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCo ('doc3', 'This is the content of document 3.'), ] - return ResponseCollectContextInfo(context_docs=mock_docs) + return ResponseCollectContextInfo(context_docs=random.sample(mock_docs, 2)) + + +class RequestStreamChatResponse(pydantic.BaseModel): + """Request from web-app to llm-proxy to stream chat responses.""" + user_message: str + chat_history: List[Dict[str, str]] + context_docs: List[Tuple[str, str]] @app.post('/stream_chat_response') @@ -87,7 +87,7 @@ async def event_generator() -> AsyncIterator[bytes]: def main(cfg: omegaconf.DictConfig) -> None: """Sets up the mock backend service.""" - logging.info('Starting mock backend with configuration: %s', + logging.info('Starting mock backend with configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) uvicorn.run( diff --git a/services/web-app/src/web_app/__init__.py b/services/web-app/src/web_app/__init__.py index 42571ab..7a7ff41 100644 --- a/services/web-app/src/web_app/__init__.py +++ b/services/web-app/src/web_app/__init__.py @@ -1,3 +1,3 @@ """Package init file.""" -from . import backend_communication +from . import backend from . import gui diff --git a/services/web-app/src/web_app/backend/__init__.py b/services/web-app/src/web_app/backend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py new file mode 100644 index 0000000..34c14d3 --- /dev/null +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -0,0 +1,56 @@ +"""Contains implementation of service that communicates with the context retriever module.""" + +import logging +from typing import Any +from typing import Dict +from typing import List +from typing import Tuple +import requests + +from web_app.backend import utils + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class ContextRetrieverService: + """Communicates with the context-retriever module and retrieves context for queries.""" + + def __init__(self, context_retriever_url: str): + + self._context_retriever_url = context_retriever_url + + def collect_context_info(self, + user_message: str, + chat_history: List[Dict[str, Any]]) -> List[Tuple[str, str]]: + """Collects context information based on the user's message and chat history. + + Args: + user_message: The message from the user to collect context information for. + chat_history: The history of the chat to provide context for the request. + + Raises: + requests.HTTPError: If the request to the backend fails. + + Returns: + A list of tuples where each tuple contains a document title and its content. + """ + + _logger().debug('Collecting context info with user_message: %s and chat_history: %s', + user_message, chat_history) + + chat_history = utils.sanitize_chat_history(chat_history) + + url = f"{self._context_retriever_url}/collect_context_info" + payload = { + 'user_message': user_message, + 'chat_history': chat_history + } + + response = requests.post(url, json=payload, timeout=5) + response.raise_for_status() + + response_data = response.json() + + return list((title, content) for title, content in response_data['context_docs']) diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py new file mode 100644 index 0000000..b3b8acb --- /dev/null +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -0,0 +1,56 @@ +"""Contains service that communicates with the llm-proxy module.""" + +from typing import Tuple +from typing import Dict +from typing import List +from typing import Iterator +import logging +import httpx +import json + +from web_app.backend import utils + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class LLMProxyService: + """Communicates with the llm-proxy module and returns model's responses.""" + + def __init__(self, llm_proxy_url: str): + + self._llm_proxy_url = llm_proxy_url + + def stream_chat_response(self, + user_message: str, + chat_history: utils.ChatHistoryType, + context_docs: List[Tuple[str, str]]) -> Iterator[Dict[str, str]]: + """Collects LLM response based on the context and streams it. + + Args: + user_message: The message from the user to generate a response for. + chat_history: The history of the chat to provide context for the request. + context_docs: The documents retrieved to provide additional context. + + Returns: + A generator that yields chunks of the chat response as they are received. + """ + + _logger().debug(('Streaming chat response with user_message: %s, ' + + 'chat_history: %s, context_docs: %s'), + user_message, chat_history, context_docs) + + chat_history = utils.sanitize_chat_history(chat_history) + + url = f"{self._llm_proxy_url}/stream_chat_response" + + payload = { + 'user_message': user_message, + 'chat_history': chat_history, + 'context_docs': context_docs + } + + with httpx.stream('POST', url, json=payload, timeout=5) as stream: + for chunk in stream.iter_bytes(): + yield json.loads(chunk.decode('utf-8')) diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py new file mode 100644 index 0000000..cad3534 --- /dev/null +++ b/services/web-app/src/web_app/backend/utils.py @@ -0,0 +1,18 @@ +"""Contains utilities used by the backend services.""" + +from typing import TypeAlias +from typing import Dict +from typing import List + +ChatHistoryType: TypeAlias = List[Dict[str, str]] + + +def sanitize_chat_history(chat_history: ChatHistoryType) -> ChatHistoryType: + """Sanitizes the chat history to ensure it contains only relevant fields.""" + return [ + { + 'role': item['role'], + 'content': item['content'] + } + for item in chat_history + ] diff --git a/services/web-app/src/web_app/backend_communication.py b/services/web-app/src/web_app/backend_communication.py deleted file mode 100644 index ef67a47..0000000 --- a/services/web-app/src/web_app/backend_communication.py +++ /dev/null @@ -1,104 +0,0 @@ -"""Contains functions to communicate with the entrypoint backend service.""" -import json -import logging -from typing import Any -from typing import Dict -from typing import Iterator -from typing import List -from typing import Tuple -from typing import TypeAlias - -import httpx -import requests - -ChatHistoryType: TypeAlias = List[Dict[str, str]] - - -def _logger() -> logging.Logger: - return logging.getLogger('web_app') - - -def _sanitize_chat_history(chat_history: ChatHistoryType) -> ChatHistoryType: - """Sanitizes the chat history to ensure it contains only relevant fields.""" - return [ - { - 'role': item['role'], - 'content': item['content'] - } - for item in chat_history - ] - - -class BackendService: - """Communicates with the entrypoint-backend.""" - - def __init__(self, backend_url: str): - - self._backend_url = backend_url - - def collect_context_info(self, - user_message: str, - chat_history: List[Dict[str, Any]]) -> List[Tuple[str, str]]: - """Collects context information based on the user's message and chat history. - - Args: - user_message: The message from the user to collect context information for. - chat_history: The history of the chat to provide context for the request. - - Raises: - requests.HTTPError: If the request to the backend fails. - - Returns: - A list of tuples where each tuple contains a document title and its content. - """ - - _logger().debug('Collecting context info with user_message: %s and chat_history: %s', - user_message, chat_history) - - chat_history = _sanitize_chat_history(chat_history) - - url = f"{self._backend_url}/collect_context_info" - payload = { - 'user_message': user_message, - 'chat_history': chat_history - } - - response = requests.post(url, json=payload, timeout=5) - response.raise_for_status() - - response_data = response.json() - - return list((title, content) for title, content in response_data['context_docs']) - - def stream_chat_response(self, - user_message: str, - chat_history: ChatHistoryType, - context_docs: List[Tuple[str, str]]) -> Iterator[Dict[str, str]]: - """Collects LLM response based on the context and streams it. - - Args: - user_message: The message from the user to generate a response for. - chat_history: The history of the chat to provide context for the request. - context_docs: The documents retrieved to provide additional context. - - Returns: - A generator that yields chunks of the chat response as they are received. - """ - - _logger().debug(('Streaming chat response with user_message: %s, ' + - 'chat_history: %s, context_docs: %s'), - user_message, chat_history, context_docs) - - chat_history = _sanitize_chat_history(chat_history) - - url = f"{self._backend_url}/stream_chat_response" - - payload = { - 'user_message': user_message, - 'chat_history': chat_history, - 'context_docs': context_docs - } - - with httpx.stream('POST', url, json=payload, timeout=5) as stream: - for chunk in stream.iter_bytes(): - yield json.loads(chunk.decode('utf-8')) diff --git a/services/web-app/src/web_app/gui.py b/services/web-app/src/web_app/gui.py index 18291c3..b79f537 100644 --- a/services/web-app/src/web_app/gui.py +++ b/services/web-app/src/web_app/gui.py @@ -5,8 +5,9 @@ from typing import Tuple import gradio as gr -import web_app -from web_app.backend_communication import ChatHistoryType + +from web_app.backend.utils import ChatHistoryType +from web_app.backend import (context_retriever, llm_proxy) def _logger() -> logging.Logger: @@ -31,9 +32,11 @@ class MainController: """Renders GUI elements and handles controller-view interactions.""" def __init__(self, - backend_service: web_app.backend_communication.BackendService): + context_retriever_service: context_retriever.ContextRetrieverService, + llm_proxy_service: llm_proxy.LLMProxyService): - self._backend_service = backend_service + self._context_retriever_service = context_retriever_service + self._llm_proxy_service = llm_proxy_service def render_gui(self) -> None: """Renders the UI for application and assigns the necessary callbacks.""" @@ -83,7 +86,7 @@ def _chat_interface_callback(self, history = history or [] try: - context_docs = self._backend_service.collect_context_info( + context_docs = self._context_retriever_service.collect_context_info( user_message=user_message, chat_history=history ) @@ -93,7 +96,7 @@ def _chat_interface_callback(self, context_docs_repr = _create_retrieved_docs_representation(context_docs) - chat_response = self._backend_service.stream_chat_response( + chat_response = self._llm_proxy_service.stream_chat_response( user_message=user_message, chat_history=history, context_docs=context_docs @@ -102,8 +105,7 @@ def _chat_interface_callback(self, full_text_response = '' for chunk in chat_response: - token = chunk.get('content', '') - full_text_response += token + full_text_response += chunk['content'] chat_message = [{ 'role': 'assistant', From 86e229f9a7955fbf4406734734e6bc76bc5cce7f Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 14 Dec 2025 10:45:30 +0000 Subject: [PATCH 013/108] Enhance readability of the code Added type aliases and dataclasses for chat history and docs Split chat interface callback into subfunctions Updated docstrings --- services/web-app/main_dev.py | 5 +- services/web-app/mock_backend.py | 17 ++-- .../src/web_app/backend/context_retriever.py | 12 +-- .../web-app/src/web_app/backend/llm_proxy.py | 13 ++- services/web-app/src/web_app/backend/utils.py | 52 ++++++++-- services/web-app/src/web_app/gui.py | 94 ++++++++++++++----- 6 files changed, 136 insertions(+), 57 deletions(-) diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 76a6594..9d852a7 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -1,7 +1,6 @@ """Contains the main entrypoint for the web application.""" import logging.config import os -from datetime import datetime import gradio as gr import hydra @@ -35,7 +34,7 @@ def _logger() -> logging.Logger: 'handlers': { 'console': { 'class': 'logging.StreamHandler', - 'level': 'INFO', + 'level': 'DEBUG', 'formatter': 'default' } }, @@ -56,7 +55,7 @@ def _logger() -> logging.Logger: CUSTOM_CSS = """ .retrieved-docs { - max-height: 30vh; + max-height: 50vh; overflow-y: auto; } """ diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index a790324..3946ca8 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -7,6 +7,7 @@ from typing import Dict from typing import List from typing import Tuple +from typing import Any import hydra import omegaconf @@ -28,12 +29,12 @@ async def read_ping() -> Dict[str, str]: class RequestCollectContextInfo(pydantic.BaseModel): """Request from web-app to context-retriever to collect context documents.""" user_message: str - chat_history: List[Dict[str, str]] + chat_history: List[Dict[str, Any]] class ResponseCollectContextInfo(pydantic.BaseModel): """Response from context-retriever to web-app with collected context docs.""" - context_docs: List[Tuple[str, str]] + context_docs: List[Dict[str, Any]] @app.post('/collect_context_info') @@ -43,9 +44,9 @@ async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCo logging.info('/collect_context_info - Message: %s', request.user_message) mock_docs = [ - ('doc1', 'This is the content of document 1.'), - ('doc2', 'This is the content of document 2.'), - ('doc3', 'This is the content of document 3.'), + {'title': 'doc1', 'content': 'This is the content of document 1.'}, + {'title': 'doc2', 'content': 'This is the content of document 2.'}, + {'title': 'doc3', 'content': 'This is the content of document 3.'}, ] return ResponseCollectContextInfo(context_docs=random.sample(mock_docs, 2)) @@ -54,8 +55,8 @@ async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCo class RequestStreamChatResponse(pydantic.BaseModel): """Request from web-app to llm-proxy to stream chat responses.""" user_message: str - chat_history: List[Dict[str, str]] - context_docs: List[Tuple[str, str]] + chat_history: List[Dict[str, Any]] + context_docs: List[Dict[str, Any]] @app.post('/stream_chat_response') @@ -72,7 +73,7 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR mock_words = mock_response.split() response = ' '.join(random.sample(mock_words, len(mock_words))) - response += f'Documents used: {[doc_id for doc_id, _ in request.context_docs]}' + response += f'Documents used: {[doc['title'] for doc in request.context_docs]}' async def event_generator() -> AsyncIterator[bytes]: for token in response.replace(' ', ' [split_token]') .split('[split_token]'): diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index 34c14d3..e017171 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -23,7 +23,7 @@ def __init__(self, context_retriever_url: str): def collect_context_info(self, user_message: str, - chat_history: List[Dict[str, Any]]) -> List[Tuple[str, str]]: + chat_history: utils.ChatHistory) -> List[utils.ContextDocument]: """Collects context information based on the user's message and chat history. Args: @@ -32,20 +32,15 @@ def collect_context_info(self, Raises: requests.HTTPError: If the request to the backend fails. - - Returns: - A list of tuples where each tuple contains a document title and its content. """ _logger().debug('Collecting context info with user_message: %s and chat_history: %s', user_message, chat_history) - chat_history = utils.sanitize_chat_history(chat_history) - url = f"{self._context_retriever_url}/collect_context_info" payload = { 'user_message': user_message, - 'chat_history': chat_history + 'chat_history': utils.chat_history_to_payload(chat_history) } response = requests.post(url, json=payload, timeout=5) @@ -53,4 +48,5 @@ def collect_context_info(self, response_data = response.json() - return list((title, content) for title, content in response_data['context_docs']) + return [utils.ContextDocument(doc['title'], doc['content']) + for doc in response_data['context_docs']] diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index b3b8acb..b763aac 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -24,8 +24,8 @@ def __init__(self, llm_proxy_url: str): def stream_chat_response(self, user_message: str, - chat_history: utils.ChatHistoryType, - context_docs: List[Tuple[str, str]]) -> Iterator[Dict[str, str]]: + chat_history: utils.ChatHistory, + context_docs: List[utils.ContextDocument]) -> Iterator[Dict[str, str]]: """Collects LLM response based on the context and streams it. Args: @@ -34,21 +34,20 @@ def stream_chat_response(self, context_docs: The documents retrieved to provide additional context. Returns: - A generator that yields chunks of the chat response as they are received. + A generator that yields chunks of the chat response as they are received. Each chunk + contain the 'content' field. """ _logger().debug(('Streaming chat response with user_message: %s, ' + 'chat_history: %s, context_docs: %s'), user_message, chat_history, context_docs) - chat_history = utils.sanitize_chat_history(chat_history) - url = f"{self._llm_proxy_url}/stream_chat_response" payload = { 'user_message': user_message, - 'chat_history': chat_history, - 'context_docs': context_docs + 'chat_history': utils.chat_history_to_payload(chat_history), + 'context_docs': utils.context_docs_to_payload(context_docs) } with httpx.stream('POST', url, json=payload, timeout=5) as stream: diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index cad3534..9babaa4 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -3,16 +3,56 @@ from typing import TypeAlias from typing import Dict from typing import List +from typing import Any +import dataclasses -ChatHistoryType: TypeAlias = List[Dict[str, str]] +@dataclasses.dataclass +class ChatMessage: + """Represents a single chat message.""" + + role: str + content: str + + +@dataclasses.dataclass +class ChatHistory: + """Contains history of messages in a chat session.""" + + messages: List[ChatMessage] + + +@dataclasses.dataclass +class ContextDocument: + """Represents a single document retrieved from the doc store.""" + + title: str + content: str + + +UnstructuredChatHistory: TypeAlias = List[Dict[str, Any]] + +UnstructuredContextDocs: TypeAlias = List[Dict[str, Any]] + + +def chat_history_to_payload(chat_history: ChatHistory) -> UnstructuredChatHistory: + """Converts chat history into json representation containing only core fields.""" + return [ + { + 'role': message.role, + 'content': message.content + } + for message in chat_history.messages + ] + + +def context_docs_to_payload(context_docs: List[ContextDocument]) -> UnstructuredContextDocs: + """Converts context docs into json representation.""" -def sanitize_chat_history(chat_history: ChatHistoryType) -> ChatHistoryType: - """Sanitizes the chat history to ensure it contains only relevant fields.""" return [ { - 'role': item['role'], - 'content': item['content'] + 'title': doc.title, + 'content': doc.content } - for item in chat_history + for doc in context_docs ] diff --git a/services/web-app/src/web_app/gui.py b/services/web-app/src/web_app/gui.py index b79f537..1c79c18 100644 --- a/services/web-app/src/web_app/gui.py +++ b/services/web-app/src/web_app/gui.py @@ -3,33 +3,34 @@ from typing import Iterator from typing import List from typing import Tuple +from typing import Optional +from typing import Dict +from typing import Any import gradio as gr -from web_app.backend.utils import ChatHistoryType +from web_app.backend import utils from web_app.backend import (context_retriever, llm_proxy) def _logger() -> logging.Logger: - return logging.getLogger('web_app') + return logging.getLogger(__name__) -def _create_retrieved_docs_representation(docs: List[Tuple[str, str]]) -> gr.Markdown: - """Concatenates the retrieved documents and returns their Markdown representation.""" +class MainController: + """Renders GUI elements and handles controller-view interactions.""" - content = '\n'.join( - f""" - ### {title} - {content} - """ - for title, content in docs - ) + _DOC_MD_TEMPLATE = """ +### {title} - return gr.Markdown(content) +{content} +""" + _DOCS_LIST_MD_TEMPLATE = """ +## Round {round_nr} -class MainController: - """Renders GUI elements and handles controller-view interactions.""" +{docs} +""" def __init__(self, context_retriever_service: context_retriever.ContextRetrieverService, @@ -38,6 +39,8 @@ def __init__(self, self._context_retriever_service = context_retriever_service self._llm_proxy_service = llm_proxy_service + self._documents_retrieval_history: List[List[utils.ContextDocument]] = [] + def render_gui(self) -> None: """Renders the UI for application and assigns the necessary callbacks.""" @@ -60,7 +63,7 @@ def render_gui(self) -> None: variant='panel', elem_classes='retrieved-docs'): - docs_list = gr.Markdown('Retrieved documents will be displayed here.',) + docs_list = gr.Markdown('Retrieved documents will be displayed here.') with gr.Column(elem_id='chat_column', scale=3): @@ -79,26 +82,50 @@ def render_gui(self) -> None: def _chat_interface_callback(self, user_message: str, - history: ChatHistoryType - ) -> Iterator[Tuple[ChatHistoryType, gr.Markdown]]: - """Main callback for the chat interface.""" + raw_history: Optional[utils.UnstructuredChatHistory], + ) -> Iterator[Tuple[Dict[str, Any], gr.Markdown]]: + """Main callback for the chat interface. - history = history or [] + It first retrieves context docs from the context-retriever, updates the internal documents + storage and streams the llm-proxy response together with the markdown representation + of the retrieval history. + """ + + raw_history = raw_history or [] + + chat_history = utils.ChatHistory( + [utils.ChatMessage(message['role'], message['content']) + for message in raw_history] + ) try: context_docs = self._context_retriever_service.collect_context_info( user_message=user_message, - chat_history=history + chat_history=chat_history ) + + self._documents_retrieval_history.append(context_docs) + except Exception as e: _logger().error('Failed to collect context info from backend.') raise gr.Error('Failed to collect context info from backend.', duration=5) from e - context_docs_repr = _create_retrieved_docs_representation(context_docs) + context_docs_repr = self._create_retrieved_docs_representation() + + for chat_message in self._stream_llm_response(user_message, + chat_history, + context_docs): + yield chat_message, context_docs_repr + + def _stream_llm_response(self, + user_message: str, + chat_history=utils.ChatHistory, + context_docs=List[utils.ContextDocument]) -> Iterator[Dict[str, Any]]: + """Yields concatenated chunks retrieved from the llm.""" chat_response = self._llm_proxy_service.stream_chat_response( user_message=user_message, - chat_history=history, + chat_history=chat_history, context_docs=context_docs ) @@ -107,9 +134,26 @@ def _chat_interface_callback(self, full_text_response += chunk['content'] - chat_message = [{ + yield { 'role': 'assistant', 'content': full_text_response - }] + } - yield chat_message, context_docs_repr + def _create_retrieved_docs_representation(self) -> gr.Markdown: + """Concatenates the documents retrieved till now and returns their Markdown repr.""" + + retrieval_history_reprs: List[str] = [] + + for docs in self._documents_retrieval_history: + + docs_repr = (self._DOC_MD_TEMPLATE.format(title=doc.title, + content=doc.content) + for doc in docs) + + retrieval_history_reprs.append('\n\n'.join(docs_repr)) + + docs_list_repr = (self._DOCS_LIST_MD_TEMPLATE.format(round_nr=i + 1, + docs=repr) + for i, repr in enumerate(retrieval_history_reprs)) + + return gr.Markdown('\n---\n'.join(docs_list_repr)) From 4b866092027b33aed7605d1d117d196d16bb96fe Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 14 Dec 2025 10:46:49 +0000 Subject: [PATCH 014/108] Rename hydra configuration for the main_dev script --- services/web-app/cfg/{main.yaml => main_dev.yaml} | 1 - services/web-app/main_dev.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) rename services/web-app/cfg/{main.yaml => main_dev.yaml} (83%) diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main_dev.yaml similarity index 83% rename from services/web-app/cfg/main.yaml rename to services/web-app/cfg/main_dev.yaml index 875c23d..f3d235e 100644 --- a/services/web-app/cfg/main.yaml +++ b/services/web-app/cfg/main_dev.yaml @@ -1,6 +1,5 @@ --- context_retriever_url: http://localhost:8888 llm_proxy_url: http://localhost:8888 -persist_data_path: data/ web_app_port: 8080 web_app_host: localhost diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 9d852a7..5421f70 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -15,7 +15,7 @@ def _logger() -> logging.Logger: with hydra.initialize(version_base=None, config_path='cfg'): - cfg = hydra.compose(config_name='main') + cfg = hydra.compose(config_name='main_dev') _logger().info('Starting web application with configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) From 27671b37f99ce69ffa49c0532c2642317df96666 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 14 Dec 2025 11:38:43 +0000 Subject: [PATCH 015/108] Create separate package for front end modules --- services/web-app/main_dev.py | 15 +++------------ services/web-app/src/web_app/gui/__init__.py | 0 .../web_app/{gui.py => gui/main_controller.py} | 0 services/web-app/src/web_app/gui/utils.py | 8 ++++++++ 4 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 services/web-app/src/web_app/gui/__init__.py rename services/web-app/src/web_app/{gui.py => gui/main_controller.py} (100%) create mode 100644 services/web-app/src/web_app/gui/utils.py diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 5421f70..bbb9a63 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -7,7 +7,7 @@ import omegaconf from web_app.backend import (context_retriever, llm_proxy) -from web_app import gui +from web_app.gui import (main_controller, utils as gui_utils) def _logger() -> logging.Logger: @@ -20,8 +20,6 @@ def _logger() -> logging.Logger: _logger().info('Starting web application with configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) -os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) - logging.config.dictConfig({ 'version': 1, 'loggers': { @@ -53,15 +51,8 @@ def _logger() -> logging.Logger: cfg.llm_proxy_url ) -CUSTOM_CSS = """ -.retrieved-docs { - max-height: 50vh; - overflow-y: auto; -} -""" - -with gr.Blocks(fill_height=True, title='AGH Chat', css=CUSTOM_CSS) as web_application: - gui.MainController(context_retriever_service, llm_proxy_service).render_gui() +with gr.Blocks(fill_height=True, title='AGH Chat', css=gui_utils.CUSTOM_CSS) as web_application: + main_controller.MainController(context_retriever_service, llm_proxy_service).render_gui() web_application.launch(server_name=cfg.web_app_host, server_port=cfg.web_app_port) diff --git a/services/web-app/src/web_app/gui/__init__.py b/services/web-app/src/web_app/gui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/web-app/src/web_app/gui.py b/services/web-app/src/web_app/gui/main_controller.py similarity index 100% rename from services/web-app/src/web_app/gui.py rename to services/web-app/src/web_app/gui/main_controller.py diff --git a/services/web-app/src/web_app/gui/utils.py b/services/web-app/src/web_app/gui/utils.py new file mode 100644 index 0000000..a34c819 --- /dev/null +++ b/services/web-app/src/web_app/gui/utils.py @@ -0,0 +1,8 @@ +"""Contains utilities for application frontend.""" + +CUSTOM_CSS = """ +.retrieved-docs { + max-height: 50vh; + overflow-y: auto; +} +""" From dae1a99b229dd99f94e1617dc0ab89aa1bb1ce73 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 14 Dec 2025 12:03:51 +0000 Subject: [PATCH 016/108] Add main application entrypoint --- services/web-app/cfg/main.yaml | 6 ++ services/web-app/justfile | 6 +- services/web-app/main.py | 91 +++++++++++++++++++ .../src/web_app/backend/context_retriever.py | 3 + .../web-app/src/web_app/backend/llm_proxy.py | 3 + 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 services/web-app/cfg/main.yaml create mode 100644 services/web-app/main.py diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml new file mode 100644 index 0000000..5f614d2 --- /dev/null +++ b/services/web-app/cfg/main.yaml @@ -0,0 +1,6 @@ +--- +context_retriever_url: http://context_retriever:8080 +llm_proxy_url: http://llm_proxy:8080 +persist_data_path: data/ +web_app_port: 8080 +web_app_host: localhost diff --git a/services/web-app/justfile b/services/web-app/justfile index 3173801..fdf4671 100644 --- a/services/web-app/justfile +++ b/services/web-app/justfile @@ -12,9 +12,13 @@ setup-environment: uv pip install -e .[dev] # Run the Gradio web application with live reloading. -run-app: +run-app-dev: uv run gradio main_dev.py --watch-dirs . --demo-name web_application +# Run the web application. +run-app: + uv run python main.py + # Run the mock backend server. run-mock-backend: uv run python mock_backend.py diff --git a/services/web-app/main.py b/services/web-app/main.py new file mode 100644 index 0000000..ce8e324 --- /dev/null +++ b/services/web-app/main.py @@ -0,0 +1,91 @@ +"""Contains the main entrypoint for the web application.""" +import logging.config +import os +from datetime import datetime + +import gradio as gr +import hydra +import omegaconf + +from web_app.backend import (context_retriever, llm_proxy) +from web_app.gui import (main_controller, utils as gui_utils) + + +def _logger() -> logging.Logger: + return logging.getLogger() + + +@hydra.main(version_base=None, config_path='cfg', config_name='main') +def main(cfg: omegaconf.DictConfig): + """Initializes and serves the web app.""" + + os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) + + logging.config.dictConfig({ + 'version': 1, + 'loggers': { + 'root': { + 'level': 'NOTSET', + 'handlers': ['console', 'file'], + 'propagate': True + }, + 'httpx': { + 'level': 'WARNING', + 'propagate': False + }, + 'httpcore': { + 'level': 'WARNING', + 'propagate': False + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'level': 'INFO', + 'formatter': 'default' + }, + 'file': { + "class": "logging.handlers.RotatingFileHandler", + "level": "DEBUG", + "formatter": "default", + "filename": os.path.join(cfg.persist_data_path, + 'log', + f'{datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}.log'), + "maxBytes": 5_000_000, + "backupCount": 5, + "encoding": "utf-8", + } + }, + 'formatters': { + 'default': { + 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + } + } + }) + + _logger().info('Starting web application with configuration:\n%s', + omegaconf.OmegaConf.to_yaml(cfg)) + + _logger().info('Creating services for backend communication...') + + context_retriever_service = context_retriever.ContextRetrieverService( + cfg.context_retriever_url + ) + + llm_proxy_service = llm_proxy.LLMProxyService( + cfg.llm_proxy_url + ) + + _logger().info('Rendering GUI...') + + with gr.Blocks(fill_height=True, + title='AGH Chat', + css=gui_utils.CUSTOM_CSS) as web_application: + main_controller.MainController(context_retriever_service, llm_proxy_service).render_gui() + + web_application.launch(server_name=cfg.web_app_host, + server_port=cfg.web_app_port) + + +if __name__ == '__main__': + main() # pylint: disable=no-value-for-parameter diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index e017171..b2b8b78 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -21,6 +21,9 @@ def __init__(self, context_retriever_url: str): self._context_retriever_url = context_retriever_url + _logger().debug('Created service for context-retriever with url: %s', + context_retriever_url) + def collect_context_info(self, user_message: str, chat_history: utils.ChatHistory) -> List[utils.ContextDocument]: diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index b763aac..904d4ba 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -22,6 +22,9 @@ def __init__(self, llm_proxy_url: str): self._llm_proxy_url = llm_proxy_url + _logger().debug('Created service for llm-proxy with url: %s', + llm_proxy_url) + def stream_chat_response(self, user_message: str, chat_history: utils.ChatHistory, From fa79da1441df8a771563616397555c844f1c2f00 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 14 Dec 2025 12:09:05 +0000 Subject: [PATCH 017/108] Run pre-commit --- services/web-app/main.py | 23 ++++++++++--------- services/web-app/main_dev.py | 8 +++---- services/web-app/mock_backend.py | 3 +-- .../src/web_app/backend/context_retriever.py | 6 +---- .../web-app/src/web_app/backend/llm_proxy.py | 10 ++++---- services/web-app/src/web_app/backend/utils.py | 7 +++--- .../src/web_app/gui/main_controller.py | 14 +++++------ 7 files changed, 32 insertions(+), 39 deletions(-) diff --git a/services/web-app/main.py b/services/web-app/main.py index ce8e324..1101c92 100644 --- a/services/web-app/main.py +++ b/services/web-app/main.py @@ -6,9 +6,10 @@ import gradio as gr import hydra import omegaconf - -from web_app.backend import (context_retriever, llm_proxy) -from web_app.gui import (main_controller, utils as gui_utils) +from web_app.backend import context_retriever +from web_app.backend import llm_proxy +from web_app.gui import main_controller +from web_app.gui import utils as gui_utils def _logger() -> logging.Logger: @@ -16,7 +17,7 @@ def _logger() -> logging.Logger: @hydra.main(version_base=None, config_path='cfg', config_name='main') -def main(cfg: omegaconf.DictConfig): +def main(cfg: omegaconf.DictConfig) -> None: """Initializes and serves the web app.""" os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) @@ -45,15 +46,15 @@ def main(cfg: omegaconf.DictConfig): 'formatter': 'default' }, 'file': { - "class": "logging.handlers.RotatingFileHandler", - "level": "DEBUG", - "formatter": "default", - "filename": os.path.join(cfg.persist_data_path, + 'class': 'logging.handlers.RotatingFileHandler', + 'level': 'DEBUG', + 'formatter': 'default', + 'filename': os.path.join(cfg.persist_data_path, 'log', f'{datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}.log'), - "maxBytes": 5_000_000, - "backupCount": 5, - "encoding": "utf-8", + 'maxBytes': 5_000_000, + 'backupCount': 5, + 'encoding': 'utf-8', } }, 'formatters': { diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index bbb9a63..4eb8110 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -1,13 +1,13 @@ """Contains the main entrypoint for the web application.""" import logging.config -import os import gradio as gr import hydra import omegaconf - -from web_app.backend import (context_retriever, llm_proxy) -from web_app.gui import (main_controller, utils as gui_utils) +from web_app.backend import context_retriever +from web_app.backend import llm_proxy +from web_app.gui import main_controller +from web_app.gui import utils as gui_utils def _logger() -> logging.Logger: diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index 3946ca8..8f57410 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -3,11 +3,10 @@ import json import logging import random +from typing import Any from typing import AsyncIterator from typing import Dict from typing import List -from typing import Tuple -from typing import Any import hydra import omegaconf diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index b2b8b78..4c6b9cb 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -1,12 +1,8 @@ """Contains implementation of service that communicates with the context retriever module.""" - import logging -from typing import Any -from typing import Dict from typing import List -from typing import Tuple -import requests +import requests from web_app.backend import utils diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index 904d4ba..cda94df 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -1,13 +1,11 @@ """Contains service that communicates with the llm-proxy module.""" - -from typing import Tuple +import json +import logging from typing import Dict -from typing import List from typing import Iterator -import logging -import httpx -import json +from typing import List +import httpx from web_app.backend import utils diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index 9babaa4..85294ad 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -1,10 +1,9 @@ """Contains utilities used by the backend services.""" - -from typing import TypeAlias +import dataclasses +from typing import Any from typing import Dict from typing import List -from typing import Any -import dataclasses +from typing import TypeAlias @dataclasses.dataclass diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 1c79c18..a455abb 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -1,16 +1,16 @@ """Contains GUI related utils.""" import logging +from typing import Any +from typing import Dict from typing import Iterator from typing import List -from typing import Tuple from typing import Optional -from typing import Dict -from typing import Any +from typing import Tuple import gradio as gr - +from web_app.backend import context_retriever +from web_app.backend import llm_proxy from web_app.backend import utils -from web_app.backend import (context_retriever, llm_proxy) def _logger() -> logging.Logger: @@ -119,8 +119,8 @@ def _chat_interface_callback(self, def _stream_llm_response(self, user_message: str, - chat_history=utils.ChatHistory, - context_docs=List[utils.ContextDocument]) -> Iterator[Dict[str, Any]]: + chat_history: utils.ChatHistory, + context_docs: List[utils.ContextDocument]) -> Iterator[Dict[str, Any]]: """Yields concatenated chunks retrieved from the llm.""" chat_response = self._llm_proxy_service.stream_chat_response( From 6aa2685f5a104afcaf4c1fdf82359ad0abdea104 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 01:54:42 +0000 Subject: [PATCH 018/108] Introduce llm-generator service and add it to the docker compose config --- .gitignore | 2 +- docker-compose.yml | 29 ++++++++----------- persist_dir/llm-generator/.gitignore | 2 ++ services/llm-generator/entrypoint.sh | 12 ++++++++ .../llm-generator/llm-generator.Dockerfile | 12 ++++++++ 5 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 persist_dir/llm-generator/.gitignore create mode 100644 services/llm-generator/entrypoint.sh create mode 100644 services/llm-generator/llm-generator.Dockerfile diff --git a/.gitignore b/.gitignore index bcbf3a7..7313dff 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ **/__pycache__/ persistent_data/ .venv/ -.mypy_cache/ +.mypy_cache/ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index f474576..0efe6dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,27 +2,22 @@ version: '3.9' services: - core-service: + llm-generator: build: - context: . - dockerfile: services/core-service/Dockerfile - container_name: core-service + context: services/llm-generator/ + dockerfile: llm-generator.Dockerfile + args: + - gpus=all + container_name: llm-generator ports: - - 8001:8000 - networks: - - rag-net - - api-gateway: - build: - context: . - dockerfile: services/api-gateway/Dockerfile - container_name: api-gateway - ports: - - 8080:8000 - depends_on: - - core-service + - 11434:11434 + volumes: + - ./persist_dir/llm-generator:/root/.ollama networks: - rag-net + environment: + - LLM_GENERATOR_MODEL=llama3.2:1b + networks: rag-net: diff --git a/persist_dir/llm-generator/.gitignore b/persist_dir/llm-generator/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/llm-generator/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/services/llm-generator/entrypoint.sh b/services/llm-generator/entrypoint.sh new file mode 100644 index 0000000..580f5d1 --- /dev/null +++ b/services/llm-generator/entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +ollama serve & +SERVER_PID=$! + +echo "Waiting for ollama server to start..." +sleep 5 + +echo "Pulling the model..." +ollama pull "${LLM_GENERATOR_MODEL}" + +wait $SERVER_PID \ No newline at end of file diff --git a/services/llm-generator/llm-generator.Dockerfile b/services/llm-generator/llm-generator.Dockerfile new file mode 100644 index 0000000..d981930 --- /dev/null +++ b/services/llm-generator/llm-generator.Dockerfile @@ -0,0 +1,12 @@ +FROM ollama/ollama:latest + +ENV OLLAMA_HOST="0.0.0.0:11434" + +COPY ./entrypoint.sh /root/entrypoint.sh +RUN chmod +x /root/entrypoint.sh + +WORKDIR /root + +EXPOSE 11434 + +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file From b41ff0e5a076d5f2ec3f3850b419a8e388027011 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 01:55:00 +0000 Subject: [PATCH 019/108] Add Devcontainer for llm-proxy --- .devcontainer/llm-proxy/Dockerfile | 21 ++++++++++++++ .devcontainer/llm-proxy/devcontainer.json | 35 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .devcontainer/llm-proxy/Dockerfile create mode 100644 .devcontainer/llm-proxy/devcontainer.json diff --git a/.devcontainer/llm-proxy/Dockerfile b/.devcontainer/llm-proxy/Dockerfile new file mode 100644 index 0000000..75e0cd6 --- /dev/null +++ b/.devcontainer/llm-proxy/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl wget git openssh-client sudo \ + just gcc g++ + +RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash +RUN chown -R appuser:appuser /home/appuser/ + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN chmod +x /tmp/base-setup.sh \ + && USERNAME="appuser" /tmp/base-setup.sh + +USER appuser +WORKDIR /home/appuser/workspace + +RUN wget -qO- https://astral.sh/uv/install.sh | sh \ No newline at end of file diff --git a/.devcontainer/llm-proxy/devcontainer.json b/.devcontainer/llm-proxy/devcontainer.json new file mode 100644 index 0000000..38edb99 --- /dev/null +++ b/.devcontainer/llm-proxy/devcontainer.json @@ -0,0 +1,35 @@ +{ + "name": "llm-proxy", + "build": { + "dockerfile": "Dockerfile", + "context": "../.." + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/home/appuser/workspace,type=bind", + "workspaceFolder": "/home/appuser/workspace/services/llm-proxy", + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" + ], + "remoteUser": "appuser", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent", + "GIT_CONFIG_GLOBAL": "/home/appuser/.gitconfig" + }, + "runArgs": [ + "--network=host" + ], + "overrideCommand": true, + "postCreateCommand": "cd /home/appuser/workspace && /bin/bash .devcontainer/res/post_create_command.bash", + "customizations": { + "vscode": { + "extensions": [ + "skellock.just", + "ms-python.python", + "ms-python.pylint", + "ms-python.autopep8", + "tamasfe.even-better-toml", + "VisualStudioExptTeam.vscodeintellicode", + "matangover.mypy" + ] + } + } +} \ No newline at end of file From 14da282f50f7d54b8397b309817f34a6a73dc379 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 01:55:51 +0000 Subject: [PATCH 020/108] Add llm-proxy package files --- services/llm-proxy/.gitignore | 3 + services/llm-proxy/justfile | 20 + services/llm-proxy/pyproject.toml | 24 + services/llm-proxy/src/llm_proxy/__init__.py | 0 services/llm-proxy/uv.lock | 2458 ++++++++++++++++++ 5 files changed, 2505 insertions(+) create mode 100644 services/llm-proxy/.gitignore create mode 100644 services/llm-proxy/justfile create mode 100644 services/llm-proxy/pyproject.toml create mode 100644 services/llm-proxy/src/llm_proxy/__init__.py create mode 100644 services/llm-proxy/uv.lock diff --git a/services/llm-proxy/.gitignore b/services/llm-proxy/.gitignore new file mode 100644 index 0000000..00c3d6c --- /dev/null +++ b/services/llm-proxy/.gitignore @@ -0,0 +1,3 @@ +src/llm_proxy.egg-info/ +data/ +outputs/ diff --git a/services/llm-proxy/justfile b/services/llm-proxy/justfile new file mode 100644 index 0000000..ada239d --- /dev/null +++ b/services/llm-proxy/justfile @@ -0,0 +1,20 @@ +# -------------------------------------------------- +# This file contains setup scripts for the project. +# For more info, see: https://github.com/casey/just +# -------------------------------------------------- + +set shell := ["bash", "-c"] + +# Setup virtual environment and install dependencies. +setup-environment: + uv python install 3.12 + uv venv + uv pip install -e .[dev] + +run-server: + uv run python main.py + +# Runs static checks using global pre-commit configuration. +run-precommit: + uv run pre-commit run -c ../../.pre-commit-config.yaml \ + --files `git ls-files --cached --others --exclude-standard` diff --git a/services/llm-proxy/pyproject.toml b/services/llm-proxy/pyproject.toml new file mode 100644 index 0000000..793c4c3 --- /dev/null +++ b/services/llm-proxy/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "llm_proxy" +version = "0.1.0" +requires-python=">=3.12" +dependencies = [ + "hydra-core==1.3.2", + "requests==2.32.3", + "uvicorn==0.38.0", + "fastapi==0.124.4", + "nemoguardrails==0.19.0", + "ollama==0.6.1" +] + +[project.optional-dependencies] +dev = [ + "pylint>=4.0.4", + "autopep8>=2.3.2", + "mypy>=1.19.0", + "pre-commit>=4.5.0" +] diff --git a/services/llm-proxy/src/llm_proxy/__init__.py b/services/llm-proxy/src/llm_proxy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/llm-proxy/uv.lock b/services/llm-proxy/uv.lock new file mode 100644 index 0000000..e6f0420 --- /dev/null +++ b/services/llm-proxy/uv.lock @@ -0,0 +1,2458 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload-time = "2025-10-28T20:56:32.708Z" }, + { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload-time = "2025-10-28T20:56:34.57Z" }, + { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload-time = "2025-10-28T20:56:36.377Z" }, + { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload-time = "2025-10-28T20:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload-time = "2025-10-28T20:56:39.75Z" }, + { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload-time = "2025-10-28T20:56:41.471Z" }, + { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload-time = "2025-10-28T20:56:43.162Z" }, + { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload-time = "2025-10-28T20:56:44.85Z" }, + { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload-time = "2025-10-28T20:56:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload-time = "2025-10-28T20:56:48.528Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload-time = "2025-10-28T20:56:50.77Z" }, + { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload-time = "2025-10-28T20:56:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload-time = "2025-10-28T20:56:54.292Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, + { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, + { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, + { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, + { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, + { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, + { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, + { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, + { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, + { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, + { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, + { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, + { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, + { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, + { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, + { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, + { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, + { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, + { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, + { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, + { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, + { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, + { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, + { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, + { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, + { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, + { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, + { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, + { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, + { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, + { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, + { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, + { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "annoy" +version = "1.17.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/38/e321b0e05d8cc068a594279fb7c097efb1df66231c295d482d7ad51b6473/annoy-1.17.3.tar.gz", hash = "sha256:9cbfebefe0a5f843eba29c6be4c84d601f4f41ad4ded0486f1b88c3b07739c15", size = 647460, upload-time = "2023-06-14T16:37:34.152Z" } + +[[package]] +name = "antlr4-python3-runtime" +version = "4.9.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034, upload-time = "2021-11-06T17:52:23.524Z" } + +[[package]] +name = "anyio" +version = "4.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, +] + +[[package]] +name = "astroid" +version = "4.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/22/97df040e15d964e592d3a180598ace67e91b7c559d8298bdb3c949dc6e42/astroid-4.0.2.tar.gz", hash = "sha256:ac8fb7ca1c08eb9afec91ccc23edbd8ac73bb22cbdd7da1d488d9fb8d6579070", size = 405714, upload-time = "2025-11-09T21:21:18.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/ac/a85b4bfb4cf53221513e27f33cc37ad158fce02ac291d18bee6b49ab477d/astroid-4.0.2-py3-none-any.whl", hash = "sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b", size = 276354, upload-time = "2025-11-09T21:21:16.54Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "autopep8" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycodestyle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210, upload-time = "2025-01-14T14:46:18.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807, upload-time = "2025-01-14T14:46:15.466Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coloredlogs" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "humanfriendly" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, +] + +[[package]] +name = "dataclasses-json" +version = "0.6.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marshmallow" }, + { name = "typing-inspect" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227, upload-time = "2024-06-09T16:20:19.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686, upload-time = "2024-06-09T16:20:16.715Z" }, +] + +[[package]] +name = "dill" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "fastapi" +version = "0.124.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/21/ade3ff6745a82ea8ad88552b4139d27941549e4f19125879f848ac8f3c3d/fastapi-0.124.4.tar.gz", hash = "sha256:0e9422e8d6b797515f33f500309f6e1c98ee4e85563ba0f2debb282df6343763", size = 378460, upload-time = "2025-12-12T15:00:43.891Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/57/aa70121b5008f44031be645a61a7c4abc24e0e888ad3fc8fda916f4d188e/fastapi-0.124.4-py3-none-any.whl", hash = "sha256:6d1e703698443ccb89e50abe4893f3c84d9d6689c0cf1ca4fad6d3c15cf69f15", size = 113281, upload-time = "2025-12-12T15:00:42.44Z" }, +] + +[[package]] +name = "fastembed" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "loguru" }, + { name = "mmh3" }, + { name = "numpy" }, + { name = "onnxruntime" }, + { name = "pillow" }, + { name = "py-rust-stemmers" }, + { name = "requests" }, + { name = "tokenizers" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/f4/036a656c605f63dc25f11284f60f69900a54a19c513e1ae60d21d6977e75/fastembed-0.6.0.tar.gz", hash = "sha256:5c9ead25f23449535b07243bbe1f370b820dcc77ec2931e61674e3fe7ff24733", size = 50731, upload-time = "2025-02-26T13:50:33.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/f4/82764d9d4fc31428f6a8dd2daa0c53462cc66843e1bb55437e8fbf581140/fastembed-0.6.0-py3-none-any.whl", hash = "sha256:a08385e9388adea0529a586004f2d588c9787880a510e4e5d167127a11e75328", size = 85390, upload-time = "2025-02-26T13:50:31.078Z" }, +] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "flatbuffers" +version = "25.9.23" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/1f/3ee70b0a55137442038f2a33469cc5fddd7e0ad2abf83d7497c18a2b6923/flatbuffers-25.9.23.tar.gz", hash = "sha256:676f9fa62750bb50cf531b42a0a2a118ad8f7f797a511eda12881c016f093b12", size = 22067, upload-time = "2025-09-24T05:25:30.106Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/1b/00a78aa2e8fbd63f9af08c9c19e6deb3d5d66b4dda677a0f61654680ee89/flatbuffers-25.9.23-py2.py3-none-any.whl", hash = "sha256:255538574d6cb6d0a79a17ec8bc0d30985913b87513a01cce8bcdb6b4c44d0e2", size = 30869, upload-time = "2025-09-24T05:25:28.912Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, +] + +[[package]] +name = "greenlet" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, + { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, + { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, + { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, + { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, + { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, + { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, + { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, + { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, + { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" }, + { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, + { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, + { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, + { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, + { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "hf-xet" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/a5/85ef910a0aa034a2abcfadc360ab5ac6f6bc4e9112349bd40ca97551cff0/hf_xet-1.2.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649", size = 2861870, upload-time = "2025-10-24T19:04:11.422Z" }, + { url = "https://files.pythonhosted.org/packages/ea/40/e2e0a7eb9a51fe8828ba2d47fe22a7e74914ea8a0db68a18c3aa7449c767/hf_xet-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813", size = 2717584, upload-time = "2025-10-24T19:04:09.586Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7d/daf7f8bc4594fdd59a8a596f9e3886133fdc68e675292218a5e4c1b7e834/hf_xet-1.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc", size = 3315004, upload-time = "2025-10-24T19:04:00.314Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ba/45ea2f605fbf6d81c8b21e4d970b168b18a53515923010c312c06cd83164/hf_xet-1.2.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5", size = 3222636, upload-time = "2025-10-24T19:03:58.111Z" }, + { url = "https://files.pythonhosted.org/packages/4a/1d/04513e3cab8f29ab8c109d309ddd21a2705afab9d52f2ba1151e0c14f086/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f", size = 3408448, upload-time = "2025-10-24T19:04:20.951Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7c/60a2756d7feec7387db3a1176c632357632fbe7849fce576c5559d4520c7/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832", size = 3503401, upload-time = "2025-10-24T19:04:22.549Z" }, + { url = "https://files.pythonhosted.org/packages/4e/64/48fffbd67fb418ab07451e4ce641a70de1c40c10a13e25325e24858ebe5a/hf_xet-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382", size = 2900866, upload-time = "2025-10-24T19:04:33.461Z" }, + { url = "https://files.pythonhosted.org/packages/e2/51/f7e2caae42f80af886db414d4e9885fac959330509089f97cccb339c6b87/hf_xet-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e", size = 2861861, upload-time = "2025-10-24T19:04:19.01Z" }, + { url = "https://files.pythonhosted.org/packages/6e/1d/a641a88b69994f9371bd347f1dd35e5d1e2e2460a2e350c8d5165fc62005/hf_xet-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8", size = 2717699, upload-time = "2025-10-24T19:04:17.306Z" }, + { url = "https://files.pythonhosted.org/packages/df/e0/e5e9bba7d15f0318955f7ec3f4af13f92e773fbb368c0b8008a5acbcb12f/hf_xet-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0", size = 3314885, upload-time = "2025-10-24T19:04:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/21/90/b7fe5ff6f2b7b8cbdf1bd56145f863c90a5807d9758a549bf3d916aa4dec/hf_xet-1.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090", size = 3221550, upload-time = "2025-10-24T19:04:05.55Z" }, + { url = "https://files.pythonhosted.org/packages/6f/cb/73f276f0a7ce46cc6a6ec7d6c7d61cbfe5f2e107123d9bbd0193c355f106/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a", size = 3408010, upload-time = "2025-10-24T19:04:28.598Z" }, + { url = "https://files.pythonhosted.org/packages/b8/1e/d642a12caa78171f4be64f7cd9c40e3ca5279d055d0873188a58c0f5fbb9/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f", size = 3503264, upload-time = "2025-10-24T19:04:30.397Z" }, + { url = "https://files.pythonhosted.org/packages/17/b5/33764714923fa1ff922770f7ed18c2daae034d21ae6e10dbf4347c854154/hf_xet-1.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc", size = 2901071, upload-time = "2025-10-24T19:04:37.463Z" }, + { url = "https://files.pythonhosted.org/packages/96/2d/22338486473df5923a9ab7107d375dbef9173c338ebef5098ef593d2b560/hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848", size = 2866099, upload-time = "2025-10-24T19:04:15.366Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8c/c5becfa53234299bc2210ba314eaaae36c2875e0045809b82e40a9544f0c/hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4", size = 2722178, upload-time = "2025-10-24T19:04:13.695Z" }, + { url = "https://files.pythonhosted.org/packages/9a/92/cf3ab0b652b082e66876d08da57fcc6fa2f0e6c70dfbbafbd470bb73eb47/hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd", size = 3320214, upload-time = "2025-10-24T19:04:03.596Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/3f7ec4a1b6a65bf45b059b6d4a5d38988f63e193056de2f420137e3c3244/hf_xet-1.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c", size = 3229054, upload-time = "2025-10-24T19:04:01.949Z" }, + { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, + { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, + { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "httpx-sse" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943, upload-time = "2025-10-10T21:48:22.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" }, +] + +[[package]] +name = "huggingface-hub" +version = "0.36.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, +] + +[[package]] +name = "humanfriendly" +version = "10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyreadline3", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, +] + +[[package]] +name = "hydra-core" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "omegaconf" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/8e/07e42bc434a847154083b315779b0a81d567154504624e181caf2c71cd98/hydra-core-1.3.2.tar.gz", hash = "sha256:8a878ed67216997c3e9d88a8e72e7b4767e81af37afb4ea3334b269a4390a824", size = 3263494, upload-time = "2023-02-23T18:33:43.03Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/50/e0edd38dcd63fb26a8547f13d28f7a008bc4a3fd4eb4ff030673f22ad41a/hydra_core-1.3.2-py3-none-any.whl", hash = "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b", size = 154547, upload-time = "2023-02-23T18:33:40.801Z" }, +] + +[[package]] +name = "identify" +version = "2.6.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "isort" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpointer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699, upload-time = "2023-06-26T12:07:29.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898, upload-time = "2023-06-16T21:01:28.466Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, +] + +[[package]] +name = "langchain" +version = "0.3.27" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langchain-text-splitters" }, + { name = "langsmith" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/f6/f4f7f3a56626fe07e2bb330feb61254dbdf06c506e6b59a536a337da51cf/langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62", size = 10233809, upload-time = "2025-07-24T14:42:32.959Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/d5/4861816a95b2f6993f1360cfb605aacb015506ee2090433a71de9cca8477/langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798", size = 1018194, upload-time = "2025-07-24T14:42:30.23Z" }, +] + +[[package]] +name = "langchain-community" +version = "0.3.27" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "dataclasses-json" }, + { name = "httpx-sse" }, + { name = "langchain" }, + { name = "langchain-core" }, + { name = "langsmith" }, + { name = "numpy" }, + { name = "pydantic-settings" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, + { name = "tenacity" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/76/200494f6de488217a196c4369e665d26b94c8c3642d46e2fd62f9daf0a3a/langchain_community-0.3.27.tar.gz", hash = "sha256:e1037c3b9da0c6d10bf06e838b034eb741e016515c79ef8f3f16e53ead33d882", size = 33237737, upload-time = "2025-07-02T18:47:02.329Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/bc/f8c7dae8321d37ed39ac9d7896617c4203248240a4835b136e3724b3bb62/langchain_community-0.3.27-py3-none-any.whl", hash = "sha256:581f97b795f9633da738ea95da9cb78f8879b538090c9b7a68c0aed49c828f0d", size = 2530442, upload-time = "2025-07-02T18:47:00.246Z" }, +] + +[[package]] +name = "langchain-core" +version = "0.3.80" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpatch" }, + { name = "langsmith" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "tenacity" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/49/f76647b7ba1a6f9c11b0343056ab4d3e5fc445981d205237fed882b2ad60/langchain_core-0.3.80.tar.gz", hash = "sha256:29636b82513ab49e834764d023c4d18554d3d719a185d37b019d0a8ae948c6bb", size = 583629, upload-time = "2025-11-19T22:23:18.771Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/e8/e7a090ebe37f2b071c64e81b99fb1273b3151ae932f560bb94c22f191cde/langchain_core-0.3.80-py3-none-any.whl", hash = "sha256:2141e3838d100d17dce2359f561ec0df52c526bae0de6d4f469f8026c5747456", size = 450786, upload-time = "2025-11-19T22:23:17.133Z" }, +] + +[[package]] +name = "langchain-text-splitters" +version = "0.3.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/11/43/dcda8fd25f0b19cb2835f2f6bb67f26ad58634f04ac2d8eae00526b0fa55/langchain_text_splitters-0.3.11.tar.gz", hash = "sha256:7a50a04ada9a133bbabb80731df7f6ddac51bc9f1b9cab7fa09304d71d38a6cc", size = 46458, upload-time = "2025-08-31T23:02:58.316Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/0d/41a51b40d24ff0384ec4f7ab8dd3dcea8353c05c973836b5e289f1465d4f/langchain_text_splitters-0.3.11-py3-none-any.whl", hash = "sha256:cf079131166a487f1372c8ab5d0bfaa6c0a4291733d9c43a34a16ac9bcd6a393", size = 33845, upload-time = "2025-08-31T23:02:57.195Z" }, +] + +[[package]] +name = "langsmith" +version = "0.4.59" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson", marker = "platform_python_implementation != 'PyPy'" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "uuid-utils" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/71/d61524c3205bde7ec90423d997cf1a228d8adf2811110ec91ed40c8e8a34/langsmith-0.4.59.tar.gz", hash = "sha256:6b143214c2303dafb29ab12dcd05ac50bdfc60dac01c6e0450e50cee1d2415e0", size = 992784, upload-time = "2025-12-11T02:40:52.231Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/54/4577ef9424debea2fa08af338489d593276520d2e2f8950575d292be612c/langsmith-0.4.59-py3-none-any.whl", hash = "sha256:97c26399286441a7b7b06b912e2801420fbbf3a049787e609d49dc975ab10bc5", size = 413051, upload-time = "2025-12-11T02:40:50.523Z" }, +] + +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, +] + +[[package]] +name = "librt" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/d9/6f3d3fcf5e5543ed8a60cc70fa7d50508ed60b8a10e9af6d2058159ab54e/librt-0.7.3.tar.gz", hash = "sha256:3ec50cf65235ff5c02c5b747748d9222e564ad48597122a361269dd3aa808798", size = 144549, upload-time = "2025-12-06T19:04:45.553Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/90/ed8595fa4e35b6020317b5ea8d226a782dcbac7a997c19ae89fb07a41c66/librt-0.7.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fa9ac2e49a6bee56e47573a6786cb635e128a7b12a0dc7851090037c0d397a3", size = 55687, upload-time = "2025-12-06T19:03:39.245Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f6/6a20702a07b41006cb001a759440cb6b5362530920978f64a2b2ae2bf729/librt-0.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e980cf1ed1a2420a6424e2ed884629cdead291686f1048810a817de07b5eb18", size = 57127, upload-time = "2025-12-06T19:03:40.3Z" }, + { url = "https://files.pythonhosted.org/packages/79/f3/b0c4703d5ffe9359b67bb2ccb86c42d4e930a363cfc72262ac3ba53cff3e/librt-0.7.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e094e445c37c57e9ec612847812c301840239d34ccc5d153a982fa9814478c60", size = 165336, upload-time = "2025-12-06T19:03:41.369Z" }, + { url = "https://files.pythonhosted.org/packages/02/69/3ba05b73ab29ccbe003856232cea4049769be5942d799e628d1470ed1694/librt-0.7.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aca73d70c3f553552ba9133d4a09e767dcfeee352d8d8d3eb3f77e38a3beb3ed", size = 174237, upload-time = "2025-12-06T19:03:42.44Z" }, + { url = "https://files.pythonhosted.org/packages/22/ad/d7c2671e7bf6c285ef408aa435e9cd3fdc06fd994601e1f2b242df12034f/librt-0.7.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c634a0a6db395fdaba0361aa78395597ee72c3aad651b9a307a3a7eaf5efd67e", size = 189017, upload-time = "2025-12-06T19:03:44.01Z" }, + { url = "https://files.pythonhosted.org/packages/f4/94/d13f57193148004592b618555f296b41d2d79b1dc814ff8b3273a0bf1546/librt-0.7.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a59a69deeb458c858b8fea6acf9e2acd5d755d76cd81a655256bc65c20dfff5b", size = 183983, upload-time = "2025-12-06T19:03:45.834Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/b612a9944ebd39fa143c7e2e2d33f2cb790205e025ddd903fb509a3a3bb3/librt-0.7.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d91e60ac44bbe3a77a67af4a4c13114cbe9f6d540337ce22f2c9eaf7454ca71f", size = 177602, upload-time = "2025-12-06T19:03:46.944Z" }, + { url = "https://files.pythonhosted.org/packages/1f/48/77bc05c4cc232efae6c5592c0095034390992edbd5bae8d6cf1263bb7157/librt-0.7.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:703456146dc2bf430f7832fd1341adac5c893ec3c1430194fdcefba00012555c", size = 199282, upload-time = "2025-12-06T19:03:48.069Z" }, + { url = "https://files.pythonhosted.org/packages/12/aa/05916ccd864227db1ffec2a303ae34f385c6b22d4e7ce9f07054dbcf083c/librt-0.7.3-cp312-cp312-win32.whl", hash = "sha256:b7c1239b64b70be7759554ad1a86288220bbb04d68518b527783c4ad3fb4f80b", size = 47879, upload-time = "2025-12-06T19:03:49.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/92/7f41c42d31ea818b3c4b9cc1562e9714bac3c676dd18f6d5dd3d0f2aa179/librt-0.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef59c938f72bdbc6ab52dc50f81d0637fde0f194b02d636987cea2ab30f8f55a", size = 54972, upload-time = "2025-12-06T19:03:50.335Z" }, + { url = "https://files.pythonhosted.org/packages/3f/dc/53582bbfb422311afcbc92adb75711f04e989cec052f08ec0152fbc36c9c/librt-0.7.3-cp312-cp312-win_arm64.whl", hash = "sha256:ff21c554304e8226bf80c3a7754be27c6c3549a9fec563a03c06ee8f494da8fc", size = 48338, upload-time = "2025-12-06T19:03:51.431Z" }, + { url = "https://files.pythonhosted.org/packages/93/7d/e0ce1837dfb452427db556e6d4c5301ba3b22fe8de318379fbd0593759b9/librt-0.7.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56f2a47beda8409061bc1c865bef2d4bd9ff9255219402c0817e68ab5ad89aed", size = 55742, upload-time = "2025-12-06T19:03:52.459Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/3564262301e507e1d5cf31c7d84cb12addf0d35e05ba53312494a2eba9a4/librt-0.7.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14569ac5dd38cfccf0a14597a88038fb16811a6fede25c67b79c6d50fc2c8fdc", size = 57163, upload-time = "2025-12-06T19:03:53.516Z" }, + { url = "https://files.pythonhosted.org/packages/be/ac/245e72b7e443d24a562f6047563c7f59833384053073ef9410476f68505b/librt-0.7.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6038ccbd5968325a5d6fd393cf6e00b622a8de545f0994b89dd0f748dcf3e19e", size = 165840, upload-time = "2025-12-06T19:03:54.918Z" }, + { url = "https://files.pythonhosted.org/packages/98/af/587e4491f40adba066ba39a450c66bad794c8d92094f936a201bfc7c2b5f/librt-0.7.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d39079379a9a28e74f4d57dc6357fa310a1977b51ff12239d7271ec7e71d67f5", size = 174827, upload-time = "2025-12-06T19:03:56.082Z" }, + { url = "https://files.pythonhosted.org/packages/78/21/5b8c60ea208bc83dd00421022a3874330685d7e856404128dc3728d5d1af/librt-0.7.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8837d5a52a2d7aa9f4c3220a8484013aed1d8ad75240d9a75ede63709ef89055", size = 189612, upload-time = "2025-12-06T19:03:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/da/2f/8b819169ef696421fb81cd04c6cdf225f6e96f197366001e9d45180d7e9e/librt-0.7.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:399bbd7bcc1633c3e356ae274a1deb8781c7bf84d9c7962cc1ae0c6e87837292", size = 184584, upload-time = "2025-12-06T19:03:58.686Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fc/af9d225a9395b77bd7678362cb055d0b8139c2018c37665de110ca388022/librt-0.7.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8d8cf653e798ee4c4e654062b633db36984a1572f68c3aa25e364a0ddfbbb910", size = 178269, upload-time = "2025-12-06T19:03:59.769Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d8/7b4fa1683b772966749d5683aa3fd605813defffe157833a8fa69cc89207/librt-0.7.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2f03484b54bf4ae80ab2e504a8d99d20d551bfe64a7ec91e218010b467d77093", size = 199852, upload-time = "2025-12-06T19:04:00.901Z" }, + { url = "https://files.pythonhosted.org/packages/77/e8/4598413aece46ca38d9260ef6c51534bd5f34b5c21474fcf210ce3a02123/librt-0.7.3-cp313-cp313-win32.whl", hash = "sha256:44b3689b040df57f492e02cd4f0bacd1b42c5400e4b8048160c9d5e866de8abe", size = 47936, upload-time = "2025-12-06T19:04:02.054Z" }, + { url = "https://files.pythonhosted.org/packages/af/80/ac0e92d5ef8c6791b3e2c62373863827a279265e0935acdf807901353b0e/librt-0.7.3-cp313-cp313-win_amd64.whl", hash = "sha256:6b407c23f16ccc36614c136251d6b32bf30de7a57f8e782378f1107be008ddb0", size = 54965, upload-time = "2025-12-06T19:04:03.224Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fd/042f823fcbff25c1449bb4203a29919891ca74141b68d3a5f6612c4ce283/librt-0.7.3-cp313-cp313-win_arm64.whl", hash = "sha256:abfc57cab3c53c4546aee31859ef06753bfc136c9d208129bad23e2eca39155a", size = 48350, upload-time = "2025-12-06T19:04:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ae/c6ecc7bb97134a71b5241e8855d39964c0e5f4d96558f0d60593892806d2/librt-0.7.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:120dd21d46ff875e849f1aae19346223cf15656be489242fe884036b23d39e93", size = 55175, upload-time = "2025-12-06T19:04:05.308Z" }, + { url = "https://files.pythonhosted.org/packages/cf/bc/2cc0cb0ab787b39aa5c7645cd792433c875982bdf12dccca558b89624594/librt-0.7.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1617bea5ab31266e152871208502ee943cb349c224846928a1173c864261375e", size = 56881, upload-time = "2025-12-06T19:04:06.674Z" }, + { url = "https://files.pythonhosted.org/packages/8e/87/397417a386190b70f5bf26fcedbaa1515f19dce33366e2684c6b7ee83086/librt-0.7.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93b2a1f325fefa1482516ced160c8c7b4b8d53226763fa6c93d151fa25164207", size = 163710, upload-time = "2025-12-06T19:04:08.437Z" }, + { url = "https://files.pythonhosted.org/packages/c9/37/7338f85b80e8a17525d941211451199845093ca242b32efbf01df8531e72/librt-0.7.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d4801db8354436fd3936531e7f0e4feb411f62433a6b6cb32bb416e20b529f", size = 172471, upload-time = "2025-12-06T19:04:10.124Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e0/741704edabbfae2c852fedc1b40d9ed5a783c70ed3ed8e4fe98f84b25d13/librt-0.7.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11ad45122bbed42cfc8b0597450660126ef28fd2d9ae1a219bc5af8406f95678", size = 186804, upload-time = "2025-12-06T19:04:11.586Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d1/0a82129d6ba242f3be9af34815be089f35051bc79619f5c27d2c449ecef6/librt-0.7.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6b4e7bff1d76dd2b46443078519dc75df1b5e01562345f0bb740cea5266d8218", size = 181817, upload-time = "2025-12-06T19:04:12.802Z" }, + { url = "https://files.pythonhosted.org/packages/4f/32/704f80bcf9979c68d4357c46f2af788fbf9d5edda9e7de5786ed2255e911/librt-0.7.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:d86f94743a11873317094326456b23f8a5788bad9161fd2f0e52088c33564620", size = 175602, upload-time = "2025-12-06T19:04:14.004Z" }, + { url = "https://files.pythonhosted.org/packages/f7/6d/4355cfa0fae0c062ba72f541d13db5bc575770125a7ad3d4f46f4109d305/librt-0.7.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:754a0d09997095ad764ccef050dd5bf26cbf457aab9effcba5890dad081d879e", size = 196497, upload-time = "2025-12-06T19:04:15.487Z" }, + { url = "https://files.pythonhosted.org/packages/2e/eb/ac6d8517d44209e5a712fde46f26d0055e3e8969f24d715f70bd36056230/librt-0.7.3-cp314-cp314-win32.whl", hash = "sha256:fbd7351d43b80d9c64c3cfcb50008f786cc82cba0450e8599fdd64f264320bd3", size = 44678, upload-time = "2025-12-06T19:04:16.688Z" }, + { url = "https://files.pythonhosted.org/packages/e9/93/238f026d141faf9958da588c761a0812a1a21c98cc54a76f3608454e4e59/librt-0.7.3-cp314-cp314-win_amd64.whl", hash = "sha256:d376a35c6561e81d2590506804b428fc1075fcc6298fc5bb49b771534c0ba010", size = 51689, upload-time = "2025-12-06T19:04:17.726Z" }, + { url = "https://files.pythonhosted.org/packages/52/44/43f462ad9dcf9ed7d3172fe2e30d77b980956250bd90e9889a9cca93df2a/librt-0.7.3-cp314-cp314-win_arm64.whl", hash = "sha256:cbdb3f337c88b43c3b49ca377731912c101178be91cb5071aac48faa898e6f8e", size = 44662, upload-time = "2025-12-06T19:04:18.771Z" }, + { url = "https://files.pythonhosted.org/packages/1d/35/fed6348915f96b7323241de97f26e2af481e95183b34991df12fd5ce31b1/librt-0.7.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9f0e0927efe87cd42ad600628e595a1a0aa1c64f6d0b55f7e6059079a428641a", size = 57347, upload-time = "2025-12-06T19:04:19.812Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f2/045383ccc83e3fea4fba1b761796584bc26817b6b2efb6b8a6731431d16f/librt-0.7.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:020c6db391268bcc8ce75105cb572df8cb659a43fd347366aaa407c366e5117a", size = 59223, upload-time = "2025-12-06T19:04:20.862Z" }, + { url = "https://files.pythonhosted.org/packages/77/3f/c081f8455ab1d7f4a10dbe58463ff97119272ff32494f21839c3b9029c2c/librt-0.7.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7af7785f5edd1f418da09a8cdb9ec84b0213e23d597413e06525340bcce1ea4f", size = 183861, upload-time = "2025-12-06T19:04:21.963Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f5/73c5093c22c31fbeaebc25168837f05ebfd8bf26ce00855ef97a5308f36f/librt-0.7.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ccadf260bb46a61b9c7e89e2218f6efea9f3eeaaab4e3d1f58571890e54858e", size = 194594, upload-time = "2025-12-06T19:04:23.14Z" }, + { url = "https://files.pythonhosted.org/packages/78/b8/d5f17d4afe16612a4a94abfded94c16c5a033f183074fb130dfe56fc1a42/librt-0.7.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9883b2d819ce83f87ba82a746c81d14ada78784db431e57cc9719179847376e", size = 206759, upload-time = "2025-12-06T19:04:24.328Z" }, + { url = "https://files.pythonhosted.org/packages/36/2e/021765c1be85ee23ffd5b5b968bb4cba7526a4db2a0fc27dcafbdfc32da7/librt-0.7.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:59cb0470612d21fa1efddfa0dd710756b50d9c7fb6c1236bbf8ef8529331dc70", size = 203210, upload-time = "2025-12-06T19:04:25.544Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/9923656e42da4fd18c594bd08cf6d7e152d4158f8b808e210d967f0dcceb/librt-0.7.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:1fe603877e1865b5fd047a5e40379509a4a60204aa7aa0f72b16f7a41c3f0712", size = 196708, upload-time = "2025-12-06T19:04:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/fc/0b/0708b886ac760e64d6fbe7e16024e4be3ad1a3629d19489a97e9cf4c3431/librt-0.7.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5460d99ed30f043595bbdc888f542bad2caeb6226b01c33cda3ae444e8f82d42", size = 217212, upload-time = "2025-12-06T19:04:27.892Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7f/12a73ff17bca4351e73d585dd9ebf46723c4a8622c4af7fe11a2e2d011ff/librt-0.7.3-cp314-cp314t-win32.whl", hash = "sha256:d09f677693328503c9e492e33e9601464297c01f9ebd966ea8fc5308f3069bfd", size = 45586, upload-time = "2025-12-06T19:04:29.116Z" }, + { url = "https://files.pythonhosted.org/packages/e2/df/8decd032ac9b995e4f5606cde783711a71094128d88d97a52e397daf2c89/librt-0.7.3-cp314-cp314t-win_amd64.whl", hash = "sha256:25711f364c64cab2c910a0247e90b51421e45dbc8910ceeb4eac97a9e132fc6f", size = 53002, upload-time = "2025-12-06T19:04:30.173Z" }, + { url = "https://files.pythonhosted.org/packages/de/0c/6605b6199de8178afe7efc77ca1d8e6db00453bc1d3349d27605c0f42104/librt-0.7.3-cp314-cp314t-win_arm64.whl", hash = "sha256:a9f9b661f82693eb56beb0605156c7fca57f535704ab91837405913417d6990b", size = 45647, upload-time = "2025-12-06T19:04:31.302Z" }, +] + +[[package]] +name = "llm-proxy" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "fastapi" }, + { name = "hydra-core" }, + { name = "nemoguardrails" }, + { name = "ollama" }, + { name = "requests" }, + { name = "uvicorn" }, +] + +[package.optional-dependencies] +dev = [ + { name = "autopep8" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pylint" }, +] + +[package.metadata] +requires-dist = [ + { name = "autopep8", marker = "extra == 'dev'", specifier = ">=2.3.2" }, + { name = "fastapi", specifier = "==0.124.4" }, + { name = "hydra-core", specifier = "==1.3.2" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, + { name = "nemoguardrails", specifier = "==0.19.0" }, + { name = "ollama", specifier = "==0.6.1" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, + { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, + { name = "requests", specifier = "==2.32.3" }, + { name = "uvicorn", specifier = "==0.38.0" }, +] +provides-extras = ["dev"] + +[[package]] +name = "loguru" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "marshmallow" +version = "3.26.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/5e/5e53d26b42ab75491cda89b871dab9e97c840bf12c63ec58a1919710cd06/marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6", size = 221825, upload-time = "2025-02-03T15:32:25.093Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/75/51952c7b2d3873b44a0028b1bd26a25078c18f92f256608e8d1dc61b39fd/marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c", size = 50878, upload-time = "2025-02-03T15:32:22.295Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mmh3" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/af/f28c2c2f51f31abb4725f9a64bc7863d5f491f6539bd26aee2a1d21a649e/mmh3-5.2.0.tar.gz", hash = "sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8", size = 33582, upload-time = "2025-07-29T07:43:48.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/6a/d5aa7edb5c08e0bd24286c7d08341a0446f9a2fbbb97d96a8a6dd81935ee/mmh3-5.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be", size = 56141, upload-time = "2025-07-29T07:42:13.456Z" }, + { url = "https://files.pythonhosted.org/packages/08/49/131d0fae6447bc4a7299ebdb1a6fb9d08c9f8dcf97d75ea93e8152ddf7ab/mmh3-5.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd", size = 40681, upload-time = "2025-07-29T07:42:14.306Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6f/9221445a6bcc962b7f5ff3ba18ad55bba624bacdc7aa3fc0a518db7da8ec/mmh3-5.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96", size = 40062, upload-time = "2025-07-29T07:42:15.08Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d4/6bb2d0fef81401e0bb4c297d1eb568b767de4ce6fc00890bc14d7b51ecc4/mmh3-5.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094", size = 97333, upload-time = "2025-07-29T07:42:16.436Z" }, + { url = "https://files.pythonhosted.org/packages/44/e0/ccf0daff8134efbb4fbc10a945ab53302e358c4b016ada9bf97a6bdd50c1/mmh3-5.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037", size = 103310, upload-time = "2025-07-29T07:42:17.796Z" }, + { url = "https://files.pythonhosted.org/packages/02/63/1965cb08a46533faca0e420e06aff8bbaf9690a6f0ac6ae6e5b2e4544687/mmh3-5.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773", size = 106178, upload-time = "2025-07-29T07:42:19.281Z" }, + { url = "https://files.pythonhosted.org/packages/c2/41/c883ad8e2c234013f27f92061200afc11554ea55edd1bcf5e1accd803a85/mmh3-5.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5", size = 113035, upload-time = "2025-07-29T07:42:20.356Z" }, + { url = "https://files.pythonhosted.org/packages/df/b5/1ccade8b1fa625d634a18bab7bf08a87457e09d5ec8cf83ca07cbea9d400/mmh3-5.2.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50", size = 120784, upload-time = "2025-07-29T07:42:21.377Z" }, + { url = "https://files.pythonhosted.org/packages/77/1c/919d9171fcbdcdab242e06394464ccf546f7d0f3b31e0d1e3a630398782e/mmh3-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765", size = 99137, upload-time = "2025-07-29T07:42:22.344Z" }, + { url = "https://files.pythonhosted.org/packages/66/8a/1eebef5bd6633d36281d9fc83cf2e9ba1ba0e1a77dff92aacab83001cee4/mmh3-5.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43", size = 98664, upload-time = "2025-07-29T07:42:23.269Z" }, + { url = "https://files.pythonhosted.org/packages/13/41/a5d981563e2ee682b21fb65e29cc0f517a6734a02b581359edd67f9d0360/mmh3-5.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4", size = 106459, upload-time = "2025-07-29T07:42:24.238Z" }, + { url = "https://files.pythonhosted.org/packages/24/31/342494cd6ab792d81e083680875a2c50fa0c5df475ebf0b67784f13e4647/mmh3-5.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3", size = 110038, upload-time = "2025-07-29T07:42:25.629Z" }, + { url = "https://files.pythonhosted.org/packages/28/44/efda282170a46bb4f19c3e2b90536513b1d821c414c28469a227ca5a1789/mmh3-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c", size = 97545, upload-time = "2025-07-29T07:42:27.04Z" }, + { url = "https://files.pythonhosted.org/packages/68/8f/534ae319c6e05d714f437e7206f78c17e66daca88164dff70286b0e8ea0c/mmh3-5.2.0-cp312-cp312-win32.whl", hash = "sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49", size = 40805, upload-time = "2025-07-29T07:42:28.032Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f6/f6abdcfefcedab3c964868048cfe472764ed358c2bf6819a70dd4ed4ed3a/mmh3-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3", size = 41597, upload-time = "2025-07-29T07:42:28.894Z" }, + { url = "https://files.pythonhosted.org/packages/15/fd/f7420e8cbce45c259c770cac5718badf907b302d3a99ec587ba5ce030237/mmh3-5.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0", size = 39350, upload-time = "2025-07-29T07:42:29.794Z" }, + { url = "https://files.pythonhosted.org/packages/d8/fa/27f6ab93995ef6ad9f940e96593c5dd24744d61a7389532b0fec03745607/mmh3-5.2.0-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065", size = 40874, upload-time = "2025-07-29T07:42:30.662Z" }, + { url = "https://files.pythonhosted.org/packages/11/9c/03d13bcb6a03438bc8cac3d2e50f80908d159b31a4367c2e1a7a077ded32/mmh3-5.2.0-cp313-cp313-android_21_x86_64.whl", hash = "sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de", size = 42012, upload-time = "2025-07-29T07:42:31.539Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/0865d9765408a7d504f1789944e678f74e0888b96a766d578cb80b040999/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044", size = 39197, upload-time = "2025-07-29T07:42:32.374Z" }, + { url = "https://files.pythonhosted.org/packages/3e/12/76c3207bd186f98b908b6706c2317abb73756d23a4e68ea2bc94825b9015/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73", size = 39840, upload-time = "2025-07-29T07:42:33.227Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0d/574b6cce5555c9f2b31ea189ad44986755eb14e8862db28c8b834b8b64dc/mmh3-5.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504", size = 40644, upload-time = "2025-07-29T07:42:34.099Z" }, + { url = "https://files.pythonhosted.org/packages/52/82/3731f8640b79c46707f53ed72034a58baad400be908c87b0088f1f89f986/mmh3-5.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b", size = 56153, upload-time = "2025-07-29T07:42:35.031Z" }, + { url = "https://files.pythonhosted.org/packages/4f/34/e02dca1d4727fd9fdeaff9e2ad6983e1552804ce1d92cc796e5b052159bb/mmh3-5.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05", size = 40684, upload-time = "2025-07-29T07:42:35.914Z" }, + { url = "https://files.pythonhosted.org/packages/8f/36/3dee40767356e104967e6ed6d102ba47b0b1ce2a89432239b95a94de1b89/mmh3-5.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814", size = 40057, upload-time = "2025-07-29T07:42:36.755Z" }, + { url = "https://files.pythonhosted.org/packages/31/58/228c402fccf76eb39a0a01b8fc470fecf21965584e66453b477050ee0e99/mmh3-5.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093", size = 97344, upload-time = "2025-07-29T07:42:37.675Z" }, + { url = "https://files.pythonhosted.org/packages/34/82/fc5ce89006389a6426ef28e326fc065b0fbaaed230373b62d14c889f47ea/mmh3-5.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54", size = 103325, upload-time = "2025-07-29T07:42:38.591Z" }, + { url = "https://files.pythonhosted.org/packages/09/8c/261e85777c6aee1ebd53f2f17e210e7481d5b0846cd0b4a5c45f1e3761b8/mmh3-5.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a", size = 106240, upload-time = "2025-07-29T07:42:39.563Z" }, + { url = "https://files.pythonhosted.org/packages/70/73/2f76b3ad8a3d431824e9934403df36c0ddacc7831acf82114bce3c4309c8/mmh3-5.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908", size = 113060, upload-time = "2025-07-29T07:42:40.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b9/7ea61a34e90e50a79a9d87aa1c0b8139a7eaf4125782b34b7d7383472633/mmh3-5.2.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5", size = 120781, upload-time = "2025-07-29T07:42:41.618Z" }, + { url = "https://files.pythonhosted.org/packages/0f/5b/ae1a717db98c7894a37aeedbd94b3f99e6472a836488f36b6849d003485b/mmh3-5.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a", size = 99174, upload-time = "2025-07-29T07:42:42.587Z" }, + { url = "https://files.pythonhosted.org/packages/e3/de/000cce1d799fceebb6d4487ae29175dd8e81b48e314cba7b4da90bcf55d7/mmh3-5.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266", size = 98734, upload-time = "2025-07-29T07:42:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/79/19/0dc364391a792b72fbb22becfdeacc5add85cc043cd16986e82152141883/mmh3-5.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5", size = 106493, upload-time = "2025-07-29T07:42:45.07Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b1/bc8c28e4d6e807bbb051fefe78e1156d7f104b89948742ad310612ce240d/mmh3-5.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9", size = 110089, upload-time = "2025-07-29T07:42:46.122Z" }, + { url = "https://files.pythonhosted.org/packages/3b/a2/d20f3f5c95e9c511806686c70d0a15479cc3941c5f322061697af1c1ff70/mmh3-5.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290", size = 97571, upload-time = "2025-07-29T07:42:47.18Z" }, + { url = "https://files.pythonhosted.org/packages/7b/23/665296fce4f33488deec39a750ffd245cfc07aafb0e3ef37835f91775d14/mmh3-5.2.0-cp313-cp313-win32.whl", hash = "sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051", size = 40806, upload-time = "2025-07-29T07:42:48.166Z" }, + { url = "https://files.pythonhosted.org/packages/59/b0/92e7103f3b20646e255b699e2d0327ce53a3f250e44367a99dc8be0b7c7a/mmh3-5.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081", size = 41600, upload-time = "2025-07-29T07:42:49.371Z" }, + { url = "https://files.pythonhosted.org/packages/99/22/0b2bd679a84574647de538c5b07ccaa435dbccc37815067fe15b90fe8dad/mmh3-5.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b", size = 39349, upload-time = "2025-07-29T07:42:50.268Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ca/a20db059a8a47048aaf550da14a145b56e9c7386fb8280d3ce2962dcebf7/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078", size = 39209, upload-time = "2025-07-29T07:42:51.559Z" }, + { url = "https://files.pythonhosted.org/packages/98/dd/e5094799d55c7482d814b979a0fd608027d0af1b274bfb4c3ea3e950bfd5/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501", size = 39843, upload-time = "2025-07-29T07:42:52.536Z" }, + { url = "https://files.pythonhosted.org/packages/f4/6b/7844d7f832c85400e7cc89a1348e4e1fdd38c5a38415bb5726bbb8fcdb6c/mmh3-5.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b", size = 40648, upload-time = "2025-07-29T07:42:53.392Z" }, + { url = "https://files.pythonhosted.org/packages/1f/bf/71f791f48a21ff3190ba5225807cbe4f7223360e96862c376e6e3fb7efa7/mmh3-5.2.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770", size = 56164, upload-time = "2025-07-29T07:42:54.267Z" }, + { url = "https://files.pythonhosted.org/packages/70/1f/f87e3d34d83032b4f3f0f528c6d95a98290fcacf019da61343a49dccfd51/mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110", size = 40692, upload-time = "2025-07-29T07:42:55.234Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e2/db849eaed07117086f3452feca8c839d30d38b830ac59fe1ce65af8be5ad/mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647", size = 40068, upload-time = "2025-07-29T07:42:56.158Z" }, + { url = "https://files.pythonhosted.org/packages/df/6b/209af927207af77425b044e32f77f49105a0b05d82ff88af6971d8da4e19/mmh3-5.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63", size = 97367, upload-time = "2025-07-29T07:42:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e0/78adf4104c425606a9ce33fb351f790c76a6c2314969c4a517d1ffc92196/mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12", size = 103306, upload-time = "2025-07-29T07:42:58.522Z" }, + { url = "https://files.pythonhosted.org/packages/a3/79/c2b89f91b962658b890104745b1b6c9ce38d50a889f000b469b91eeb1b9e/mmh3-5.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22", size = 106312, upload-time = "2025-07-29T07:42:59.552Z" }, + { url = "https://files.pythonhosted.org/packages/4b/14/659d4095528b1a209be90934778c5ffe312177d51e365ddcbca2cac2ec7c/mmh3-5.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5", size = 113135, upload-time = "2025-07-29T07:43:00.745Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6f/cd7734a779389a8a467b5c89a48ff476d6f2576e78216a37551a97e9e42a/mmh3-5.2.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07", size = 120775, upload-time = "2025-07-29T07:43:02.124Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ca/8256e3b96944408940de3f9291d7e38a283b5761fe9614d4808fcf27bd62/mmh3-5.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935", size = 99178, upload-time = "2025-07-29T07:43:03.182Z" }, + { url = "https://files.pythonhosted.org/packages/8a/32/39e2b3cf06b6e2eb042c984dab8680841ac2a0d3ca6e0bea30db1f27b565/mmh3-5.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7", size = 98738, upload-time = "2025-07-29T07:43:04.207Z" }, + { url = "https://files.pythonhosted.org/packages/61/d3/7bbc8e0e8cf65ebbe1b893ffa0467b7ecd1bd07c3bbf6c9db4308ada22ec/mmh3-5.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5", size = 106510, upload-time = "2025-07-29T07:43:05.656Z" }, + { url = "https://files.pythonhosted.org/packages/10/99/b97e53724b52374e2f3859046f0eb2425192da356cb19784d64bc17bb1cf/mmh3-5.2.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384", size = 110053, upload-time = "2025-07-29T07:43:07.204Z" }, + { url = "https://files.pythonhosted.org/packages/ac/62/3688c7d975ed195155671df68788c83fed6f7909b6ec4951724c6860cb97/mmh3-5.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e", size = 97546, upload-time = "2025-07-29T07:43:08.226Z" }, + { url = "https://files.pythonhosted.org/packages/ca/3b/c6153250f03f71a8b7634cded82939546cdfba02e32f124ff51d52c6f991/mmh3-5.2.0-cp314-cp314-win32.whl", hash = "sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0", size = 41422, upload-time = "2025-07-29T07:43:09.216Z" }, + { url = "https://files.pythonhosted.org/packages/74/01/a27d98bab083a435c4c07e9d1d720d4c8a578bf4c270bae373760b1022be/mmh3-5.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b", size = 42135, upload-time = "2025-07-29T07:43:10.183Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c9/dbba5507e95429b8b380e2ba091eff5c20a70a59560934dff0ad8392b8c8/mmh3-5.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115", size = 39879, upload-time = "2025-07-29T07:43:11.106Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d1/c8c0ef839c17258b9de41b84f663574fabcf8ac2007b7416575e0f65ff6e/mmh3-5.2.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932", size = 57696, upload-time = "2025-07-29T07:43:11.989Z" }, + { url = "https://files.pythonhosted.org/packages/2f/55/95e2b9ff201e89f9fe37036037ab61a6c941942b25cdb7b6a9df9b931993/mmh3-5.2.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c", size = 41421, upload-time = "2025-07-29T07:43:13.269Z" }, + { url = "https://files.pythonhosted.org/packages/77/79/9be23ad0b7001a4b22752e7693be232428ecc0a35068a4ff5c2f14ef8b20/mmh3-5.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be", size = 40853, upload-time = "2025-07-29T07:43:14.888Z" }, + { url = "https://files.pythonhosted.org/packages/ac/1b/96b32058eda1c1dee8264900c37c359a7325c1f11f5ff14fd2be8e24eff9/mmh3-5.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb", size = 109694, upload-time = "2025-07-29T07:43:15.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6f/a2ae44cd7dad697b6dea48390cbc977b1e5ca58fda09628cbcb2275af064/mmh3-5.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65", size = 117438, upload-time = "2025-07-29T07:43:16.865Z" }, + { url = "https://files.pythonhosted.org/packages/a0/08/bfb75451c83f05224a28afeaf3950c7b793c0b71440d571f8e819cfb149a/mmh3-5.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991", size = 120409, upload-time = "2025-07-29T07:43:18.207Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ea/8b118b69b2ff8df568f742387d1a159bc654a0f78741b31437dd047ea28e/mmh3-5.2.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645", size = 125909, upload-time = "2025-07-29T07:43:19.39Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/168cc0b6a30650032e351a3b89b8a47382da541993a03af91e1ba2501234/mmh3-5.2.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3", size = 135331, upload-time = "2025-07-29T07:43:20.435Z" }, + { url = "https://files.pythonhosted.org/packages/31/05/e3a9849b1c18a7934c64e831492c99e67daebe84a8c2f2c39a7096a830e3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279", size = 110085, upload-time = "2025-07-29T07:43:21.92Z" }, + { url = "https://files.pythonhosted.org/packages/d9/d5/a96bcc306e3404601418b2a9a370baec92af84204528ba659fdfe34c242f/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513", size = 111195, upload-time = "2025-07-29T07:43:23.066Z" }, + { url = "https://files.pythonhosted.org/packages/af/29/0fd49801fec5bff37198684e0849b58e0dab3a2a68382a357cfffb0fafc3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db", size = 116919, upload-time = "2025-07-29T07:43:24.178Z" }, + { url = "https://files.pythonhosted.org/packages/2d/04/4f3c32b0a2ed762edca45d8b46568fc3668e34f00fb1e0a3b5451ec1281c/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667", size = 123160, upload-time = "2025-07-29T07:43:25.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/76/3d29eaa38821730633d6a240d36fa8ad2807e9dfd432c12e1a472ed211eb/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5", size = 110206, upload-time = "2025-07-29T07:43:26.699Z" }, + { url = "https://files.pythonhosted.org/packages/44/1c/ccf35892684d3a408202e296e56843743e0b4fb1629e59432ea88cdb3909/mmh3-5.2.0-cp314-cp314t-win32.whl", hash = "sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7", size = 41970, upload-time = "2025-07-29T07:43:27.666Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/b9e4f1e5adb5e21eb104588fcee2cd1eaa8308255173481427d5ecc4284e/mmh3-5.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d", size = 43063, upload-time = "2025-07-29T07:43:28.582Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fc/0e61d9a4e29c8679356795a40e48f647b4aad58d71bfc969f0f8f56fb912/mmh3-5.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9", size = 40455, upload-time = "2025-07-29T07:43:29.563Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "mypy" +version = "1.19.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "librt" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/b5/b58cdc25fadd424552804bf410855d52324183112aa004f0732c5f6324cf/mypy-1.19.0.tar.gz", hash = "sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528", size = 3579025, upload-time = "2025-11-28T15:49:01.26Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/7e/1afa8fb188b876abeaa14460dc4983f909aaacaa4bf5718c00b2c7e0b3d5/mypy-1.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d", size = 13207728, upload-time = "2025-11-28T15:46:26.463Z" }, + { url = "https://files.pythonhosted.org/packages/b2/13/f103d04962bcbefb1644f5ccb235998b32c337d6c13145ea390b9da47f3e/mypy-1.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760", size = 12202945, upload-time = "2025-11-28T15:48:49.143Z" }, + { url = "https://files.pythonhosted.org/packages/e4/93/a86a5608f74a22284a8ccea8592f6e270b61f95b8588951110ad797c2ddd/mypy-1.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6", size = 12718673, upload-time = "2025-11-28T15:47:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/3d/58/cf08fff9ced0423b858f2a7495001fda28dc058136818ee9dffc31534ea9/mypy-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2", size = 13608336, upload-time = "2025-11-28T15:48:32.625Z" }, + { url = "https://files.pythonhosted.org/packages/64/ed/9c509105c5a6d4b73bb08733102a3ea62c25bc02c51bca85e3134bf912d3/mypy-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431", size = 13833174, upload-time = "2025-11-28T15:45:48.091Z" }, + { url = "https://files.pythonhosted.org/packages/cd/71/01939b66e35c6f8cb3e6fdf0b657f0fd24de2f8ba5e523625c8e72328208/mypy-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018", size = 10112208, upload-time = "2025-11-28T15:46:41.702Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0d/a1357e6bb49e37ce26fcf7e3cc55679ce9f4ebee0cd8b6ee3a0e301a9210/mypy-1.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e", size = 13191993, upload-time = "2025-11-28T15:47:22.336Z" }, + { url = "https://files.pythonhosted.org/packages/5d/75/8e5d492a879ec4490e6ba664b5154e48c46c85b5ac9785792a5ec6a4d58f/mypy-1.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d", size = 12174411, upload-time = "2025-11-28T15:44:55.492Z" }, + { url = "https://files.pythonhosted.org/packages/71/31/ad5dcee9bfe226e8eaba777e9d9d251c292650130f0450a280aec3485370/mypy-1.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba", size = 12727751, upload-time = "2025-11-28T15:44:14.169Z" }, + { url = "https://files.pythonhosted.org/packages/77/06/b6b8994ce07405f6039701f4b66e9d23f499d0b41c6dd46ec28f96d57ec3/mypy-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364", size = 13593323, upload-time = "2025-11-28T15:46:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/68/b1/126e274484cccdf099a8e328d4fda1c7bdb98a5e888fa6010b00e1bbf330/mypy-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee", size = 13818032, upload-time = "2025-11-28T15:46:18.286Z" }, + { url = "https://files.pythonhosted.org/packages/f8/56/53a8f70f562dfc466c766469133a8a4909f6c0012d83993143f2a9d48d2d/mypy-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53", size = 10120644, upload-time = "2025-11-28T15:47:43.99Z" }, + { url = "https://files.pythonhosted.org/packages/b0/f4/7751f32f56916f7f8c229fe902cbdba3e4dd3f3ea9e8b872be97e7fc546d/mypy-1.19.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d", size = 13185236, upload-time = "2025-11-28T15:45:20.696Z" }, + { url = "https://files.pythonhosted.org/packages/35/31/871a9531f09e78e8d145032355890384f8a5b38c95a2c7732d226b93242e/mypy-1.19.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18", size = 12213902, upload-time = "2025-11-28T15:46:10.117Z" }, + { url = "https://files.pythonhosted.org/packages/58/b8/af221910dd40eeefa2077a59107e611550167b9994693fc5926a0b0f87c0/mypy-1.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7", size = 12738600, upload-time = "2025-11-28T15:44:22.521Z" }, + { url = "https://files.pythonhosted.org/packages/11/9f/c39e89a3e319c1d9c734dedec1183b2cc3aefbab066ec611619002abb932/mypy-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f", size = 13592639, upload-time = "2025-11-28T15:48:08.55Z" }, + { url = "https://files.pythonhosted.org/packages/97/6d/ffaf5f01f5e284d9033de1267e6c1b8f3783f2cf784465378a86122e884b/mypy-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835", size = 13799132, upload-time = "2025-11-28T15:47:06.032Z" }, + { url = "https://files.pythonhosted.org/packages/fe/b0/c33921e73aaa0106224e5a34822411bea38046188eb781637f5a5b07e269/mypy-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1", size = 10269832, upload-time = "2025-11-28T15:47:29.392Z" }, + { url = "https://files.pythonhosted.org/packages/09/0e/fe228ed5aeab470c6f4eb82481837fadb642a5aa95cc8215fd2214822c10/mypy-1.19.0-py3-none-any.whl", hash = "sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9", size = 2469714, upload-time = "2025-11-28T15:45:33.22Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nemoguardrails" +version = "0.19.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "annoy" }, + { name = "fastapi" }, + { name = "fastembed", marker = "python_full_version < '3.14'" }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "langchain" }, + { name = "langchain-community" }, + { name = "langchain-core" }, + { name = "lark" }, + { name = "nest-asyncio" }, + { name = "pandas" }, + { name = "prompt-toolkit" }, + { name = "protobuf" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "rich" }, + { name = "simpleeval" }, + { name = "starlette" }, + { name = "typer" }, + { name = "uvicorn" }, + { name = "watchdog" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/b2/95cf4aa45c8d32c012ecde508cf9a9526b4825b7d8e66128f4b16dfa8bf0/nemoguardrails-0.19.0-py3-none-any.whl", hash = "sha256:1a2de59a942b6d79a8e7c70a3fe92c154d76451db987a411e8e6b641f78f7c77", size = 11317602, upload-time = "2025-12-03T17:26:23.338Z" }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, +] + +[[package]] +name = "ollama" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/5a/652dac4b7affc2b37b95386f8ae78f22808af09d720689e3d7a86b6ed98e/ollama-0.6.1.tar.gz", hash = "sha256:478c67546836430034b415ed64fa890fd3d1ff91781a9d548b3325274e69d7c6", size = 51620, upload-time = "2025-11-13T23:02:17.416Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/4f/4a617ee93d8208d2bcf26b2d8b9402ceaed03e3853c754940e2290fed063/ollama-0.6.1-py3-none-any.whl", hash = "sha256:fc4c984b345735c5486faeee67d8a265214a31cbb828167782dc642ce0a2bf8c", size = 14354, upload-time = "2025-11-13T23:02:16.292Z" }, +] + +[[package]] +name = "omegaconf" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/48/6388f1bb9da707110532cb70ec4d2822858ddfb44f1cdf1233c20a80ea4b/omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7", size = 3298120, upload-time = "2022-12-08T20:59:22.753Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, +] + +[[package]] +name = "onnxruntime" +version = "1.23.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coloredlogs" }, + { name = "flatbuffers" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/9e/f748cd64161213adeef83d0cb16cb8ace1e62fa501033acdd9f9341fff57/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:b8f029a6b98d3cf5be564d52802bb50a8489ab73409fa9db0bf583eabb7c2321", size = 17195929, upload-time = "2025-10-22T03:47:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/91/9d/a81aafd899b900101988ead7fb14974c8a58695338ab6a0f3d6b0100f30b/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:218295a8acae83905f6f1aed8cacb8e3eb3bd7513a13fe4ba3b2664a19fc4a6b", size = 19157705, upload-time = "2025-10-22T03:46:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/4e40f2fba272a6698d62be2cd21ddc3675edfc1a4b9ddefcc4648f115315/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76ff670550dc23e58ea9bc53b5149b99a44e63b34b524f7b8547469aaa0dcb8c", size = 15226915, upload-time = "2025-10-22T03:46:27.773Z" }, + { url = "https://files.pythonhosted.org/packages/ef/88/9cc25d2bafe6bc0d4d3c1db3ade98196d5b355c0b273e6a5dc09c5d5d0d5/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f9b4ae77f8e3c9bee50c27bc1beede83f786fe1d52e99ac85aa8d65a01e9b77", size = 17382649, upload-time = "2025-10-22T03:47:02.782Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b4/569d298f9fc4d286c11c45e85d9ffa9e877af12ace98af8cab52396e8f46/onnxruntime-1.23.2-cp312-cp312-win_amd64.whl", hash = "sha256:25de5214923ce941a3523739d34a520aac30f21e631de53bba9174dc9c004435", size = 13470528, upload-time = "2025-10-22T03:47:28.106Z" }, + { url = "https://files.pythonhosted.org/packages/3d/41/fba0cabccecefe4a1b5fc8020c44febb334637f133acefc7ec492029dd2c/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:2ff531ad8496281b4297f32b83b01cdd719617e2351ffe0dba5684fb283afa1f", size = 17196337, upload-time = "2025-10-22T03:46:35.168Z" }, + { url = "https://files.pythonhosted.org/packages/fe/f9/2d49ca491c6a986acce9f1d1d5fc2099108958cc1710c28e89a032c9cfe9/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:162f4ca894ec3de1a6fd53589e511e06ecdc3ff646849b62a9da7489dee9ce95", size = 19157691, upload-time = "2025-10-22T03:46:43.518Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a1/428ee29c6eaf09a6f6be56f836213f104618fb35ac6cc586ff0f477263eb/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45d127d6e1e9b99d1ebeae9bcd8f98617a812f53f46699eafeb976275744826b", size = 15226898, upload-time = "2025-10-22T03:46:30.039Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2b/b57c8a2466a3126dbe0a792f56ad7290949b02f47b86216cd47d857e4b77/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8bace4e0d46480fbeeb7bbe1ffe1f080e6663a42d1086ff95c1551f2d39e7872", size = 17382518, upload-time = "2025-10-22T03:47:05.407Z" }, + { url = "https://files.pythonhosted.org/packages/4a/93/aba75358133b3a941d736816dd392f687e7eab77215a6e429879080b76b6/onnxruntime-1.23.2-cp313-cp313-win_amd64.whl", hash = "sha256:1f9cc0a55349c584f083c1c076e611a7c35d5b867d5d6e6d6c823bf821978088", size = 13470276, upload-time = "2025-10-22T03:47:31.193Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3d/6830fa61c69ca8e905f237001dbfc01689a4e4ab06147020a4518318881f/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d2385e774f46ac38f02b3a91a91e30263d41b2f1f4f26ae34805b2a9ddef466", size = 15229610, upload-time = "2025-10-22T03:46:32.239Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ca/862b1e7a639460f0ca25fd5b6135fb42cf9deea86d398a92e44dfda2279d/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2b9233c4947907fd1818d0e581c049c41ccc39b2856cc942ff6d26317cee145", size = 17394184, upload-time = "2025-10-22T03:47:08.127Z" }, +] + +[[package]] +name = "orjson" +version = "3.11.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/b8/333fdb27840f3bf04022d21b654a35f58e15407183aeb16f3b41aa053446/orjson-3.11.5.tar.gz", hash = "sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5", size = 5972347, upload-time = "2025-12-06T15:55:39.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a4/8052a029029b096a78955eadd68ab594ce2197e24ec50e6b6d2ab3f4e33b/orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d", size = 245347, upload-time = "2025-12-06T15:54:22.061Z" }, + { url = "https://files.pythonhosted.org/packages/64/67/574a7732bd9d9d79ac620c8790b4cfe0717a3d5a6eb2b539e6e8995e24a0/orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626", size = 129435, upload-time = "2025-12-06T15:54:23.615Z" }, + { url = "https://files.pythonhosted.org/packages/52/8d/544e77d7a29d90cf4d9eecd0ae801c688e7f3d1adfa2ebae5e1e94d38ab9/orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f", size = 132074, upload-time = "2025-12-06T15:54:24.694Z" }, + { url = "https://files.pythonhosted.org/packages/6e/57/b9f5b5b6fbff9c26f77e785baf56ae8460ef74acdb3eae4931c25b8f5ba9/orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85", size = 130520, upload-time = "2025-12-06T15:54:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6d/d34970bf9eb33f9ec7c979a262cad86076814859e54eb9a059a52f6dc13d/orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9", size = 136209, upload-time = "2025-12-06T15:54:27.264Z" }, + { url = "https://files.pythonhosted.org/packages/e7/39/bc373b63cc0e117a105ea12e57280f83ae52fdee426890d57412432d63b3/orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626", size = 139837, upload-time = "2025-12-06T15:54:28.75Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7c4818c8d7d324da220f4f1af55c343956003aa4d1ce1857bdc1d396ba69/orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa", size = 137307, upload-time = "2025-12-06T15:54:29.856Z" }, + { url = "https://files.pythonhosted.org/packages/46/bf/0993b5a056759ba65145effe3a79dd5a939d4a070eaa5da2ee3180fbb13f/orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477", size = 139020, upload-time = "2025-12-06T15:54:31.024Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/83a6c95db3039e504eda60fc388f9faedbb4f6472f5aba7084e06552d9aa/orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e", size = 141099, upload-time = "2025-12-06T15:54:32.196Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b4/24fdc024abfce31c2f6812973b0a693688037ece5dc64b7a60c1ce69e2f2/orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69", size = 413540, upload-time = "2025-12-06T15:54:33.361Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/01c0ec95d55ed0c11e4cae3e10427e479bba40c77312b63e1f9665e0737d/orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3", size = 151530, upload-time = "2025-12-06T15:54:34.6Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d4/f9ebc57182705bb4bbe63f5bbe14af43722a2533135e1d2fb7affa0c355d/orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca", size = 141863, upload-time = "2025-12-06T15:54:35.801Z" }, + { url = "https://files.pythonhosted.org/packages/0d/04/02102b8d19fdcb009d72d622bb5781e8f3fae1646bf3e18c53d1bc8115b5/orjson-3.11.5-cp312-cp312-win32.whl", hash = "sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98", size = 135255, upload-time = "2025-12-06T15:54:37.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fb/f05646c43d5450492cb387de5549f6de90a71001682c17882d9f66476af5/orjson-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875", size = 133252, upload-time = "2025-12-06T15:54:38.401Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/7b8c0b26ba18c793533ac1cd145e131e46fcf43952aa94c109b5b913c1f0/orjson-3.11.5-cp312-cp312-win_arm64.whl", hash = "sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe", size = 126777, upload-time = "2025-12-06T15:54:39.515Z" }, + { url = "https://files.pythonhosted.org/packages/10/43/61a77040ce59f1569edf38f0b9faadc90c8cf7e9bec2e0df51d0132c6bb7/orjson-3.11.5-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629", size = 245271, upload-time = "2025-12-06T15:54:40.878Z" }, + { url = "https://files.pythonhosted.org/packages/55/f9/0f79be617388227866d50edd2fd320cb8fb94dc1501184bb1620981a0aba/orjson-3.11.5-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3", size = 129422, upload-time = "2025-12-06T15:54:42.403Z" }, + { url = "https://files.pythonhosted.org/packages/77/42/f1bf1549b432d4a78bfa95735b79b5dac75b65b5bb815bba86ad406ead0a/orjson-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39", size = 132060, upload-time = "2025-12-06T15:54:43.531Z" }, + { url = "https://files.pythonhosted.org/packages/25/49/825aa6b929f1a6ed244c78acd7b22c1481fd7e5fda047dc8bf4c1a807eb6/orjson-3.11.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f", size = 130391, upload-time = "2025-12-06T15:54:45.059Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/de55391858b49e16e1aa8f0bbbb7e5997b7345d8e984a2dec3746d13065b/orjson-3.11.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51", size = 135964, upload-time = "2025-12-06T15:54:46.576Z" }, + { url = "https://files.pythonhosted.org/packages/1c/40/820bc63121d2d28818556a2d0a09384a9f0262407cf9fa305e091a8048df/orjson-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8", size = 139817, upload-time = "2025-12-06T15:54:48.084Z" }, + { url = "https://files.pythonhosted.org/packages/09/c7/3a445ca9a84a0d59d26365fd8898ff52bdfcdcb825bcc6519830371d2364/orjson-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706", size = 137336, upload-time = "2025-12-06T15:54:49.426Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b3/dc0d3771f2e5d1f13368f56b339c6782f955c6a20b50465a91acb79fe961/orjson-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f", size = 138993, upload-time = "2025-12-06T15:54:50.939Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a2/65267e959de6abe23444659b6e19c888f242bf7725ff927e2292776f6b89/orjson-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863", size = 141070, upload-time = "2025-12-06T15:54:52.414Z" }, + { url = "https://files.pythonhosted.org/packages/63/c9/da44a321b288727a322c6ab17e1754195708786a04f4f9d2220a5076a649/orjson-3.11.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228", size = 413505, upload-time = "2025-12-06T15:54:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/7f/17/68dc14fa7000eefb3d4d6d7326a190c99bb65e319f02747ef3ebf2452f12/orjson-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2", size = 151342, upload-time = "2025-12-06T15:54:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c5/ccee774b67225bed630a57478529fc026eda33d94fe4c0eac8fe58d4aa52/orjson-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05", size = 141823, upload-time = "2025-12-06T15:54:56.331Z" }, + { url = "https://files.pythonhosted.org/packages/67/80/5d00e4155d0cd7390ae2087130637671da713959bb558db9bac5e6f6b042/orjson-3.11.5-cp313-cp313-win32.whl", hash = "sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef", size = 135236, upload-time = "2025-12-06T15:54:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/95/fe/792cc06a84808dbdc20ac6eab6811c53091b42f8e51ecebf14b540e9cfe4/orjson-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583", size = 133167, upload-time = "2025-12-06T15:54:58.71Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/d158bd8b50e3b1cfdcf406a7e463f6ffe3f0d167b99634717acdaf5e299f/orjson-3.11.5-cp313-cp313-win_arm64.whl", hash = "sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287", size = 126712, upload-time = "2025-12-06T15:54:59.892Z" }, + { url = "https://files.pythonhosted.org/packages/c2/60/77d7b839e317ead7bb225d55bb50f7ea75f47afc489c81199befc5435b50/orjson-3.11.5-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0", size = 245252, upload-time = "2025-12-06T15:55:01.127Z" }, + { url = "https://files.pythonhosted.org/packages/f1/aa/d4639163b400f8044cef0fb9aa51b0337be0da3a27187a20d1166e742370/orjson-3.11.5-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81", size = 129419, upload-time = "2025-12-06T15:55:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/30/94/9eabf94f2e11c671111139edf5ec410d2f21e6feee717804f7e8872d883f/orjson-3.11.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f", size = 132050, upload-time = "2025-12-06T15:55:03.918Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c8/ca10f5c5322f341ea9a9f1097e140be17a88f88d1cfdd29df522970d9744/orjson-3.11.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e", size = 130370, upload-time = "2025-12-06T15:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/25/d4/e96824476d361ee2edd5c6290ceb8d7edf88d81148a6ce172fc00278ca7f/orjson-3.11.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7", size = 136012, upload-time = "2025-12-06T15:55:06.402Z" }, + { url = "https://files.pythonhosted.org/packages/85/8e/9bc3423308c425c588903f2d103cfcfe2539e07a25d6522900645a6f257f/orjson-3.11.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb", size = 139809, upload-time = "2025-12-06T15:55:07.656Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3c/b404e94e0b02a232b957c54643ce68d0268dacb67ac33ffdee24008c8b27/orjson-3.11.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4", size = 137332, upload-time = "2025-12-06T15:55:08.961Z" }, + { url = "https://files.pythonhosted.org/packages/51/30/cc2d69d5ce0ad9b84811cdf4a0cd5362ac27205a921da524ff42f26d65e0/orjson-3.11.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad", size = 138983, upload-time = "2025-12-06T15:55:10.595Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/de3223944a3e297d4707d2fe3b1ffb71437550e165eaf0ca8bbe43ccbcb1/orjson-3.11.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829", size = 141069, upload-time = "2025-12-06T15:55:11.832Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/81d5087ae74be33bcae3ff2d80f5ccaa4a8fedc6d39bf65a427a95b8977f/orjson-3.11.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac", size = 413491, upload-time = "2025-12-06T15:55:13.314Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6f/f6058c21e2fc1efaf918986dbc2da5cd38044f1a2d4b7b91ad17c4acf786/orjson-3.11.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d", size = 151375, upload-time = "2025-12-06T15:55:14.715Z" }, + { url = "https://files.pythonhosted.org/packages/54/92/c6921f17d45e110892899a7a563a925b2273d929959ce2ad89e2525b885b/orjson-3.11.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439", size = 141850, upload-time = "2025-12-06T15:55:15.94Z" }, + { url = "https://files.pythonhosted.org/packages/88/86/cdecb0140a05e1a477b81f24739da93b25070ee01ce7f7242f44a6437594/orjson-3.11.5-cp314-cp314-win32.whl", hash = "sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499", size = 135278, upload-time = "2025-12-06T15:55:17.202Z" }, + { url = "https://files.pythonhosted.org/packages/e4/97/b638d69b1e947d24f6109216997e38922d54dcdcdb1b11c18d7efd2d3c59/orjson-3.11.5-cp314-cp314-win_amd64.whl", hash = "sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310", size = 133170, upload-time = "2025-12-06T15:55:18.468Z" }, + { url = "https://files.pythonhosted.org/packages/8f/dd/f4fff4a6fe601b4f8f3ba3aa6da8ac33d17d124491a3b804c662a70e1636/orjson-3.11.5-cp314-cp314-win_arm64.whl", hash = "sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5", size = 126713, upload-time = "2025-12-06T15:55:19.738Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pillow" +version = "11.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, + { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, + { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, + { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, + { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, + { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, + { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, + { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, + { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, + { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, + { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, + { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, + { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, + { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, + { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, + { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, + { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, + { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, + { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/9b/6a4ffb4ed980519da959e1cf3122fc6cb41211daa58dbae1c73c0e519a37/pre_commit-4.5.0.tar.gz", hash = "sha256:dc5a065e932b19fc1d4c653c6939068fe54325af8e741e74e88db4d28a4dd66b", size = 198428, upload-time = "2025-11-22T21:02:42.304Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/c4/b2d28e9d2edf4f1713eb3c29307f1a63f3d67cf09bdda29715a36a68921a/pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1", size = 226429, upload-time = "2025-11-22T21:02:40.836Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "protobuf" +version = "6.33.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" }, + { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" }, + { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" }, + { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" }, +] + +[[package]] +name = "py-rust-stemmers" +version = "0.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/63/4fbc14810c32d2a884e2e94e406a7d5bf8eee53e1103f558433817230342/py_rust_stemmers-0.1.5.tar.gz", hash = "sha256:e9c310cfb5c2470d7c7c8a0484725965e7cab8b1237e106a0863d5741da3e1f7", size = 9388, upload-time = "2025-02-19T13:56:28.708Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e1/ea8ac92454a634b1bb1ee0a89c2f75a4e6afec15a8412527e9bbde8c6b7b/py_rust_stemmers-0.1.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:29772837126a28263bf54ecd1bc709dd569d15a94d5e861937813ce51e8a6df4", size = 286085, upload-time = "2025-02-19T13:55:23.871Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/fe1cc3d36a19c1ce39792b1ed151ddff5ee1d74c8801f0e93ff36e65f885/py_rust_stemmers-0.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d62410ada44a01e02974b85d45d82f4b4c511aae9121e5f3c1ba1d0bea9126b", size = 272021, upload-time = "2025-02-19T13:55:25.685Z" }, + { url = "https://files.pythonhosted.org/packages/0a/38/b8f94e5e886e7ab181361a0911a14fb923b0d05b414de85f427e773bf445/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b28ef729a4c83c7d9418be3c23c0372493fcccc67e86783ff04596ef8a208cdf", size = 310547, upload-time = "2025-02-19T13:55:26.891Z" }, + { url = "https://files.pythonhosted.org/packages/a9/08/62e97652d359b75335486f4da134a6f1c281f38bd3169ed6ecfb276448c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a979c3f4ff7ad94a0d4cf566ca7bfecebb59e66488cc158e64485cf0c9a7879f", size = 315237, upload-time = "2025-02-19T13:55:28.116Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b9/fc0278432f288d2be4ee4d5cc80fd8013d604506b9b0503e8b8cae4ba1c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c3593d895453fa06bf70a7b76d6f00d06def0f91fc253fe4260920650c5e078", size = 324419, upload-time = "2025-02-19T13:55:29.211Z" }, + { url = "https://files.pythonhosted.org/packages/6b/5b/74e96eaf622fe07e83c5c389d101540e305e25f76a6d0d6fb3d9e0506db8/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:96ccc7fd042ffc3f7f082f2223bb7082ed1423aa6b43d5d89ab23e321936c045", size = 324792, upload-time = "2025-02-19T13:55:30.948Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f7/b76816d7d67166e9313915ad486c21d9e7da0ac02703e14375bb1cb64b5a/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef18cfced2c9c676e0d7d172ba61c3fab2aa6969db64cc8f5ca33a7759efbefe", size = 488014, upload-time = "2025-02-19T13:55:32.066Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ed/7d9bed02f78d85527501f86a867cd5002d97deb791b9a6b1b45b00100010/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:541d4b5aa911381e3d37ec483abb6a2cf2351b4f16d5e8d77f9aa2722956662a", size = 575582, upload-time = "2025-02-19T13:55:34.005Z" }, + { url = "https://files.pythonhosted.org/packages/93/40/eafd1b33688e8e8ae946d1ef25c4dc93f5b685bd104b9c5573405d7e1d30/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ffd946a36e9ac17ca96821963663012e04bc0ee94d21e8b5ae034721070b436c", size = 493267, upload-time = "2025-02-19T13:55:35.294Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6a/15135b69e4fd28369433eb03264d201b1b0040ba534b05eddeb02a276684/py_rust_stemmers-0.1.5-cp312-none-win_amd64.whl", hash = "sha256:6ed61e1207f3b7428e99b5d00c055645c6415bb75033bff2d06394cbe035fd8e", size = 209395, upload-time = "2025-02-19T13:55:36.519Z" }, + { url = "https://files.pythonhosted.org/packages/80/b8/030036311ec25952bf3083b6c105be5dee052a71aa22d5fbeb857ebf8c1c/py_rust_stemmers-0.1.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:398b3a843a9cd4c5d09e726246bc36f66b3d05b0a937996814e91f47708f5db5", size = 286086, upload-time = "2025-02-19T13:55:37.581Z" }, + { url = "https://files.pythonhosted.org/packages/ed/be/0465dcb3a709ee243d464e89231e3da580017f34279d6304de291d65ccb0/py_rust_stemmers-0.1.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e308fc7687901f0c73603203869908f3156fa9c17c4ba010a7fcc98a7a1c5f2", size = 272019, upload-time = "2025-02-19T13:55:39.183Z" }, + { url = "https://files.pythonhosted.org/packages/ab/b6/76ca5b1f30cba36835938b5d9abee0c130c81833d51b9006264afdf8df3c/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9efc4da5e734bdd00612e7506de3d0c9b7abc4b89d192742a0569d0d1fe749", size = 310545, upload-time = "2025-02-19T13:55:40.339Z" }, + { url = "https://files.pythonhosted.org/packages/56/8f/5be87618cea2fe2e70e74115a20724802bfd06f11c7c43514b8288eb6514/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc2cc8d2b36bc05b8b06506199ac63d437360ae38caefd98cd19e479d35afd42", size = 315236, upload-time = "2025-02-19T13:55:41.55Z" }, + { url = "https://files.pythonhosted.org/packages/00/02/ea86a316aee0f0a9d1449ad4dbffff38f4cf0a9a31045168ae8b95d8bdf8/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a231dc6f0b2a5f12a080dfc7abd9e6a4ea0909290b10fd0a4620e5a0f52c3d17", size = 324419, upload-time = "2025-02-19T13:55:42.693Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fd/1612c22545dcc0abe2f30fc08f30a2332f2224dd536fa1508444a9ca0e39/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5845709d48afc8b29e248f42f92431155a3d8df9ba30418301c49c6072b181b0", size = 324794, upload-time = "2025-02-19T13:55:43.896Z" }, + { url = "https://files.pythonhosted.org/packages/66/18/8a547584d7edac9e7ac9c7bdc53228d6f751c0f70a317093a77c386c8ddc/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e48bfd5e3ce9d223bfb9e634dc1425cf93ee57eef6f56aa9a7120ada3990d4be", size = 488014, upload-time = "2025-02-19T13:55:45.088Z" }, + { url = "https://files.pythonhosted.org/packages/3b/87/4619c395b325e26048a6e28a365afed754614788ba1f49b2eefb07621a03/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:35d32f6e7bdf6fd90e981765e32293a8be74def807147dea9fdc1f65d6ce382f", size = 575582, upload-time = "2025-02-19T13:55:46.436Z" }, + { url = "https://files.pythonhosted.org/packages/98/6e/214f1a889142b7df6d716e7f3fea6c41e87bd6c29046aa57e175d452b104/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:191ea8bf922c984631ffa20bf02ef0ad7eec0465baeaed3852779e8f97c7e7a3", size = 493269, upload-time = "2025-02-19T13:55:49.057Z" }, + { url = "https://files.pythonhosted.org/packages/e1/b9/c5185df277576f995ae34418eb2b2ac12f30835412270f9e05c52face521/py_rust_stemmers-0.1.5-cp313-none-win_amd64.whl", hash = "sha256:e564c9efdbe7621704e222b53bac265b0e4fbea788f07c814094f0ec6b80adcf", size = 209397, upload-time = "2025-02-19T13:55:50.853Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pylint" +version = "4.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d2/b081da1a8930d00e3fc06352a1d449aaf815d4982319fab5d8cdb2e9ab35/pylint-4.0.4.tar.gz", hash = "sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2", size = 1571735, upload-time = "2025-11-30T13:29:04.315Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/92/d40f5d937517cc489ad848fc4414ecccc7592e4686b9071e09e64f5e378e/pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0", size = 536425, upload-time = "2025-11-30T13:29:02.53Z" }, +] + +[[package]] +name = "pyreadline3" +version = "3.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload-time = "2024-09-19T02:40:10.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, +] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "simpleeval" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/6f/15be211749430f52f2c8f0c69158a6fc961c03aac93fa28d44d1a6f5ebc7/simpleeval-1.0.3.tar.gz", hash = "sha256:67bbf246040ac3b57c29cf048657b9cf31d4e7b9d6659684daa08ca8f1e45829", size = 24358, upload-time = "2024-11-02T10:29:46.912Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e9/e58082fbb8cecbb6fb4133033c40cc50c248b1a331582be3a0f39138d65b/simpleeval-1.0.3-py3-none-any.whl", hash = "sha256:e3bdbb8c82c26297c9a153902d0fd1858a6c3774bf53ff4f134788c3f2035c38", size = 15762, upload-time = "2024-11-02T10:29:45.706Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.45" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/c7/1900b56ce19bff1c26f39a4ce427faec7716c81ac792bfac8b6a9f3dca93/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f", size = 3333760, upload-time = "2025-12-09T22:11:02.66Z" }, + { url = "https://files.pythonhosted.org/packages/0a/93/3be94d96bb442d0d9a60e55a6bb6e0958dd3457751c6f8502e56ef95fed0/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d", size = 3348268, upload-time = "2025-12-09T22:13:49.054Z" }, + { url = "https://files.pythonhosted.org/packages/48/4b/f88ded696e61513595e4a9778f9d3f2bf7332cce4eb0c7cedaabddd6687b/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4", size = 3278144, upload-time = "2025-12-09T22:11:04.14Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6a/310ecb5657221f3e1bd5288ed83aa554923fb5da48d760a9f7622afeb065/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6", size = 3313907, upload-time = "2025-12-09T22:13:50.598Z" }, + { url = "https://files.pythonhosted.org/packages/5c/39/69c0b4051079addd57c84a5bfb34920d87456dd4c90cf7ee0df6efafc8ff/sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953", size = 2112182, upload-time = "2025-12-09T21:39:30.824Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4e/510db49dd89fc3a6e994bee51848c94c48c4a00dc905e8d0133c251f41a7/sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1", size = 2139200, upload-time = "2025-12-09T21:39:32.321Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, + { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, + { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, + { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, + { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tenacity" +version = "9.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" }, +] + +[[package]] +name = "tokenizers" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/46/fb6854cec3278fbfa4a75b50232c77622bc517ac886156e6afbfa4d8fc6e/tokenizers-0.22.1.tar.gz", hash = "sha256:61de6522785310a309b3407bac22d99c4db5dba349935e99e4d15ea2226af2d9", size = 363123, upload-time = "2025-09-19T09:49:23.424Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/33/f4b2d94ada7ab297328fc671fed209368ddb82f965ec2224eb1892674c3a/tokenizers-0.22.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59fdb013df17455e5f950b4b834a7b3ee2e0271e6378ccb33aa74d178b513c73", size = 3069318, upload-time = "2025-09-19T09:49:11.848Z" }, + { url = "https://files.pythonhosted.org/packages/1c/58/2aa8c874d02b974990e89ff95826a4852a8b2a273c7d1b4411cdd45a4565/tokenizers-0.22.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d4e484f7b0827021ac5f9f71d4794aaef62b979ab7608593da22b1d2e3c4edc", size = 2926478, upload-time = "2025-09-19T09:49:09.759Z" }, + { url = "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a", size = 3256994, upload-time = "2025-09-19T09:48:56.701Z" }, + { url = "https://files.pythonhosted.org/packages/71/0b/fbfecf42f67d9b7b80fde4aabb2b3110a97fac6585c9470b5bff103a80cb/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38201f15cdb1f8a6843e6563e6e79f4abd053394992b9bbdf5213ea3469b4ae7", size = 3153141, upload-time = "2025-09-19T09:48:59.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/a9/b38f4e74e0817af8f8ef925507c63c6ae8171e3c4cb2d5d4624bf58fca69/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1cbe5454c9a15df1b3443c726063d930c16f047a3cc724b9e6e1a91140e5a21", size = 3508049, upload-time = "2025-09-19T09:49:05.868Z" }, + { url = "https://files.pythonhosted.org/packages/d2/48/dd2b3dac46bb9134a88e35d72e1aa4869579eacc1a27238f1577270773ff/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7d094ae6312d69cc2a872b54b91b309f4f6fbce871ef28eb27b52a98e4d0214", size = 3710730, upload-time = "2025-09-19T09:49:01.832Z" }, + { url = "https://files.pythonhosted.org/packages/93/0e/ccabc8d16ae4ba84a55d41345207c1e2ea88784651a5a487547d80851398/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afd7594a56656ace95cdd6df4cca2e4059d294c5cfb1679c57824b605556cb2f", size = 3412560, upload-time = "2025-09-19T09:49:03.867Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c6/dc3a0db5a6766416c32c034286d7c2d406da1f498e4de04ab1b8959edd00/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ef6063d7a84994129732b47e7915e8710f27f99f3a3260b8a38fc7ccd083f4", size = 3250221, upload-time = "2025-09-19T09:49:07.664Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a6/2c8486eef79671601ff57b093889a345dd3d576713ef047776015dc66de7/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba0a64f450b9ef412c98f6bcd2a50c6df6e2443b560024a09fa6a03189726879", size = 9345569, upload-time = "2025-09-19T09:49:14.214Z" }, + { url = "https://files.pythonhosted.org/packages/6b/16/32ce667f14c35537f5f605fe9bea3e415ea1b0a646389d2295ec348d5657/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:331d6d149fa9c7d632cde4490fb8bbb12337fa3a0232e77892be656464f4b446", size = 9271599, upload-time = "2025-09-19T09:49:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/51/7c/a5f7898a3f6baa3fc2685c705e04c98c1094c523051c805cdd9306b8f87e/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:607989f2ea68a46cb1dfbaf3e3aabdf3f21d8748312dbeb6263d1b3b66c5010a", size = 9533862, upload-time = "2025-09-19T09:49:19.146Z" }, + { url = "https://files.pythonhosted.org/packages/36/65/7e75caea90bc73c1dd8d40438adf1a7bc26af3b8d0a6705ea190462506e1/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a0f307d490295717726598ef6fa4f24af9d484809223bbc253b201c740a06390", size = 9681250, upload-time = "2025-09-19T09:49:21.501Z" }, + { url = "https://files.pythonhosted.org/packages/30/2c/959dddef581b46e6209da82df3b78471e96260e2bc463f89d23b1bf0e52a/tokenizers-0.22.1-cp39-abi3-win32.whl", hash = "sha256:b5120eed1442765cd90b903bb6cfef781fd8fe64e34ccaecbae4c619b7b12a82", size = 2472003, upload-time = "2025-09-19T09:49:27.089Z" }, + { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dc/74/1789779d91f1961fa9438e9a8710cdae6bd138c80d7303996933d117264a/typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78", size = 13825, upload-time = "2023-05-24T20:25:47.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/f3/107a22063bf27bdccf2024833d3445f4eea42b2e598abfbd46f6a63b6cb0/typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", size = 8827, upload-time = "2023-05-24T20:25:45.287Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] + +[[package]] +name = "uuid-utils" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/0e/512fb221e4970c2f75ca9dae412d320b7d9ddc9f2b15e04ea8e44710396c/uuid_utils-0.12.0.tar.gz", hash = "sha256:252bd3d311b5d6b7f5dfce7a5857e27bb4458f222586bb439463231e5a9cbd64", size = 20889, upload-time = "2025-12-01T17:29:55.494Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/43/de5cd49a57b6293b911b6a9a62fc03e55db9f964da7d5882d9edbee1e9d2/uuid_utils-0.12.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3b9b30707659292f207b98f294b0e081f6d77e1fbc760ba5b41331a39045f514", size = 603197, upload-time = "2025-12-01T17:29:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/02/fa/5fd1d8c9234e44f0c223910808cde0de43bb69f7df1349e49b1afa7f2baa/uuid_utils-0.12.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:add3d820c7ec14ed37317375bea30249699c5d08ff4ae4dbee9fc9bce3bfbf65", size = 305168, upload-time = "2025-12-01T17:29:31.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c6/8633ac9942bf9dc97a897b5154e5dcffa58816ec4dd780b3b12b559ff05c/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8fce83ecb3b16af29c7809669056c4b6e7cc912cab8c6d07361645de12dd79", size = 340580, upload-time = "2025-12-01T17:29:32.362Z" }, + { url = "https://files.pythonhosted.org/packages/f3/88/8a61307b04b4da1c576373003e6d857a04dade52ab035151d62cb84d5cb5/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec921769afcb905035d785582b0791d02304a7850fbd6ce924c1a8976380dfc6", size = 346771, upload-time = "2025-12-01T17:29:33.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fb/aab2dcf94b991e62aa167457c7825b9b01055b884b888af926562864398c/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f3b060330f5899a92d5c723547dc6a95adef42433e9748f14c66859a7396664", size = 474781, upload-time = "2025-12-01T17:29:35.237Z" }, + { url = "https://files.pythonhosted.org/packages/5a/7a/dbd5e49c91d6c86dba57158bbfa0e559e1ddf377bb46dcfd58aea4f0d567/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:908dfef7f0bfcf98d406e5dc570c25d2f2473e49b376de41792b6e96c1d5d291", size = 343685, upload-time = "2025-12-01T17:29:36.677Z" }, + { url = "https://files.pythonhosted.org/packages/1a/19/8c4b1d9f450159733b8be421a4e1fb03533709b80ed3546800102d085572/uuid_utils-0.12.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c6a24148926bd0ca63e8a2dabf4cc9dc329a62325b3ad6578ecd60fbf926506", size = 366482, upload-time = "2025-12-01T17:29:37.979Z" }, + { url = "https://files.pythonhosted.org/packages/82/43/c79a6e45687647f80a159c8ba34346f287b065452cc419d07d2212d38420/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:64a91e632669f059ef605f1771d28490b1d310c26198e46f754e8846dddf12f4", size = 523132, upload-time = "2025-12-01T17:29:39.293Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a2/b2d75a621260a40c438aa88593827dfea596d18316520a99e839f7a5fb9d/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:93c082212470bb4603ca3975916c205a9d7ef1443c0acde8fbd1e0f5b36673c7", size = 614218, upload-time = "2025-12-01T17:29:40.315Z" }, + { url = "https://files.pythonhosted.org/packages/13/6b/ba071101626edd5a6dabf8525c9a1537ff3d885dbc210540574a03901fef/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:431b1fb7283ba974811b22abd365f2726f8f821ab33f0f715be389640e18d039", size = 546241, upload-time = "2025-12-01T17:29:41.656Z" }, + { url = "https://files.pythonhosted.org/packages/01/12/9a942b81c0923268e6d85bf98d8f0a61fcbcd5e432fef94fdf4ce2ef8748/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd7838c40149100299fa37cbd8bab5ee382372e8e65a148002a37d380df7c8", size = 511842, upload-time = "2025-12-01T17:29:43.107Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a7/c326f5163dd48b79368b87d8a05f5da4668dd228a3f5ca9d79d5fee2fc40/uuid_utils-0.12.0-cp39-abi3-win32.whl", hash = "sha256:487f17c0fee6cbc1d8b90fe811874174a9b1b5683bf2251549e302906a50fed3", size = 179088, upload-time = "2025-12-01T17:29:44.492Z" }, + { url = "https://files.pythonhosted.org/packages/38/92/41c8734dd97213ee1d5ae435cf4499705dc4f2751e3b957fd12376f61784/uuid_utils-0.12.0-cp39-abi3-win_amd64.whl", hash = "sha256:9598e7c9da40357ae8fffc5d6938b1a7017f09a1acbcc95e14af8c65d48c655a", size = 183003, upload-time = "2025-12-01T17:29:45.47Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/52ab0359618987331a1f739af837d26168a4b16281c9c3ab46519940c628/uuid_utils-0.12.0-cp39-abi3-win_arm64.whl", hash = "sha256:c9bea7c5b2aa6f57937ebebeee4d4ef2baad10f86f1b97b58a3f6f34c14b4e84", size = 182975, upload-time = "2025-12-01T17:29:46.444Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.35.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, +] + +[[package]] +name = "win32-setctime" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "zstandard" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, + { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, + { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" }, + { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" }, + { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" }, + { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" }, + { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" }, + { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, + { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" }, + { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" }, + { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" }, + { url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload-time = "2025-09-14T22:17:31.044Z" }, + { url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload-time = "2025-09-14T22:17:32.711Z" }, + { url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload-time = "2025-09-14T22:17:34.41Z" }, + { url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload-time = "2025-09-14T22:17:36.084Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload-time = "2025-09-14T22:17:37.891Z" }, + { url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload-time = "2025-09-14T22:17:40.206Z" }, + { url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload-time = "2025-09-14T22:17:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload-time = "2025-09-14T22:17:43.577Z" }, + { url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload-time = "2025-09-14T22:17:45.271Z" }, + { url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload-time = "2025-09-14T22:17:47.08Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload-time = "2025-09-14T22:17:48.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" }, + { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" }, + { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" }, + { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" }, + { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" }, + { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" }, +] From ce3b021b82e4fe7f3b55c445f954e82e7ae46b48 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 02:01:09 +0000 Subject: [PATCH 021/108] Add first working version of the input query guardlines --- services/llm-proxy/cfg/main.yaml | 7 + services/llm-proxy/guardrails_cfg/config.yml | 18 ++ services/llm-proxy/guardrails_cfg/prompts.yml | 20 +++ services/llm-proxy/main.py | 168 ++++++++++++++++++ .../src/llm_proxy/chat_llm_service.py | 46 +++++ .../src/llm_proxy/guardrails_service.py | 46 +++++ 6 files changed, 305 insertions(+) create mode 100644 services/llm-proxy/cfg/main.yaml create mode 100644 services/llm-proxy/guardrails_cfg/config.yml create mode 100644 services/llm-proxy/guardrails_cfg/prompts.yml create mode 100644 services/llm-proxy/main.py create mode 100644 services/llm-proxy/src/llm_proxy/chat_llm_service.py create mode 100644 services/llm-proxy/src/llm_proxy/guardrails_service.py diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml new file mode 100644 index 0000000..f4c9387 --- /dev/null +++ b/services/llm-proxy/cfg/main.yaml @@ -0,0 +1,7 @@ +persist_data_path: data/ +guardrails_cfg_path: guardrails_cfg/ +server_host: 0.0.0.0 +server_port: 8080 +chat_llm_cfg: + model: llama3.2:1b + url: http://localhost:11435 \ No newline at end of file diff --git a/services/llm-proxy/guardrails_cfg/config.yml b/services/llm-proxy/guardrails_cfg/config.yml new file mode 100644 index 0000000..1bfd6f3 --- /dev/null +++ b/services/llm-proxy/guardrails_cfg/config.yml @@ -0,0 +1,18 @@ + +models: + - type: self_check_input + engine: ollama + model: llama3.2:1b + parameters: + base_url: http://localhost:11435 + + - type: main + engine: ollama + model: llama3.2:1b + parameters: + base_url: http://localhost:11435 + +rails: + input: + flows: + - self check input \ No newline at end of file diff --git a/services/llm-proxy/guardrails_cfg/prompts.yml b/services/llm-proxy/guardrails_cfg/prompts.yml new file mode 100644 index 0000000..7a8d5e9 --- /dev/null +++ b/services/llm-proxy/guardrails_cfg/prompts.yml @@ -0,0 +1,20 @@ +prompts: + - task: self_check_input + messages: + - type: system + content: | + You are an AI assistant tasked with evaluating user instructions that come together with the context of the conversation. + Block it if the input is harmful/explicit/abusive/requests illegal or dangerous instructions. + Otherwise do not block it. + + Analyze the instruction carefully. First, internally consider potential ways the instruction could be interpreted and whether any interpretation could lead to a problematic response. + Pay heed to satements that are ambiguous when analyzed in isolation, but in context of the conversation history could be held as inapropriate. + Then, conclude with a simple "yes" or "no" answer. + Respond with only "yes" or "no". + - type: user + content: | + + "{{ user_input }}" + + + Would this instruction lead to a problematic response (yes/no)? \ No newline at end of file diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py new file mode 100644 index 0000000..b4fcede --- /dev/null +++ b/services/llm-proxy/main.py @@ -0,0 +1,168 @@ +""""Starts the backend server for the entrypoint service.""" +import logging +import multiprocessing +import os +from datetime import datetime +from typing import Any +from typing import Dict +from typing import List +from contextlib import asynccontextmanager + + +import hydra +import omegaconf +import uvicorn +import pydantic +import fastapi +from fastapi.responses import StreamingResponse + +from llm_proxy import (guardrails_service, chat_llm_service) + + +def _logger() -> logging.Logger: + return logging.getLogger() + + +guard_service: guardrails_service.GuardrailsService | None = None # pylint: disable=invalid-name +llm_service: chat_llm_service.ChatLLMService | None = None # pylint: disable=invalid-name + + +@asynccontextmanager +async def lifespan(_): # type: ignore + """Sets up global contexts used by the server workers.""" + + cfg = omegaconf.OmegaConf.load('cfg/main.yaml') + + global guard_service, llm_service # pylint: disable=global-statement + + guard_service = guardrails_service.GuardrailsService( + config_path=cfg.guardrails_cfg_path + ) + llm_service = chat_llm_service.ChatLLMService( + ollama_model=cfg.chat_llm_cfg.model, + ollama_url=cfg.chat_llm_cfg.url + ) + + yield + + +app = fastapi.FastAPI(lifespan=lifespan) + + +@app.get('/ping') +async def read_ping() -> Dict[str, str]: + """Health check endpoint.""" + return {'message': 'Service is running'} + + +class RequestStreamChatResponse(pydantic.BaseModel): + """Request to return the LLM response for a given query and retrieved context.""" + user_message: str + chat_history: List[Dict[str, Any]] + context_docs: List[Dict[str, Any]] + + +@app.post('/stream_chat_response') +async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingResponse: + """Streams chat response for the user query based on the provided context.""" + + assert llm_service is not None + + return StreamingResponse(llm_service.stream_chat_response(request.user_message, + chat_history=request.chat_history), + media_type='application/json') + + +class RequestShouldAllowQuery(pydantic.BaseModel): + """Request to tell whether a given query is eligible for processing.""" + user_message: str + chat_history: List[Dict[str, Any]] + + +class ResponseShouldAllowQuery(pydantic.BaseModel): + """Responds with the information whether a given query should be processed.""" + allowed: bool + + +@app.post('/should_allow_query') +async def should_allow_query(request: RequestShouldAllowQuery) -> ResponseShouldAllowQuery: + """Tells whether a given user query passes the guardrails.""" + + assert guard_service is not None + + is_allowed = await guard_service.should_process_query(query=request.user_message, + chat_history=request.chat_history) + + return ResponseShouldAllowQuery(allowed=is_allowed) + + +@hydra.main(version_base=None, config_path='cfg', config_name='main') +def main(cfg: omegaconf.DictConfig) -> None: + """Initializes and serves the web app.""" + + os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) + + logging.config.dictConfig({ + 'version': 1, + 'loggers': { + 'root': { + 'level': 'NOTSET', + 'handlers': ['console', 'file'], + 'propagate': True + }, + 'httpx': { + 'level': 'WARNING', + 'propagate': False + }, + 'httpcore': { + 'level': 'WARNING', + 'propagate': False + }, + 'nemoguardrails': { + 'level': 'WARNING', + 'propagate': False + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'level': 'INFO', + 'formatter': 'default' + }, + 'file': { + 'class': 'logging.handlers.RotatingFileHandler', + 'level': 'DEBUG', + 'formatter': 'default', + 'filename': os.path.join(cfg.persist_data_path, + 'log', + f'{datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}.log'), + 'maxBytes': 5_000_000, + 'backupCount': 5, + 'encoding': 'utf-8', + } + }, + 'formatters': { + 'default': { + 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + } + } + }) + + # n_workers = (multiprocessing.cpu_count() * 2) + 1 + n_workers = 1 + + _logger().info('Starting server on %s:%d with %d workers.', + cfg.server_host, cfg.server_port, n_workers) + + uvicorn.run('main:app', + host=cfg.server_host, + port=cfg.server_port, + workers=n_workers, + log_level='info', + access_log=True, + limit_concurrency=1000, + timeout_keep_alive=5) + + +if __name__ == '__main__': + main() # pylint: disable=no-value-for-parameter diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py new file mode 100644 index 0000000..299b9c9 --- /dev/null +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -0,0 +1,46 @@ +"""Contains service responsible for connecting with self-hosted LLM.""" + +import logging +from typing import Dict +from typing import List +from typing import Any +from typing import AsyncIterator +import json + +import ollama + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class ChatLLMService: + """Establishes connection with self-hosted LLM and handles requests to it.""" + + def __init__(self, + ollama_model: str, + ollama_url: str): + + self._ollama_model = ollama_model + self._ollama_url = ollama_url + + self._client = ollama.AsyncClient(ollama_url) + + _logger().debug('Created ChatLLMService for model: %s and url: %s.', + ollama_model, ollama_url) + + async def stream_chat_response(self, + user_query: str, + chat_history: List[Dict[str, Any]]) -> AsyncIterator[bytes]: + """Streams, chunk by chunk, LLM response for a given query and chat history.""" + + messages = chat_history + [ + {'role': 'user', 'content': user_query} + ] + + async for chunk in await self._client.chat(model=self._ollama_model, + messages=messages, + stream=True): + + chunk_struct = {'content': chunk} + yield json.dumps(chunk_struct).encode('utf-8') diff --git a/services/llm-proxy/src/llm_proxy/guardrails_service.py b/services/llm-proxy/src/llm_proxy/guardrails_service.py new file mode 100644 index 0000000..cc7f12b --- /dev/null +++ b/services/llm-proxy/src/llm_proxy/guardrails_service.py @@ -0,0 +1,46 @@ +"""Contains the implementation of a guardrails service performing query sanitization.""" + +from typing import Dict +from typing import Any +from typing import List +import logging + +import nemoguardrails + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class GuardrailsService: + """Checks whether LLM inputs and outputs should be allowed to pass. + + The queries and responses are checked according to a given configuration that specifies llm + endpoints and guardrails. + """ + + def __init__(self, + config_path: str): + + config = nemoguardrails.RailsConfig.from_path(config_path) + + self._guardrails_client = nemoguardrails.LLMRails(config) + + _logger().debug('Created GuardrailsService from config path: %s.', config_path) + + async def should_process_query(self, + query: str, + chat_history: List[Dict[str, Any]]) -> bool: + """Tells whether a user's chat message (query + chat history) passes the guardrails.""" + + _logger().debug('Matching the query \'%s\' and conversation %s against input guardrails...', + query, chat_history) + + llm_result = await self._guardrails_client.generate_async( + messages=chat_history + [{"role": "user", "content": query}], + options={"rails": ["input"], }, + ) + + _logger().debug('Received response: %s', llm_result) + + return llm_result.response[0]['content'].strip().lower() == 'yes' From ae29bb5700efb351f99db17db2ffbe36fa4de37c Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 10:32:00 +0000 Subject: [PATCH 022/108] Replace separate guard querying with wrapping the main llm --- services/llm-proxy/cfg/main.yaml | 4 +- services/llm-proxy/guardrails_cfg/prompts.yml | 7 ++- services/llm-proxy/main.py | 41 ++--------------- .../src/llm_proxy/chat_llm_service.py | 25 +++++----- .../src/llm_proxy/guardrails_service.py | 46 ------------------- 5 files changed, 22 insertions(+), 101 deletions(-) delete mode 100644 services/llm-proxy/src/llm_proxy/guardrails_service.py diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index f4c9387..6cf2b7a 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -2,6 +2,4 @@ persist_data_path: data/ guardrails_cfg_path: guardrails_cfg/ server_host: 0.0.0.0 server_port: 8080 -chat_llm_cfg: - model: llama3.2:1b - url: http://localhost:11435 \ No newline at end of file +n_server_workers: 1 \ No newline at end of file diff --git a/services/llm-proxy/guardrails_cfg/prompts.yml b/services/llm-proxy/guardrails_cfg/prompts.yml index 7a8d5e9..79cb94d 100644 --- a/services/llm-proxy/guardrails_cfg/prompts.yml +++ b/services/llm-proxy/guardrails_cfg/prompts.yml @@ -3,18 +3,17 @@ prompts: messages: - type: system content: | - You are an AI assistant tasked with evaluating user instructions that come together with the context of the conversation. + You are an AI assistant tasked with evaluating user instructions. Block it if the input is harmful/explicit/abusive/requests illegal or dangerous instructions. Otherwise do not block it. Analyze the instruction carefully. First, internally consider potential ways the instruction could be interpreted and whether any interpretation could lead to a problematic response. - Pay heed to satements that are ambiguous when analyzed in isolation, but in context of the conversation history could be held as inapropriate. Then, conclude with a simple "yes" or "no" answer. Respond with only "yes" or "no". - type: user content: | - + "{{ user_input }}" - + Would this instruction lead to a problematic response (yes/no)? \ No newline at end of file diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index b4fcede..7b78002 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -16,14 +16,13 @@ import fastapi from fastapi.responses import StreamingResponse -from llm_proxy import (guardrails_service, chat_llm_service) +from llm_proxy import chat_llm_service def _logger() -> logging.Logger: return logging.getLogger() -guard_service: guardrails_service.GuardrailsService | None = None # pylint: disable=invalid-name llm_service: chat_llm_service.ChatLLMService | None = None # pylint: disable=invalid-name @@ -33,14 +32,10 @@ async def lifespan(_): # type: ignore cfg = omegaconf.OmegaConf.load('cfg/main.yaml') - global guard_service, llm_service # pylint: disable=global-statement + global llm_service # pylint: disable=global-statement - guard_service = guardrails_service.GuardrailsService( - config_path=cfg.guardrails_cfg_path - ) llm_service = chat_llm_service.ChatLLMService( - ollama_model=cfg.chat_llm_cfg.model, - ollama_url=cfg.chat_llm_cfg.url + guardrails_cfg_path=cfg.guardrails_cfg_path ) yield @@ -73,29 +68,6 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR media_type='application/json') -class RequestShouldAllowQuery(pydantic.BaseModel): - """Request to tell whether a given query is eligible for processing.""" - user_message: str - chat_history: List[Dict[str, Any]] - - -class ResponseShouldAllowQuery(pydantic.BaseModel): - """Responds with the information whether a given query should be processed.""" - allowed: bool - - -@app.post('/should_allow_query') -async def should_allow_query(request: RequestShouldAllowQuery) -> ResponseShouldAllowQuery: - """Tells whether a given user query passes the guardrails.""" - - assert guard_service is not None - - is_allowed = await guard_service.should_process_query(query=request.user_message, - chat_history=request.chat_history) - - return ResponseShouldAllowQuery(allowed=is_allowed) - - @hydra.main(version_base=None, config_path='cfg', config_name='main') def main(cfg: omegaconf.DictConfig) -> None: """Initializes and serves the web app.""" @@ -148,16 +120,13 @@ def main(cfg: omegaconf.DictConfig) -> None: } }) - # n_workers = (multiprocessing.cpu_count() * 2) + 1 - n_workers = 1 - _logger().info('Starting server on %s:%d with %d workers.', - cfg.server_host, cfg.server_port, n_workers) + cfg.server_host, cfg.server_port, cfg.n_server_workers) uvicorn.run('main:app', host=cfg.server_host, port=cfg.server_port, - workers=n_workers, + workers=cfg.n_server_workers, log_level='info', access_log=True, limit_concurrency=1000, diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 299b9c9..ef44660 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -7,7 +7,7 @@ from typing import AsyncIterator import json -import ollama +import nemoguardrails def _logger() -> logging.Logger: @@ -18,29 +18,30 @@ class ChatLLMService: """Establishes connection with self-hosted LLM and handles requests to it.""" def __init__(self, - ollama_model: str, - ollama_url: str): + guardrails_cfg_path: str): - self._ollama_model = ollama_model - self._ollama_url = ollama_url + config = nemoguardrails.RailsConfig.from_path(guardrails_cfg_path) - self._client = ollama.AsyncClient(ollama_url) + self._rails_client = nemoguardrails.LLMRails(config) - _logger().debug('Created ChatLLMService for model: %s and url: %s.', - ollama_model, ollama_url) + _logger().debug('Created GuardrailsService from config: %s.', config) async def stream_chat_response(self, user_query: str, chat_history: List[Dict[str, Any]]) -> AsyncIterator[bytes]: - """Streams, chunk by chunk, LLM response for a given query and chat history.""" + """Streams, chunk by chunk, LLM response for a given query and chat history. + + The input is checkes according to the guardrails specification. + """ + + _logger().debug('Streaming llm response for query \'%s\' and conversation %s...', + user_query, chat_history) messages = chat_history + [ {'role': 'user', 'content': user_query} ] - async for chunk in await self._client.chat(model=self._ollama_model, - messages=messages, - stream=True): + async for chunk in self._rails_client.stream_async(messages=messages): chunk_struct = {'content': chunk} yield json.dumps(chunk_struct).encode('utf-8') diff --git a/services/llm-proxy/src/llm_proxy/guardrails_service.py b/services/llm-proxy/src/llm_proxy/guardrails_service.py deleted file mode 100644 index cc7f12b..0000000 --- a/services/llm-proxy/src/llm_proxy/guardrails_service.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Contains the implementation of a guardrails service performing query sanitization.""" - -from typing import Dict -from typing import Any -from typing import List -import logging - -import nemoguardrails - - -def _logger() -> logging.Logger: - return logging.getLogger(__name__) - - -class GuardrailsService: - """Checks whether LLM inputs and outputs should be allowed to pass. - - The queries and responses are checked according to a given configuration that specifies llm - endpoints and guardrails. - """ - - def __init__(self, - config_path: str): - - config = nemoguardrails.RailsConfig.from_path(config_path) - - self._guardrails_client = nemoguardrails.LLMRails(config) - - _logger().debug('Created GuardrailsService from config path: %s.', config_path) - - async def should_process_query(self, - query: str, - chat_history: List[Dict[str, Any]]) -> bool: - """Tells whether a user's chat message (query + chat history) passes the guardrails.""" - - _logger().debug('Matching the query \'%s\' and conversation %s against input guardrails...', - query, chat_history) - - llm_result = await self._guardrails_client.generate_async( - messages=chat_history + [{"role": "user", "content": query}], - options={"rails": ["input"], }, - ) - - _logger().debug('Received response: %s', llm_result) - - return llm_result.response[0]['content'].strip().lower() == 'yes' From 7615eac023083424c25747a48cc6c4c7b43281ef Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 15 Dec 2025 17:00:42 +0000 Subject: [PATCH 023/108] Enhance setting up docker-compose clusters Added just recipe Made ollama server port passable as argument to run container --- docker-compose.yml | 7 ++++--- justfile | 10 ++-------- services/llm-generator/llm-generator.Dockerfile | 2 -- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0efe6dd..68626b5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,8 +6,7 @@ services: build: context: services/llm-generator/ dockerfile: llm-generator.Dockerfile - args: - - gpus=all + container_name: llm-generator ports: - 11434:11434 @@ -16,7 +15,9 @@ services: networks: - rag-net environment: - - LLM_GENERATOR_MODEL=llama3.2:1b + - LLM_GENERATOR_MODEL=llama3.1:8b + - OLLAMA_DEBUG=2 + - OLLAMA_HOST=0.0.0.0:11434 networks: diff --git a/justfile b/justfile index a0b6b12..aa849e6 100644 --- a/justfile +++ b/justfile @@ -5,11 +5,5 @@ set shell := ["bash", "-c"] -# Run static repository checks -run-pre-commit: - uv run pre-commit run --all-files - -# Set up environment and install dependencies -setup-dev: - uv venv - uv sync --project . --extra dev +up-infrastructure: + docker compose up --build \ No newline at end of file diff --git a/services/llm-generator/llm-generator.Dockerfile b/services/llm-generator/llm-generator.Dockerfile index d981930..6ac427d 100644 --- a/services/llm-generator/llm-generator.Dockerfile +++ b/services/llm-generator/llm-generator.Dockerfile @@ -1,7 +1,5 @@ FROM ollama/ollama:latest -ENV OLLAMA_HOST="0.0.0.0:11434" - COPY ./entrypoint.sh /root/entrypoint.sh RUN chmod +x /root/entrypoint.sh From 0b7a531a09eda13d362db8d2878425a7f880668d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 17 Dec 2025 14:08:51 +0000 Subject: [PATCH 024/108] Run pre-commit --- .devcontainer/llm-proxy/Dockerfile | 2 +- services/llm-proxy/cfg/main.yaml | 3 ++- services/llm-proxy/guardrails_cfg/config.yml | 6 +++--- services/llm-proxy/guardrails_cfg/prompts.yml | 3 ++- services/llm-proxy/main.py | 9 +++------ services/llm-proxy/src/llm_proxy/chat_llm_service.py | 7 +++---- 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/.devcontainer/llm-proxy/Dockerfile b/.devcontainer/llm-proxy/Dockerfile index 75e0cd6..67dd575 100644 --- a/.devcontainer/llm-proxy/Dockerfile +++ b/.devcontainer/llm-proxy/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12-slim +FROM python:3.12 SHELL ["/bin/bash", "-c"] ENV DEBIAN_FRONTEND=noninteractive diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index 6cf2b7a..4c65730 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -1,5 +1,6 @@ +--- persist_data_path: data/ guardrails_cfg_path: guardrails_cfg/ server_host: 0.0.0.0 server_port: 8080 -n_server_workers: 1 \ No newline at end of file +n_server_workers: 1 diff --git a/services/llm-proxy/guardrails_cfg/config.yml b/services/llm-proxy/guardrails_cfg/config.yml index 1bfd6f3..48be5fd 100644 --- a/services/llm-proxy/guardrails_cfg/config.yml +++ b/services/llm-proxy/guardrails_cfg/config.yml @@ -1,11 +1,11 @@ - +--- models: - type: self_check_input engine: ollama model: llama3.2:1b parameters: base_url: http://localhost:11435 - + - type: main engine: ollama model: llama3.2:1b @@ -15,4 +15,4 @@ models: rails: input: flows: - - self check input \ No newline at end of file + - self check input diff --git a/services/llm-proxy/guardrails_cfg/prompts.yml b/services/llm-proxy/guardrails_cfg/prompts.yml index 79cb94d..2e2a48a 100644 --- a/services/llm-proxy/guardrails_cfg/prompts.yml +++ b/services/llm-proxy/guardrails_cfg/prompts.yml @@ -1,3 +1,4 @@ +--- prompts: - task: self_check_input messages: @@ -16,4 +17,4 @@ prompts: "{{ user_input }}" - Would this instruction lead to a problematic response (yes/no)? \ No newline at end of file + Would this instruction lead to a problematic response (yes/no)? diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 7b78002..3581f8d 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -1,21 +1,18 @@ """"Starts the backend server for the entrypoint service.""" import logging -import multiprocessing import os +from contextlib import asynccontextmanager from datetime import datetime from typing import Any from typing import Dict from typing import List -from contextlib import asynccontextmanager - +import fastapi import hydra import omegaconf -import uvicorn import pydantic -import fastapi +import uvicorn from fastapi.responses import StreamingResponse - from llm_proxy import chat_llm_service diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index ef44660..0e73a7e 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -1,11 +1,10 @@ """Contains service responsible for connecting with self-hosted LLM.""" - +import json import logging -from typing import Dict -from typing import List from typing import Any from typing import AsyncIterator -import json +from typing import Dict +from typing import List import nemoguardrails From 7750a3ffbb3ad9536b722d0bbb22d77f6a077802 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 17 Dec 2025 14:21:09 +0000 Subject: [PATCH 025/108] Move logging setup to separate function --- services/llm-proxy/main.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 3581f8d..ff732c7 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -65,11 +65,7 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR media_type='application/json') -@hydra.main(version_base=None, config_path='cfg', config_name='main') -def main(cfg: omegaconf.DictConfig) -> None: - """Initializes and serves the web app.""" - - os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) +def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: logging.config.dictConfig({ 'version': 1, @@ -102,7 +98,7 @@ def main(cfg: omegaconf.DictConfig) -> None: 'class': 'logging.handlers.RotatingFileHandler', 'level': 'DEBUG', 'formatter': 'default', - 'filename': os.path.join(cfg.persist_data_path, + 'filename': os.path.join(script_cfg.persist_data_path, 'log', f'{datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}.log'), 'maxBytes': 5_000_000, @@ -117,6 +113,15 @@ def main(cfg: omegaconf.DictConfig) -> None: } }) + +@hydra.main(version_base=None, config_path='cfg', config_name='main') +def main(cfg: omegaconf.DictConfig) -> None: + """Initializes and serves the web app.""" + + os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) + + _configure_logging(cfg) + _logger().info('Starting server on %s:%d with %d workers.', cfg.server_host, cfg.server_port, cfg.n_server_workers) From 47088ace67c1019774a4d5edfc7142ecba56aa68 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 17 Dec 2025 14:56:21 +0000 Subject: [PATCH 026/108] Disable noisy 3rd party debug logs --- services/llm-proxy/main.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index ff732c7..da578c4 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -17,7 +17,7 @@ def _logger() -> logging.Logger: - return logging.getLogger() + return logging.getLogger('llm_proxy') llm_service: chat_llm_service.ChatLLMService | None = None # pylint: disable=invalid-name @@ -71,20 +71,12 @@ def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: 'version': 1, 'loggers': { 'root': { - 'level': 'NOTSET', - 'handlers': ['console', 'file'], - 'propagate': True - }, - 'httpx': { 'level': 'WARNING', - 'propagate': False + 'handlers': ['console', 'file'] }, - 'httpcore': { - 'level': 'WARNING', - 'propagate': False - }, - 'nemoguardrails': { - 'level': 'WARNING', + 'llm_proxy': { + 'level': 'DEBUG', + 'handlers': ['console', 'file'], 'propagate': False } }, From 79055a0141a467751e2d6b3883f9eb9345d55319 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 17 Dec 2025 14:56:57 +0000 Subject: [PATCH 027/108] Enable passing dynamic server configuration to uvicorn workers via env vars --- services/llm-proxy/main.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index da578c4..682687d 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -6,6 +6,8 @@ from typing import Any from typing import Dict from typing import List +import json +import sys import fastapi import hydra @@ -27,8 +29,17 @@ def _logger() -> logging.Logger: async def lifespan(_): # type: ignore """Sets up global contexts used by the server workers.""" - cfg = omegaconf.OmegaConf.load('cfg/main.yaml') + cfg_serialized = os.environ.get('LLM_PROXY_SERVER_CFG', None) + if cfg_serialized is None: + _logger().critical('Failed to load llm-proxy server config from environment variable.') + sys.exit(1) + + cfg = omegaconf.OmegaConf.create(json.loads(cfg_serialized)) + + # The llm_service is designed to be used by the endpoint handlers as a global service. It is + # not assigned in the `main` function because the uvicorn workers don't call it, as opposed to + # the `lifespan` callback. global llm_service # pylint: disable=global-statement llm_service = chat_llm_service.ChatLLMService( @@ -117,6 +128,9 @@ def main(cfg: omegaconf.DictConfig) -> None: _logger().info('Starting server on %s:%d with %d workers.', cfg.server_host, cfg.server_port, cfg.n_server_workers) + cfg_serialized = json.dumps(omegaconf.OmegaConf.to_container(cfg)) + os.environ['LLM_PROXY_SERVER_CFG'] = cfg_serialized + uvicorn.run('main:app', host=cfg.server_host, port=cfg.server_port, From 3b104d7f5c0a93afd261d24fe61db7dfe2bc5b8a Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 22 Dec 2025 11:28:38 +0100 Subject: [PATCH 028/108] Replace llm-generator with generalized llm endpoint and rename llm-generator service with main-llm-responder --- docker-compose.yml | 10 +++++----- .../{llm-generator => main-llm-responder}/.gitignore | 0 services/{llm-generator => llm-endpoint}/entrypoint.sh | 0 .../llm-endpoint.Dockerfile} | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename persist_dir/{llm-generator => main-llm-responder}/.gitignore (100%) rename services/{llm-generator => llm-endpoint}/entrypoint.sh (100%) rename services/{llm-generator/llm-generator.Dockerfile => llm-endpoint/llm-endpoint.Dockerfile} (100%) diff --git a/docker-compose.yml b/docker-compose.yml index 68626b5..1fc4543 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,16 +2,16 @@ version: '3.9' services: - llm-generator: + main-llm-responder: build: - context: services/llm-generator/ - dockerfile: llm-generator.Dockerfile + context: services/llm-endpoint/ + dockerfile: llm-endpoint.Dockerfile - container_name: llm-generator + container_name: main-llm-responder ports: - 11434:11434 volumes: - - ./persist_dir/llm-generator:/root/.ollama + - ./persist_dir/main-llm-responder:/root/.ollama networks: - rag-net environment: diff --git a/persist_dir/llm-generator/.gitignore b/persist_dir/main-llm-responder/.gitignore similarity index 100% rename from persist_dir/llm-generator/.gitignore rename to persist_dir/main-llm-responder/.gitignore diff --git a/services/llm-generator/entrypoint.sh b/services/llm-endpoint/entrypoint.sh similarity index 100% rename from services/llm-generator/entrypoint.sh rename to services/llm-endpoint/entrypoint.sh diff --git a/services/llm-generator/llm-generator.Dockerfile b/services/llm-endpoint/llm-endpoint.Dockerfile similarity index 100% rename from services/llm-generator/llm-generator.Dockerfile rename to services/llm-endpoint/llm-endpoint.Dockerfile From 767774d98954e1cdf135cf929d5a5d5110afcf02 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 22 Dec 2025 11:29:37 +0100 Subject: [PATCH 029/108] Introduce llm-guard service --- docker-compose.yml | 17 +++++++++++++++++ persist_dir/guard-llm/.gitignore | 2 ++ 2 files changed, 19 insertions(+) create mode 100644 persist_dir/guard-llm/.gitignore diff --git a/docker-compose.yml b/docker-compose.yml index 1fc4543..27d7997 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,23 @@ services: - LLM_GENERATOR_MODEL=llama3.1:8b - OLLAMA_DEBUG=2 - OLLAMA_HOST=0.0.0.0:11434 + + guard-llm: + build: + context: services/llm-endpoint/ + dockerfile: llm-endpoint.Dockerfile + + container_name: guard-llm + ports: + - 11435:11435 + volumes: + - ./persist_dir/guard-llm:/root/.ollama + networks: + - rag-net + environment: + - LLM_GENERATOR_MODEL=llama-guard3:1b + - OLLAMA_DEBUG=2 + - OLLAMA_HOST=0.0.0.0:11435 networks: diff --git a/persist_dir/guard-llm/.gitignore b/persist_dir/guard-llm/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/guard-llm/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file From 6fd5fba4c9dbbf879a426453344c503b1c42dc06 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 22 Dec 2025 11:30:16 +0100 Subject: [PATCH 030/108] Make used llm rails a passable argument --- services/llm-proxy/cfg/main.yaml | 1 + services/llm-proxy/justfile | 4 ++-- services/llm-proxy/main.py | 5 ++++- services/llm-proxy/src/llm_proxy/chat_llm_service.py | 10 +++++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index 4c65730..c979449 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -4,3 +4,4 @@ guardrails_cfg_path: guardrails_cfg/ server_host: 0.0.0.0 server_port: 8080 n_server_workers: 1 +llm_rails_used: [input] \ No newline at end of file diff --git a/services/llm-proxy/justfile b/services/llm-proxy/justfile index ada239d..f8eae92 100644 --- a/services/llm-proxy/justfile +++ b/services/llm-proxy/justfile @@ -11,8 +11,8 @@ setup-environment: uv venv uv pip install -e .[dev] -run-server: - uv run python main.py +run-server *args: + uv run python main.py "$@" # Runs static checks using global pre-commit configuration. run-precommit: diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 682687d..a01b6f5 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -43,7 +43,8 @@ async def lifespan(_): # type: ignore global llm_service # pylint: disable=global-statement llm_service = chat_llm_service.ChatLLMService( - guardrails_cfg_path=cfg.guardrails_cfg_path + guardrails_cfg_path=cfg.guardrails_cfg_path, + used_llm_rails=cfg.llm_rails_used ) yield @@ -121,6 +122,8 @@ def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: def main(cfg: omegaconf.DictConfig) -> None: """Initializes and serves the web app.""" + _logger().info('Script configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) + os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) _configure_logging(cfg) diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 0e73a7e..a3bf6f0 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -17,10 +17,12 @@ class ChatLLMService: """Establishes connection with self-hosted LLM and handles requests to it.""" def __init__(self, - guardrails_cfg_path: str): + guardrails_cfg_path: str, + used_llm_rails: List[str]): - config = nemoguardrails.RailsConfig.from_path(guardrails_cfg_path) + self._used_llm_rails = used_llm_rails + config = nemoguardrails.RailsConfig.from_path(guardrails_cfg_path) self._rails_client = nemoguardrails.LLMRails(config) _logger().debug('Created GuardrailsService from config: %s.', config) @@ -40,7 +42,9 @@ async def stream_chat_response(self, {'role': 'user', 'content': user_query} ] - async for chunk in self._rails_client.stream_async(messages=messages): + async for chunk in self._rails_client.stream_async( + messages=messages, + options={'rails': self._used_llm_rails}): chunk_struct = {'content': chunk} yield json.dumps(chunk_struct).encode('utf-8') From 8abaf7e6de8f4c9a7471497df13d11fedec92200 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 2 Jan 2026 11:03:20 +0000 Subject: [PATCH 031/108] Update llm endpoints configuration Fix exposing correct port Minor fixes --- docker-compose.yml | 6 +++++- services/llm-endpoint/entrypoint.sh | 2 +- services/llm-endpoint/llm-endpoint.Dockerfile | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 27d7997..b996cf4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,6 +6,8 @@ services: build: context: services/llm-endpoint/ dockerfile: llm-endpoint.Dockerfile + args: + EXPOSED_PORT: 11434 container_name: main-llm-responder ports: @@ -23,6 +25,8 @@ services: build: context: services/llm-endpoint/ dockerfile: llm-endpoint.Dockerfile + args: + EXPOSED_PORT: 11435 container_name: guard-llm ports: @@ -32,7 +36,7 @@ services: networks: - rag-net environment: - - LLM_GENERATOR_MODEL=llama-guard3:1b + - LLM_GENERATOR_MODEL=llama3.1:8b - OLLAMA_DEBUG=2 - OLLAMA_HOST=0.0.0.0:11435 diff --git a/services/llm-endpoint/entrypoint.sh b/services/llm-endpoint/entrypoint.sh index 580f5d1..1a6d7ad 100644 --- a/services/llm-endpoint/entrypoint.sh +++ b/services/llm-endpoint/entrypoint.sh @@ -7,6 +7,6 @@ echo "Waiting for ollama server to start..." sleep 5 echo "Pulling the model..." -ollama pull "${LLM_GENERATOR_MODEL}" +ollama run "${LLM_GENERATOR_MODEL}" wait $SERVER_PID \ No newline at end of file diff --git a/services/llm-endpoint/llm-endpoint.Dockerfile b/services/llm-endpoint/llm-endpoint.Dockerfile index 6ac427d..873cc31 100644 --- a/services/llm-endpoint/llm-endpoint.Dockerfile +++ b/services/llm-endpoint/llm-endpoint.Dockerfile @@ -5,6 +5,6 @@ RUN chmod +x /root/entrypoint.sh WORKDIR /root -EXPOSE 11434 +EXPOSE ${EXPOSED_PORT} ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file From 1933520fe3936e05caaa29644bee1f2635ebde9b Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 2 Jan 2026 11:04:40 +0000 Subject: [PATCH 032/108] Remove passing optional used rails --- services/llm-proxy/cfg/main.yaml | 3 +-- services/llm-proxy/main.py | 3 +-- services/llm-proxy/src/llm_proxy/chat_llm_service.py | 5 +---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index c979449..d31c71a 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -3,5 +3,4 @@ persist_data_path: data/ guardrails_cfg_path: guardrails_cfg/ server_host: 0.0.0.0 server_port: 8080 -n_server_workers: 1 -llm_rails_used: [input] \ No newline at end of file +n_server_workers: 1 \ No newline at end of file diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index a01b6f5..f598864 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -43,8 +43,7 @@ async def lifespan(_): # type: ignore global llm_service # pylint: disable=global-statement llm_service = chat_llm_service.ChatLLMService( - guardrails_cfg_path=cfg.guardrails_cfg_path, - used_llm_rails=cfg.llm_rails_used + guardrails_cfg_path=cfg.guardrails_cfg_path ) yield diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index a3bf6f0..4ced605 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -17,10 +17,7 @@ class ChatLLMService: """Establishes connection with self-hosted LLM and handles requests to it.""" def __init__(self, - guardrails_cfg_path: str, - used_llm_rails: List[str]): - - self._used_llm_rails = used_llm_rails + guardrails_cfg_path: str): config = nemoguardrails.RailsConfig.from_path(guardrails_cfg_path) self._rails_client = nemoguardrails.LLMRails(config) From 1746860d8a899dcb0bcf63df7302cbc4b96965e6 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 2 Jan 2026 11:05:42 +0000 Subject: [PATCH 033/108] Implement custom input guardrails Added conversation check flow Added handling of blocked requests and llm call errors --- services/llm-proxy/guardrails_cfg/actions.py | 94 +++++++++++++++++++ services/llm-proxy/guardrails_cfg/config.yml | 16 ++-- services/llm-proxy/guardrails_cfg/prompts.yml | 36 ++++--- .../rails/chat_conversation_check.co | 22 +++++ .../src/llm_proxy/chat_llm_service.py | 29 +++++- 5 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 services/llm-proxy/guardrails_cfg/actions.py create mode 100644 services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co diff --git a/services/llm-proxy/guardrails_cfg/actions.py b/services/llm-proxy/guardrails_cfg/actions.py new file mode 100644 index 0000000..6cc6fad --- /dev/null +++ b/services/llm-proxy/guardrails_cfg/actions.py @@ -0,0 +1,94 @@ +"""Contains custom actions triggered by the safety guardrails.""" +# mypy: ignore-errors + +import logging +from typing import Optional, Any + +from langchain_core.language_models import BaseLLM + +from nemoguardrails import RailsConfig +from nemoguardrails.actions.actions import action +from nemoguardrails.actions.llm.utils import llm_call +from nemoguardrails.context import llm_call_info_var +from nemoguardrails.llm.taskmanager import LLMTaskManager +from nemoguardrails.logging.explain import LLMCallInfo +from nemoguardrails.actions.llm.utils import LLMCallException + + +def _logger() -> logging.Logger: + return logging.getLogger('llm_proxy._nemoguardrails.actions') + + +def _construct_conversation_fragment(context: dict[str, Any]) -> str: + """Constructs a conversation fragment from the llm call context.""" + + conversation = [] + + if 'last_user_message' in context: + conversation.append(f"User: {context['last_user_message']}") + + if 'last_bot_message' in context: + conversation.append(f"Assistant: {context['last_bot_message']}") + + if 'user_message' in context: + conversation.append(f"User: {context['user_message']}") + + return "\n".join(conversation) + + +@action(is_system_action=False) +async def chat_conversation_check(llm_task_manager: LLMTaskManager, + context: Optional[dict] = None, + llm: Optional[BaseLLM] = None, + config: Optional[RailsConfig] = None + ) -> dict[str, Any]: + """Checks the user input together with the chat history to determine if it is safe to answer.""" + + _MAX_TOKENS = 3 + + conversation_fragment = _construct_conversation_fragment(context or {}) + + if conversation_fragment: + + prompt = llm_task_manager.render_task_prompt( + task='chat_conversation_check', + context={ + "conversation_fragment": conversation_fragment, + }, + ) + stop = llm_task_manager.get_stop_tokens(task='chat_conversation_check') + max_tokens = llm_task_manager.get_max_tokens(task='chat_conversation_check') + max_tokens = max_tokens or _MAX_TOKENS + + llm_call_info_var.set(LLMCallInfo(task='chat_conversation_check')) + + try: + response = await llm_call( + llm, + prompt, + stop=stop, + llm_params={ + "temperature": config.lowest_temperature, + "max_tokens": max_tokens + }, + ) + + _logger().debug("chat_conversation_check response is `%s` for prompt:\n%s", + response, prompt) + + result = llm_task_manager.parse_task_output('chat_conversation_check', + output=response, + forced_output_parser="is_content_safe") + + if result[0]: + return {'result': True, 'reason': None} + + else: + return { + 'result': False, + 'reason': ''} + + except LLMCallException as e: + _logger().error('LLM call failed during chat_conversation_check: %s', e) + + return {'result': False, 'reason': ''} diff --git a/services/llm-proxy/guardrails_cfg/config.yml b/services/llm-proxy/guardrails_cfg/config.yml index 48be5fd..ae559d3 100644 --- a/services/llm-proxy/guardrails_cfg/config.yml +++ b/services/llm-proxy/guardrails_cfg/config.yml @@ -1,18 +1,22 @@ --- models: - - type: self_check_input + - type: main engine: ollama - model: llama3.2:1b + model: llama3.1:8b parameters: - base_url: http://localhost:11435 + base_url: http://localhost:11434 - - type: main + - type: chat_conversation_check engine: ollama - model: llama3.2:1b + model: llama3.1:8b parameters: base_url: http://localhost:11435 + raw: True rails: input: flows: - - self check input + - chat conversation check + +actions: + module: actions diff --git a/services/llm-proxy/guardrails_cfg/prompts.yml b/services/llm-proxy/guardrails_cfg/prompts.yml index 2e2a48a..eec583e 100644 --- a/services/llm-proxy/guardrails_cfg/prompts.yml +++ b/services/llm-proxy/guardrails_cfg/prompts.yml @@ -1,20 +1,30 @@ --- prompts: - - task: self_check_input + - task: chat_conversation_check messages: - - type: system + - type: user content: | - You are an AI assistant tasked with evaluating user instructions. - Block it if the input is harmful/explicit/abusive/requests illegal or dangerous instructions. - Otherwise do not block it. + You are an AI assistant tasked with evaluating user-assistant conversations. + Block it if the conversation contains unsafe content according ONLY to the following policy: + + + S1. Insults and jokes targeted at the AGH University of Krakow. + + + Analyze the excerpt of the conversation carefully. The response should contain "safe" or "unsafe" only. If the content is not referred to by any of the policy statements, respond with "safe". + + + {{ conversation_fragment }} + + + Does this conversation fragment contain content that should be blocked (safe/unsafe)? - Analyze the instruction carefully. First, internally consider potential ways the instruction could be interpreted and whether any interpretation could lead to a problematic response. - Then, conclude with a simple "yes" or "no" answer. - Respond with only "yes" or "no". + - task: general + messages: + - type: system + content: | + You are a helpful AI assistant. You will be presented with a conversation history between a user and an assistant. Your task is to continue the conversation by providing a helpful and relevant response to the user's latest message. - type: user content: | - - "{{ user_input }}" - - - Would this instruction lead to a problematic response (yes/no)? + {{ history | user_assistant_sequence }} + Assistant: \ No newline at end of file diff --git a/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co b/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co new file mode 100644 index 0000000..a61a4e6 --- /dev/null +++ b/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co @@ -0,0 +1,22 @@ +define bot refuse llm call error + "" + +define bot refuse input violation + "" + +define flow chat conversation check + + $result = execute chat_conversation_check + + if not $result.allowed + if $result.reason == "" + bot refuse llm call error + stop + + if $result.reason == "" + bot refuse input violation + stop + + + + diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 4ced605..88b994c 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -41,7 +41,34 @@ async def stream_chat_response(self, async for chunk in self._rails_client.stream_async( messages=messages, - options={'rails': self._used_llm_rails}): + options={'log': {'activated_rails': True}, + 'llm_output': True}): + + if self._is_chunk_error(chunk): + yield json.dumps({'error': self._get_error_message(chunk)}).encode('utf-8') + return chunk_struct = {'content': chunk} + yield json.dumps(chunk_struct).encode('utf-8') + + def _is_chunk_error(self, chunk: str) -> bool: + """Tells whether the given chunk indicates an error. + + An error chunk does not contain the expected vocabulary and indicates that either + the guardrails blocked the response or the LLM call failed. + """ + + return chunk in ('', '') + + def _get_error_message(self, chunk: str) -> str: + """Returns human-readable error message for the given error chunk.""" + + if chunk == '': + return 'The input was blocked by safety guardrails.' + + if chunk == '': + return 'The model call failed.' + + _logger().error('Unknown error chunk: %s', chunk) + return 'An unknown error occurred.' From 9bfa9d9ffba342dfb63051933c8a5a873847c532 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 2 Jan 2026 11:08:53 +0000 Subject: [PATCH 034/108] Update devcontainer extensions list --- .devcontainer/base/devcontainer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/base/devcontainer.json b/.devcontainer/base/devcontainer.json index 46414d9..99f7c2a 100644 --- a/.devcontainer/base/devcontainer.json +++ b/.devcontainer/base/devcontainer.json @@ -36,7 +36,9 @@ "ms-python.pylint", "ms-python.autopep8", "tamasfe.even-better-toml", - "VisualStudioExptTeam.vscodeintellicode" + "VisualStudioExptTeam.vscodeintellicode", + "mhutchie.git-graph", + "eamodio.gitlens" ] } } From 2f54ea1ccb0192178240083ee050bf81d3a0cc10 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 4 Jan 2026 15:15:32 +0000 Subject: [PATCH 035/108] Remove nemoguardrails configuration --- services/llm-proxy/guardrails_cfg/actions.py | 94 ------------------- services/llm-proxy/guardrails_cfg/config.yml | 22 ----- services/llm-proxy/guardrails_cfg/prompts.yml | 30 ------ .../rails/chat_conversation_check.co | 22 ----- 4 files changed, 168 deletions(-) delete mode 100644 services/llm-proxy/guardrails_cfg/actions.py delete mode 100644 services/llm-proxy/guardrails_cfg/config.yml delete mode 100644 services/llm-proxy/guardrails_cfg/prompts.yml delete mode 100644 services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co diff --git a/services/llm-proxy/guardrails_cfg/actions.py b/services/llm-proxy/guardrails_cfg/actions.py deleted file mode 100644 index 6cc6fad..0000000 --- a/services/llm-proxy/guardrails_cfg/actions.py +++ /dev/null @@ -1,94 +0,0 @@ -"""Contains custom actions triggered by the safety guardrails.""" -# mypy: ignore-errors - -import logging -from typing import Optional, Any - -from langchain_core.language_models import BaseLLM - -from nemoguardrails import RailsConfig -from nemoguardrails.actions.actions import action -from nemoguardrails.actions.llm.utils import llm_call -from nemoguardrails.context import llm_call_info_var -from nemoguardrails.llm.taskmanager import LLMTaskManager -from nemoguardrails.logging.explain import LLMCallInfo -from nemoguardrails.actions.llm.utils import LLMCallException - - -def _logger() -> logging.Logger: - return logging.getLogger('llm_proxy._nemoguardrails.actions') - - -def _construct_conversation_fragment(context: dict[str, Any]) -> str: - """Constructs a conversation fragment from the llm call context.""" - - conversation = [] - - if 'last_user_message' in context: - conversation.append(f"User: {context['last_user_message']}") - - if 'last_bot_message' in context: - conversation.append(f"Assistant: {context['last_bot_message']}") - - if 'user_message' in context: - conversation.append(f"User: {context['user_message']}") - - return "\n".join(conversation) - - -@action(is_system_action=False) -async def chat_conversation_check(llm_task_manager: LLMTaskManager, - context: Optional[dict] = None, - llm: Optional[BaseLLM] = None, - config: Optional[RailsConfig] = None - ) -> dict[str, Any]: - """Checks the user input together with the chat history to determine if it is safe to answer.""" - - _MAX_TOKENS = 3 - - conversation_fragment = _construct_conversation_fragment(context or {}) - - if conversation_fragment: - - prompt = llm_task_manager.render_task_prompt( - task='chat_conversation_check', - context={ - "conversation_fragment": conversation_fragment, - }, - ) - stop = llm_task_manager.get_stop_tokens(task='chat_conversation_check') - max_tokens = llm_task_manager.get_max_tokens(task='chat_conversation_check') - max_tokens = max_tokens or _MAX_TOKENS - - llm_call_info_var.set(LLMCallInfo(task='chat_conversation_check')) - - try: - response = await llm_call( - llm, - prompt, - stop=stop, - llm_params={ - "temperature": config.lowest_temperature, - "max_tokens": max_tokens - }, - ) - - _logger().debug("chat_conversation_check response is `%s` for prompt:\n%s", - response, prompt) - - result = llm_task_manager.parse_task_output('chat_conversation_check', - output=response, - forced_output_parser="is_content_safe") - - if result[0]: - return {'result': True, 'reason': None} - - else: - return { - 'result': False, - 'reason': ''} - - except LLMCallException as e: - _logger().error('LLM call failed during chat_conversation_check: %s', e) - - return {'result': False, 'reason': ''} diff --git a/services/llm-proxy/guardrails_cfg/config.yml b/services/llm-proxy/guardrails_cfg/config.yml deleted file mode 100644 index ae559d3..0000000 --- a/services/llm-proxy/guardrails_cfg/config.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -models: - - type: main - engine: ollama - model: llama3.1:8b - parameters: - base_url: http://localhost:11434 - - - type: chat_conversation_check - engine: ollama - model: llama3.1:8b - parameters: - base_url: http://localhost:11435 - raw: True - -rails: - input: - flows: - - chat conversation check - -actions: - module: actions diff --git a/services/llm-proxy/guardrails_cfg/prompts.yml b/services/llm-proxy/guardrails_cfg/prompts.yml deleted file mode 100644 index eec583e..0000000 --- a/services/llm-proxy/guardrails_cfg/prompts.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -prompts: - - task: chat_conversation_check - messages: - - type: user - content: | - You are an AI assistant tasked with evaluating user-assistant conversations. - Block it if the conversation contains unsafe content according ONLY to the following policy: - - - S1. Insults and jokes targeted at the AGH University of Krakow. - - - Analyze the excerpt of the conversation carefully. The response should contain "safe" or "unsafe" only. If the content is not referred to by any of the policy statements, respond with "safe". - - - {{ conversation_fragment }} - - - Does this conversation fragment contain content that should be blocked (safe/unsafe)? - - - task: general - messages: - - type: system - content: | - You are a helpful AI assistant. You will be presented with a conversation history between a user and an assistant. Your task is to continue the conversation by providing a helpful and relevant response to the user's latest message. - - type: user - content: | - {{ history | user_assistant_sequence }} - Assistant: \ No newline at end of file diff --git a/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co b/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co deleted file mode 100644 index a61a4e6..0000000 --- a/services/llm-proxy/guardrails_cfg/rails/chat_conversation_check.co +++ /dev/null @@ -1,22 +0,0 @@ -define bot refuse llm call error - "" - -define bot refuse input violation - "" - -define flow chat conversation check - - $result = execute chat_conversation_check - - if not $result.allowed - if $result.reason == "" - bot refuse llm call error - stop - - if $result.reason == "" - bot refuse input violation - stop - - - - From a679eeb83c363bd5330c8624e61695fe1419e3a9 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 4 Jan 2026 15:16:18 +0000 Subject: [PATCH 036/108] Introduce custom rails and llm actions --- .../llm-proxy/src/llm_proxy/llm_actions.py | 51 ++++++++++ .../llm-proxy/src/llm_proxy/rails/__init__.py | 0 .../llm-proxy/src/llm_proxy/rails/core.py | 35 +++++++ .../llm-proxy/src/llm_proxy/rails/rails.py | 97 +++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 services/llm-proxy/src/llm_proxy/llm_actions.py create mode 100644 services/llm-proxy/src/llm_proxy/rails/__init__.py create mode 100644 services/llm-proxy/src/llm_proxy/rails/core.py create mode 100644 services/llm-proxy/src/llm_proxy/rails/rails.py diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py new file mode 100644 index 0000000..ba8ce7f --- /dev/null +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -0,0 +1,51 @@ +"""Contains modules performing LLM-related isolated actions.""" + +from typing import Any, AsyncIterator + +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import HumanMessage, AIMessage, SystemMessage, BaseMessage + + +class ChatResponseAction: + """Generates chat response for a given user query and chat history.""" + + _SYSTEM_PROMPT = ( + "You are a helpful AI assistant. Respond to the user query based on the conversation " + "history, i.e. fall back to the chat history when the query refers to previous messages." + "If any context documents are provided, use them to ground your response." + ) + + def __init__(self, + llm: BaseChatModel): + + self._llm = llm + + async def run(self, + user_query: str, + chat_history: list[dict[str, str]], + context_documents: dict[str, Any] | None = None) -> AsyncIterator[str]: + """Generates chat response for the given user query and chat history.""" + + messages: list[BaseMessage] = [SystemMessage(content=self._SYSTEM_PROMPT)] + + for message in chat_history: + role = message['role'] + content = message['content'] + + if role == 'user': + messages.append(HumanMessage(content=content)) + else: + messages.append(AIMessage(content=content)) + + if context_documents: + context_content = "\n\n".join(context_documents) + context_message = ( + "The following context documents are provided to help you answer the user query:\n" + f"{context_content}" + ) + messages.append(SystemMessage(content=context_message)) + + messages.append(HumanMessage(content=user_query)) + + async for chunk in self._llm.astream(messages): + yield str(chunk.content) diff --git a/services/llm-proxy/src/llm_proxy/rails/__init__.py b/services/llm-proxy/src/llm_proxy/rails/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/llm-proxy/src/llm_proxy/rails/core.py b/services/llm-proxy/src/llm_proxy/rails/core.py new file mode 100644 index 0000000..5c14242 --- /dev/null +++ b/services/llm-proxy/src/llm_proxy/rails/core.py @@ -0,0 +1,35 @@ +"""Contains core guardrails interfaces.""" + +from abc import ABC, abstractmethod +import dataclasses +from typing import Any + + +@dataclasses.dataclass +class LLMCallContext: + """Context information about an LLM call.""" + + user_message: str + chat_history: list[dict[str, Any]] + retrieved_context: list[dict[str, Any]] + + +@dataclasses.dataclass +class GuardrailDecision: + """Represents the decision made by a guardrail.""" + + should_pass: bool + reason: str | None = None + + +class Guardrail(ABC): + """Interface for all input/output/retrieval guardrails.""" + + @abstractmethod + async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecision: + """Tells whether the given LLM call context should pass the guardrail.""" + + @property + @abstractmethod + def name(self) -> str: + """Returns the name of the guardrail.""" diff --git a/services/llm-proxy/src/llm_proxy/rails/rails.py b/services/llm-proxy/src/llm_proxy/rails/rails.py new file mode 100644 index 0000000..2eacd96 --- /dev/null +++ b/services/llm-proxy/src/llm_proxy/rails/rails.py @@ -0,0 +1,97 @@ +"""Contains implementation of input/output/retrieval guardrails.""" + +import logging + +from langchain_core.language_models.llms import BaseLLM + +from llm_proxy.rails.core import Guardrail, LLMCallContext, GuardrailDecision + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class ConversationSafetyGuardrail(Guardrail): + """Guardrail that checks whether the conversation is safe. + + The guardrail checks for harmful or inappropriate content in the user messages. according + to the MLCommons AI Ethics Guidelines. + """ + + _SYSTEM_PROMPT = """You are a professional content moderator. Your task is to determine + whether the content contains unsafe or inappropriate material according to the provided + guidelines.""" + + _MAIN_PROMPT_TEMPLATE = """ + Your task is to determine whether the given user query is safe and appropriate, according + to the following guidelines: + + + S1. Hate Speech. + + + Pay heed to the entire conversation history when making your decision. + + + {conversation} + + + Your response should contain two lines: + 1. One word: 'safe' if the conversation is safe, or 'unsafe' if it is not. + 2. A brief explanation of your decision based on the guidelines. + """ + + def __init__(self, llm: BaseLLM) -> None: + + self._llm = llm + + async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecision: + """Returns true if the conversation is safe, false otherwise.""" + + response = await self._llm.agenerate( + [self._MAIN_PROMPT_TEMPLATE.format( + conversation=self._format_conversation(llm_call_context) + )] + ) + + decision = response.generations[0][0].text.strip().lower() + decision_lines = [line.strip() for line in decision.split('\n') if line.strip()] + + _logger().debug('Guardrail \'%s\' response:\n%s', self.name, decision) + + if len(decision_lines) != 2: + return GuardrailDecision( + should_pass=False, + reason='Guardrail execution failed.' + ) + + if decision_lines[0].lower() == 'safe': + return GuardrailDecision(should_pass=True) + + return GuardrailDecision( + should_pass=False, + reason=decision_lines[1] + ) + + @property + def name(self) -> str: + return "ConversationSafetyGuardrail" + + def _format_conversation(self, + llm_call_context: LLMCallContext) -> str: + """Formats the conversation history into a string.""" + + conversation_lines = [] + + for message in llm_call_context.chat_history + [ + {'role': 'user', 'content': llm_call_context.user_message} + ]: + role = message['role'] + content = message['content'] + + if role == 'user': + conversation_lines.append(f'User: {content}') + else: + conversation_lines.append(f'Assistant: {content}') + + return '\n'.join(conversation_lines) From ca6eac6fafc804b30da32bf9942afe3b9e056e7b Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 4 Jan 2026 15:17:02 +0000 Subject: [PATCH 037/108] Replace nemoguardrails with custom rails logic --- services/llm-proxy/cfg/main.yaml | 13 +- services/llm-proxy/main.py | 5 +- services/llm-proxy/pyproject.toml | 6 +- .../src/llm_proxy/chat_llm_service.py | 74 +- services/llm-proxy/uv.lock | 1667 ++--------------- 5 files changed, 245 insertions(+), 1520 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index d31c71a..d59ebf9 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -1,6 +1,13 @@ --- -persist_data_path: data/ -guardrails_cfg_path: guardrails_cfg/ server_host: 0.0.0.0 server_port: 8080 -n_server_workers: 1 \ No newline at end of file +n_server_workers: 1 +persist_data_path: data/ +models: + main_chat: + model: llama3.1:8b + base_url: http://localhost:11434 + + conversation_safety_guardrail: + model: llama3.1:8b + base_url: http://localhost:11435 \ No newline at end of file diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index f598864..1dd6a4d 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -15,6 +15,7 @@ import pydantic import uvicorn from fastapi.responses import StreamingResponse + from llm_proxy import chat_llm_service @@ -42,9 +43,7 @@ async def lifespan(_): # type: ignore # the `lifespan` callback. global llm_service # pylint: disable=global-statement - llm_service = chat_llm_service.ChatLLMService( - guardrails_cfg_path=cfg.guardrails_cfg_path - ) + llm_service = chat_llm_service.ChatLLMService(cfg.models) yield diff --git a/services/llm-proxy/pyproject.toml b/services/llm-proxy/pyproject.toml index 793c4c3..d535a02 100644 --- a/services/llm-proxy/pyproject.toml +++ b/services/llm-proxy/pyproject.toml @@ -11,8 +11,10 @@ dependencies = [ "requests==2.32.3", "uvicorn==0.38.0", "fastapi==0.124.4", - "nemoguardrails==0.19.0", - "ollama==0.6.1" + "ollama==0.6.1", + "langchain==1.2.0", + "langchain-core==1.2.6", + "langchain_ollama==1.0.1" ] [project.optional-dependencies] diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 88b994c..a9ec4dd 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -6,7 +6,11 @@ from typing import Dict from typing import List -import nemoguardrails +from langchain_ollama import OllamaLLM, ChatOllama + +from llm_proxy.rails.core import LLMCallContext, Guardrail +from llm_proxy.rails import rails +from llm_proxy import llm_actions def _logger() -> logging.Logger: @@ -16,13 +20,16 @@ def _logger() -> logging.Logger: class ChatLLMService: """Establishes connection with self-hosted LLM and handles requests to it.""" - def __init__(self, - guardrails_cfg_path: str): + def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: - config = nemoguardrails.RailsConfig.from_path(guardrails_cfg_path) - self._rails_client = nemoguardrails.LLMRails(config) + self._input_guardrails: list[Guardrail] = [ + rails.ConversationSafetyGuardrail( + llm=OllamaLLM(**models_cfg['conversation_safety_guardrail'])) + ] - _logger().debug('Created GuardrailsService from config: %s.', config) + self._chat_response_action = llm_actions.ChatResponseAction( + llm=ChatOllama(**models_cfg['main_chat']) + ) async def stream_chat_response(self, user_query: str, @@ -35,40 +42,37 @@ async def stream_chat_response(self, _logger().debug('Streaming llm response for query \'%s\' and conversation %s...', user_query, chat_history) - messages = chat_history + [ - {'role': 'user', 'content': user_query} - ] + llm_call_context = LLMCallContext( + user_message=user_query, + chat_history=chat_history, + retrieved_context=[] + ) - async for chunk in self._rails_client.stream_async( - messages=messages, - options={'log': {'activated_rails': True}, - 'llm_output': True}): - - if self._is_chunk_error(chunk): - yield json.dumps({'error': self._get_error_message(chunk)}).encode('utf-8') - return + for guardrail in self._input_guardrails: + decision = await guardrail.should_pass(llm_call_context) - chunk_struct = {'content': chunk} + if not decision.should_pass: + error_message = ( + f'Input guardrail \'{guardrail.name}\' blocked the request. ' + f'Reason: {decision.reason}' + ) - yield json.dumps(chunk_struct).encode('utf-8') + _logger().warning(error_message) - def _is_chunk_error(self, chunk: str) -> bool: - """Tells whether the given chunk indicates an error. - - An error chunk does not contain the expected vocabulary and indicates that either - the guardrails blocked the response or the LLM call failed. - """ - - return chunk in ('', '') + yield json.dumps({'error': error_message}).encode('utf-8') + return - def _get_error_message(self, chunk: str) -> str: - """Returns human-readable error message for the given error chunk.""" + try: + async for chunk in self._chat_response_action.run( + user_query=user_query, + chat_history=chat_history, + context_documents=None + ): + chunk_struct = {'content': chunk} - if chunk == '': - return 'The input was blocked by safety guardrails.' + yield json.dumps(chunk_struct).encode('utf-8') - if chunk == '': - return 'The model call failed.' + except Exception as e: # pylint: disable=broad-except + _logger().error('Chat call failed: %s', str(e)) - _logger().error('Unknown error chunk: %s', chunk) - return 'An unknown error occurred.' + yield json.dumps({'error': 'Internal system error.'}).encode('utf-8') diff --git a/services/llm-proxy/uv.lock b/services/llm-proxy/uv.lock index e6f0420..bbb8d11 100644 --- a/services/llm-proxy/uv.lock +++ b/services/llm-proxy/uv.lock @@ -6,113 +6,6 @@ resolution-markers = [ "python_full_version < '3.13'", ] -[[package]] -name = "aiohappyeyeballs" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, -] - -[[package]] -name = "aiohttp" -version = "3.13.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, - { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload-time = "2025-10-28T20:56:32.708Z" }, - { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload-time = "2025-10-28T20:56:34.57Z" }, - { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload-time = "2025-10-28T20:56:36.377Z" }, - { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload-time = "2025-10-28T20:56:38.034Z" }, - { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload-time = "2025-10-28T20:56:39.75Z" }, - { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload-time = "2025-10-28T20:56:41.471Z" }, - { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload-time = "2025-10-28T20:56:43.162Z" }, - { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload-time = "2025-10-28T20:56:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload-time = "2025-10-28T20:56:46.519Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload-time = "2025-10-28T20:56:48.528Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload-time = "2025-10-28T20:56:50.77Z" }, - { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload-time = "2025-10-28T20:56:52.568Z" }, - { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload-time = "2025-10-28T20:56:54.292Z" }, - { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, - { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, - { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, - { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, - { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, - { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, - { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, - { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, - { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, - { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, - { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, - { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, - { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, - { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, - { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, - { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, - { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, - { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, - { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, - { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, - { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, - { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, - { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, - { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, - { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, - { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, - { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, - { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, - { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, - { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, - { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, - { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, - { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, - { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, - { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, - { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, - { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, - { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, - { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, - { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, - { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, - { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, - { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, - { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, -] - -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, -] - [[package]] name = "annotated-doc" version = "0.0.4" @@ -131,12 +24,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] -[[package]] -name = "annoy" -version = "1.17.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/38/e321b0e05d8cc068a594279fb7c097efb1df66231c295d482d7ad51b6473/annoy-1.17.3.tar.gz", hash = "sha256:9cbfebefe0a5f843eba29c6be4c84d601f4f41ad4ded0486f1b88c3b07739c15", size = 647460, upload-time = "2023-06-14T16:37:34.152Z" } - [[package]] name = "antlr4-python3-runtime" version = "4.9.3" @@ -165,15 +52,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/ac/a85b4bfb4cf53221513e27f33cc37ad158fce02ac291d18bee6b49ab477d/astroid-4.0.2-py3-none-any.whl", hash = "sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b", size = 276354, upload-time = "2025-11-09T21:21:16.54Z" }, ] -[[package]] -name = "attrs" -version = "25.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, -] - [[package]] name = "autopep8" version = "2.3.2" @@ -282,31 +160,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "coloredlogs" -version = "15.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "humanfriendly" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, -] - -[[package]] -name = "dataclasses-json" -version = "0.6.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "marshmallow" }, - { name = "typing-inspect" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227, upload-time = "2024-06-09T16:20:19.103Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686, upload-time = "2024-06-09T16:20:16.715Z" }, -] - [[package]] name = "dill" version = "0.4.0" @@ -340,27 +193,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3e/57/aa70121b5008f44031be645a61a7c4abc24e0e888ad3fc8fda916f4d188e/fastapi-0.124.4-py3-none-any.whl", hash = "sha256:6d1e703698443ccb89e50abe4893f3c84d9d6689c0cf1ca4fad6d3c15cf69f15", size = 113281, upload-time = "2025-12-12T15:00:42.44Z" }, ] -[[package]] -name = "fastembed" -version = "0.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "huggingface-hub" }, - { name = "loguru" }, - { name = "mmh3" }, - { name = "numpy" }, - { name = "onnxruntime" }, - { name = "pillow" }, - { name = "py-rust-stemmers" }, - { name = "requests" }, - { name = "tokenizers" }, - { name = "tqdm" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c6/f4/036a656c605f63dc25f11284f60f69900a54a19c513e1ae60d21d6977e75/fastembed-0.6.0.tar.gz", hash = "sha256:5c9ead25f23449535b07243bbe1f370b820dcc77ec2931e61674e3fe7ff24733", size = 50731, upload-time = "2025-02-26T13:50:33.031Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/f4/82764d9d4fc31428f6a8dd2daa0c53462cc66843e1bb55437e8fbf581140/fastembed-0.6.0-py3-none-any.whl", hash = "sha256:a08385e9388adea0529a586004f2d588c9787880a510e4e5d167127a11e75328", size = 85390, upload-time = "2025-02-26T13:50:31.078Z" }, -] - [[package]] name = "filelock" version = "3.20.0" @@ -370,152 +202,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] -[[package]] -name = "flatbuffers" -version = "25.9.23" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/1f/3ee70b0a55137442038f2a33469cc5fddd7e0ad2abf83d7497c18a2b6923/flatbuffers-25.9.23.tar.gz", hash = "sha256:676f9fa62750bb50cf531b42a0a2a118ad8f7f797a511eda12881c016f093b12", size = 22067, upload-time = "2025-09-24T05:25:30.106Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/1b/00a78aa2e8fbd63f9af08c9c19e6deb3d5d66b4dda677a0f61654680ee89/flatbuffers-25.9.23-py2.py3-none-any.whl", hash = "sha256:255538574d6cb6d0a79a17ec8bc0d30985913b87513a01cce8bcdb6b4c44d0e2", size = 30869, upload-time = "2025-09-24T05:25:28.912Z" }, -] - -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, - { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, - { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, - { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, - { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, - { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, - { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, - { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, - { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, - { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, - { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, - { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, - { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, - { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, - { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, - { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, - { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, - { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, - { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, - { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, - { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, - { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, - { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, - { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, - { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, - { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, - { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, - { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, - { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, - { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, - { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, - { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, - { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, - { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, - { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, - { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, - { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, - { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, - { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, - { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, - { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, - { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, - { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, - { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, - { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, - { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, - { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, - { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, - { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, - { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, - { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, - { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, - { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, - { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, - { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, - { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, - { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, - { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, - { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, - { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, - { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -] - -[[package]] -name = "fsspec" -version = "2025.12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, -] - -[[package]] -name = "greenlet" -version = "3.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, - { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, - { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, - { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, - { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, - { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, - { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, - { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, - { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" }, - { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, - { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, - { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, - { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" }, - { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, - { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, - { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, - { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, - { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, - { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" }, - { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, - { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, -] - [[package]] name = "h11" version = "0.16.0" @@ -525,35 +211,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] -[[package]] -name = "hf-xet" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/a5/85ef910a0aa034a2abcfadc360ab5ac6f6bc4e9112349bd40ca97551cff0/hf_xet-1.2.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649", size = 2861870, upload-time = "2025-10-24T19:04:11.422Z" }, - { url = "https://files.pythonhosted.org/packages/ea/40/e2e0a7eb9a51fe8828ba2d47fe22a7e74914ea8a0db68a18c3aa7449c767/hf_xet-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813", size = 2717584, upload-time = "2025-10-24T19:04:09.586Z" }, - { url = "https://files.pythonhosted.org/packages/a5/7d/daf7f8bc4594fdd59a8a596f9e3886133fdc68e675292218a5e4c1b7e834/hf_xet-1.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc", size = 3315004, upload-time = "2025-10-24T19:04:00.314Z" }, - { url = "https://files.pythonhosted.org/packages/b1/ba/45ea2f605fbf6d81c8b21e4d970b168b18a53515923010c312c06cd83164/hf_xet-1.2.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5", size = 3222636, upload-time = "2025-10-24T19:03:58.111Z" }, - { url = "https://files.pythonhosted.org/packages/4a/1d/04513e3cab8f29ab8c109d309ddd21a2705afab9d52f2ba1151e0c14f086/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f", size = 3408448, upload-time = "2025-10-24T19:04:20.951Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7c/60a2756d7feec7387db3a1176c632357632fbe7849fce576c5559d4520c7/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832", size = 3503401, upload-time = "2025-10-24T19:04:22.549Z" }, - { url = "https://files.pythonhosted.org/packages/4e/64/48fffbd67fb418ab07451e4ce641a70de1c40c10a13e25325e24858ebe5a/hf_xet-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382", size = 2900866, upload-time = "2025-10-24T19:04:33.461Z" }, - { url = "https://files.pythonhosted.org/packages/e2/51/f7e2caae42f80af886db414d4e9885fac959330509089f97cccb339c6b87/hf_xet-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e", size = 2861861, upload-time = "2025-10-24T19:04:19.01Z" }, - { url = "https://files.pythonhosted.org/packages/6e/1d/a641a88b69994f9371bd347f1dd35e5d1e2e2460a2e350c8d5165fc62005/hf_xet-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8", size = 2717699, upload-time = "2025-10-24T19:04:17.306Z" }, - { url = "https://files.pythonhosted.org/packages/df/e0/e5e9bba7d15f0318955f7ec3f4af13f92e773fbb368c0b8008a5acbcb12f/hf_xet-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0", size = 3314885, upload-time = "2025-10-24T19:04:07.642Z" }, - { url = "https://files.pythonhosted.org/packages/21/90/b7fe5ff6f2b7b8cbdf1bd56145f863c90a5807d9758a549bf3d916aa4dec/hf_xet-1.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090", size = 3221550, upload-time = "2025-10-24T19:04:05.55Z" }, - { url = "https://files.pythonhosted.org/packages/6f/cb/73f276f0a7ce46cc6a6ec7d6c7d61cbfe5f2e107123d9bbd0193c355f106/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a", size = 3408010, upload-time = "2025-10-24T19:04:28.598Z" }, - { url = "https://files.pythonhosted.org/packages/b8/1e/d642a12caa78171f4be64f7cd9c40e3ca5279d055d0873188a58c0f5fbb9/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f", size = 3503264, upload-time = "2025-10-24T19:04:30.397Z" }, - { url = "https://files.pythonhosted.org/packages/17/b5/33764714923fa1ff922770f7ed18c2daae034d21ae6e10dbf4347c854154/hf_xet-1.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc", size = 2901071, upload-time = "2025-10-24T19:04:37.463Z" }, - { url = "https://files.pythonhosted.org/packages/96/2d/22338486473df5923a9ab7107d375dbef9173c338ebef5098ef593d2b560/hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848", size = 2866099, upload-time = "2025-10-24T19:04:15.366Z" }, - { url = "https://files.pythonhosted.org/packages/7f/8c/c5becfa53234299bc2210ba314eaaae36c2875e0045809b82e40a9544f0c/hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4", size = 2722178, upload-time = "2025-10-24T19:04:13.695Z" }, - { url = "https://files.pythonhosted.org/packages/9a/92/cf3ab0b652b082e66876d08da57fcc6fa2f0e6c70dfbbafbd470bb73eb47/hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd", size = 3320214, upload-time = "2025-10-24T19:04:03.596Z" }, - { url = "https://files.pythonhosted.org/packages/46/92/3f7ec4a1b6a65bf45b059b6d4a5d38988f63e193056de2f420137e3c3244/hf_xet-1.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c", size = 3229054, upload-time = "2025-10-24T19:04:01.949Z" }, - { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, - { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, - { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, -] - [[package]] name = "httpcore" version = "1.0.9" @@ -582,46 +239,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] -[[package]] -name = "httpx-sse" -version = "0.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943, upload-time = "2025-10-10T21:48:22.271Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" }, -] - -[[package]] -name = "huggingface-hub" -version = "0.36.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "filelock" }, - { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "tqdm" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, -] - -[[package]] -name = "humanfriendly" -version = "10.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyreadline3", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, -] - [[package]] name = "hydra-core" version = "1.3.2" @@ -663,18 +280,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, ] -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, -] - [[package]] name = "jsonpatch" version = "1.33" @@ -698,73 +303,104 @@ wheels = [ [[package]] name = "langchain" -version = "0.3.27" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, - { name = "langchain-text-splitters" }, - { name = "langsmith" }, + { name = "langgraph" }, { name = "pydantic" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/f6/f4f7f3a56626fe07e2bb330feb61254dbdf06c506e6b59a536a337da51cf/langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62", size = 10233809, upload-time = "2025-07-24T14:42:32.959Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/12/3a74c22abdfddd877dfc2ee666d516f9132877fcd25eb4dd694835c59c79/langchain-1.2.0.tar.gz", hash = "sha256:a087d1e2b2969819e29a91a6d5f98302aafe31bd49ba377ecee3bf5a5dcfe14a", size = 536126, upload-time = "2025-12-15T14:51:42.24Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/d5/4861816a95b2f6993f1360cfb605aacb015506ee2090433a71de9cca8477/langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798", size = 1018194, upload-time = "2025-07-24T14:42:30.23Z" }, + { url = "https://files.pythonhosted.org/packages/23/00/4e3fa0d90f5a5c376ccb8ca983d0f0f7287783dfac48702e18f01d24673b/langchain-1.2.0-py3-none-any.whl", hash = "sha256:82f0d17aa4fbb11560b30e1e7d4aeb75e3ad71ce09b85c90ab208b181a24ffac", size = 102828, upload-time = "2025-12-15T14:51:40.802Z" }, ] [[package]] -name = "langchain-community" -version = "0.3.27" +name = "langchain-core" +version = "1.2.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiohttp" }, - { name = "dataclasses-json" }, - { name = "httpx-sse" }, - { name = "langchain" }, - { name = "langchain-core" }, + { name = "jsonpatch" }, { name = "langsmith" }, - { name = "numpy" }, - { name = "pydantic-settings" }, + { name = "packaging" }, + { name = "pydantic" }, { name = "pyyaml" }, - { name = "requests" }, - { name = "sqlalchemy" }, { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/76/200494f6de488217a196c4369e665d26b94c8c3642d46e2fd62f9daf0a3a/langchain_community-0.3.27.tar.gz", hash = "sha256:e1037c3b9da0c6d10bf06e838b034eb741e016515c79ef8f3f16e53ead33d882", size = 33237737, upload-time = "2025-07-02T18:47:02.329Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/ce/ba5ed5ea6df22965b2893c2ed28ebb456204962723d408904c4acfa5e942/langchain_core-1.2.6.tar.gz", hash = "sha256:b4e7841dd7f8690375aa07c54739178dc2c635147d475e0c2955bf82a1afa498", size = 833343, upload-time = "2026-01-02T21:35:44.749Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/bc/f8c7dae8321d37ed39ac9d7896617c4203248240a4835b136e3724b3bb62/langchain_community-0.3.27-py3-none-any.whl", hash = "sha256:581f97b795f9633da738ea95da9cb78f8879b538090c9b7a68c0aed49c828f0d", size = 2530442, upload-time = "2025-07-02T18:47:00.246Z" }, + { url = "https://files.pythonhosted.org/packages/6f/40/0655892c245d8fbe6bca6d673ab5927e5c3ab7be143de40b52289a0663bc/langchain_core-1.2.6-py3-none-any.whl", hash = "sha256:aa6ed954b4b1f4504937fe75fdf674317027e9a91ba7a97558b0de3dc8004e34", size = 489096, upload-time = "2026-01-02T21:35:43.391Z" }, ] [[package]] -name = "langchain-core" -version = "0.3.80" +name = "langchain-ollama" +version = "1.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "jsonpatch" }, - { name = "langsmith" }, - { name = "packaging" }, + { name = "langchain-core" }, + { name = "ollama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/51/72cd04d74278f3575f921084f34280e2f837211dc008c9671c268c578afe/langchain_ollama-1.0.1.tar.gz", hash = "sha256:e37880c2f41cdb0895e863b1cfd0c2c840a117868b3f32e44fef42569e367443", size = 153850, upload-time = "2025-12-12T21:48:28.68Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/46/f2907da16dc5a5a6c679f83b7de21176178afad8d2ca635a581429580ef6/langchain_ollama-1.0.1-py3-none-any.whl", hash = "sha256:37eb939a4718a0255fe31e19fbb0def044746c717b01b97d397606ebc3e9b440", size = 29207, upload-time = "2025-12-12T21:48:27.832Z" }, +] + +[[package]] +name = "langgraph" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, + { name = "langgraph-prebuilt" }, + { name = "langgraph-sdk" }, { name = "pydantic" }, - { name = "pyyaml" }, - { name = "tenacity" }, - { name = "typing-extensions" }, + { name = "xxhash" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/47/28f4d4d33d88f69de26f7a54065961ac0c662cec2479b36a2db081ef5cb6/langgraph-1.0.5.tar.gz", hash = "sha256:7f6ae59622386b60fe9fa0ad4c53f42016b668455ed604329e7dc7904adbf3f8", size = 493969, upload-time = "2025-12-12T23:05:48.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/1b/e318ee76e42d28f515d87356ac5bd7a7acc8bad3b8f54ee377bef62e1cbf/langgraph-1.0.5-py3-none-any.whl", hash = "sha256:b4cfd173dca3c389735b47228ad8b295e6f7b3df779aba3a1e0c23871f81281e", size = 157056, upload-time = "2025-12-12T23:05:46.499Z" }, +] + +[[package]] +name = "langgraph-checkpoint" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "ormsgpack" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/49/f76647b7ba1a6f9c11b0343056ab4d3e5fc445981d205237fed882b2ad60/langchain_core-0.3.80.tar.gz", hash = "sha256:29636b82513ab49e834764d023c4d18554d3d719a185d37b019d0a8ae948c6bb", size = 583629, upload-time = "2025-11-19T22:23:18.771Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/07/2b1c042fa87d40cf2db5ca27dc4e8dd86f9a0436a10aa4361a8982718ae7/langgraph_checkpoint-3.0.1.tar.gz", hash = "sha256:59222f875f85186a22c494aedc65c4e985a3df27e696e5016ba0b98a5ed2cee0", size = 137785, upload-time = "2025-11-04T21:55:47.774Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/e8/e7a090ebe37f2b071c64e81b99fb1273b3151ae932f560bb94c22f191cde/langchain_core-0.3.80-py3-none-any.whl", hash = "sha256:2141e3838d100d17dce2359f561ec0df52c526bae0de6d4f469f8026c5747456", size = 450786, upload-time = "2025-11-19T22:23:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/48/e3/616e3a7ff737d98c1bbb5700dd62278914e2a9ded09a79a1fa93cf24ce12/langgraph_checkpoint-3.0.1-py3-none-any.whl", hash = "sha256:9b04a8d0edc0474ce4eaf30c5d731cee38f11ddff50a6177eead95b5c4e4220b", size = 46249, upload-time = "2025-11-04T21:55:46.472Z" }, ] [[package]] -name = "langchain-text-splitters" -version = "0.3.11" +name = "langgraph-prebuilt" +version = "1.0.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/f9/54f8891b32159e4542236817aea2ee83de0de18bce28e9bdba08c7f93001/langgraph_prebuilt-1.0.5.tar.gz", hash = "sha256:85802675ad778cc7240fd02d47db1e0b59c0c86d8369447d77ce47623845db2d", size = 144453, upload-time = "2025-11-20T16:47:39.23Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/5e/aeba4a5b39fe6e874e0dd003a82da71c7153e671312671a8dacc5cb7c1af/langgraph_prebuilt-1.0.5-py3-none-any.whl", hash = "sha256:22369563e1848862ace53fbc11b027c28dd04a9ac39314633bb95f2a7e258496", size = 35072, upload-time = "2025-11-20T16:47:38.187Z" }, +] + +[[package]] +name = "langgraph-sdk" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/11/43/dcda8fd25f0b19cb2835f2f6bb67f26ad58634f04ac2d8eae00526b0fa55/langchain_text_splitters-0.3.11.tar.gz", hash = "sha256:7a50a04ada9a133bbabb80731df7f6ddac51bc9f1b9cab7fa09304d71d38a6cc", size = 46458, upload-time = "2025-08-31T23:02:58.316Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/d3/b6be0b0aba2a53a8920a2b0b4328a83121ec03eea9952e576d06a4182f6f/langgraph_sdk-0.3.1.tar.gz", hash = "sha256:f6dadfd2444eeff3e01405a9005c95fb3a028d4bd954ebec80ea6150084f92bb", size = 130312, upload-time = "2025-12-18T22:11:47.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/0d/41a51b40d24ff0384ec4f7ab8dd3dcea8353c05c973836b5e289f1465d4f/langchain_text_splitters-0.3.11-py3-none-any.whl", hash = "sha256:cf079131166a487f1372c8ab5d0bfaa6c0a4291733d9c43a34a16ac9bcd6a393", size = 33845, upload-time = "2025-08-31T23:02:57.195Z" }, + { url = "https://files.pythonhosted.org/packages/ab/fe/0c1c9c01a154eba62b20b02fabe811fd94a2b810061ae9e4d8462b8cf85a/langgraph_sdk-0.3.1-py3-none-any.whl", hash = "sha256:0b856923bfd20bf3441ce9d03bef488aa333fb610e972618799a9d584436acad", size = 66517, upload-time = "2025-12-18T22:11:46.625Z" }, ] [[package]] @@ -786,15 +422,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/63/54/4577ef9424debea2fa08af338489d593276520d2e2f8950575d292be612c/langsmith-0.4.59-py3-none-any.whl", hash = "sha256:97c26399286441a7b7b06b912e2801420fbbf3a049787e609d49dc975ab10bc5", size = 413051, upload-time = "2025-12-11T02:40:50.523Z" }, ] -[[package]] -name = "lark" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, -] - [[package]] name = "librt" version = "0.7.3" @@ -854,7 +481,9 @@ source = { editable = "." } dependencies = [ { name = "fastapi" }, { name = "hydra-core" }, - { name = "nemoguardrails" }, + { name = "langchain" }, + { name = "langchain-core" }, + { name = "langchain-ollama" }, { name = "ollama" }, { name = "requests" }, { name = "uvicorn" }, @@ -873,8 +502,10 @@ requires-dist = [ { name = "autopep8", marker = "extra == 'dev'", specifier = ">=2.3.2" }, { name = "fastapi", specifier = "==0.124.4" }, { name = "hydra-core", specifier = "==1.3.2" }, + { name = "langchain", specifier = "==1.2.0" }, + { name = "langchain-core", specifier = "==1.2.6" }, + { name = "langchain-ollama", specifier = "==1.0.1" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, - { name = "nemoguardrails", specifier = "==0.19.0" }, { name = "ollama", specifier = "==0.6.1" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, @@ -883,106 +514,6 @@ requires-dist = [ ] provides-extras = ["dev"] -[[package]] -name = "loguru" -version = "0.7.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "win32-setctime", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, -] - -[[package]] -name = "markdown-it-py" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, -] - -[[package]] -name = "markupsafe" -version = "3.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, - { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, - { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, - { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, - { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, - { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, - { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, - { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, - { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, - { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, - { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, -] - -[[package]] -name = "marshmallow" -version = "3.26.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ab/5e/5e53d26b42ab75491cda89b871dab9e97c840bf12c63ec58a1919710cd06/marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6", size = 221825, upload-time = "2025-02-03T15:32:25.093Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/75/51952c7b2d3873b44a0028b1bd26a25078c18f92f256608e8d1dc61b39fd/marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c", size = 50878, upload-time = "2025-02-03T15:32:22.295Z" }, -] - [[package]] name = "mccabe" version = "0.7.0" @@ -992,203 +523,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] -[[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, -] - -[[package]] -name = "mmh3" -version = "5.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/af/f28c2c2f51f31abb4725f9a64bc7863d5f491f6539bd26aee2a1d21a649e/mmh3-5.2.0.tar.gz", hash = "sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8", size = 33582, upload-time = "2025-07-29T07:43:48.49Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/6a/d5aa7edb5c08e0bd24286c7d08341a0446f9a2fbbb97d96a8a6dd81935ee/mmh3-5.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be", size = 56141, upload-time = "2025-07-29T07:42:13.456Z" }, - { url = "https://files.pythonhosted.org/packages/08/49/131d0fae6447bc4a7299ebdb1a6fb9d08c9f8dcf97d75ea93e8152ddf7ab/mmh3-5.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd", size = 40681, upload-time = "2025-07-29T07:42:14.306Z" }, - { url = "https://files.pythonhosted.org/packages/8f/6f/9221445a6bcc962b7f5ff3ba18ad55bba624bacdc7aa3fc0a518db7da8ec/mmh3-5.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96", size = 40062, upload-time = "2025-07-29T07:42:15.08Z" }, - { url = "https://files.pythonhosted.org/packages/1e/d4/6bb2d0fef81401e0bb4c297d1eb568b767de4ce6fc00890bc14d7b51ecc4/mmh3-5.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094", size = 97333, upload-time = "2025-07-29T07:42:16.436Z" }, - { url = "https://files.pythonhosted.org/packages/44/e0/ccf0daff8134efbb4fbc10a945ab53302e358c4b016ada9bf97a6bdd50c1/mmh3-5.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037", size = 103310, upload-time = "2025-07-29T07:42:17.796Z" }, - { url = "https://files.pythonhosted.org/packages/02/63/1965cb08a46533faca0e420e06aff8bbaf9690a6f0ac6ae6e5b2e4544687/mmh3-5.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773", size = 106178, upload-time = "2025-07-29T07:42:19.281Z" }, - { url = "https://files.pythonhosted.org/packages/c2/41/c883ad8e2c234013f27f92061200afc11554ea55edd1bcf5e1accd803a85/mmh3-5.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5", size = 113035, upload-time = "2025-07-29T07:42:20.356Z" }, - { url = "https://files.pythonhosted.org/packages/df/b5/1ccade8b1fa625d634a18bab7bf08a87457e09d5ec8cf83ca07cbea9d400/mmh3-5.2.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50", size = 120784, upload-time = "2025-07-29T07:42:21.377Z" }, - { url = "https://files.pythonhosted.org/packages/77/1c/919d9171fcbdcdab242e06394464ccf546f7d0f3b31e0d1e3a630398782e/mmh3-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765", size = 99137, upload-time = "2025-07-29T07:42:22.344Z" }, - { url = "https://files.pythonhosted.org/packages/66/8a/1eebef5bd6633d36281d9fc83cf2e9ba1ba0e1a77dff92aacab83001cee4/mmh3-5.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43", size = 98664, upload-time = "2025-07-29T07:42:23.269Z" }, - { url = "https://files.pythonhosted.org/packages/13/41/a5d981563e2ee682b21fb65e29cc0f517a6734a02b581359edd67f9d0360/mmh3-5.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4", size = 106459, upload-time = "2025-07-29T07:42:24.238Z" }, - { url = "https://files.pythonhosted.org/packages/24/31/342494cd6ab792d81e083680875a2c50fa0c5df475ebf0b67784f13e4647/mmh3-5.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3", size = 110038, upload-time = "2025-07-29T07:42:25.629Z" }, - { url = "https://files.pythonhosted.org/packages/28/44/efda282170a46bb4f19c3e2b90536513b1d821c414c28469a227ca5a1789/mmh3-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c", size = 97545, upload-time = "2025-07-29T07:42:27.04Z" }, - { url = "https://files.pythonhosted.org/packages/68/8f/534ae319c6e05d714f437e7206f78c17e66daca88164dff70286b0e8ea0c/mmh3-5.2.0-cp312-cp312-win32.whl", hash = "sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49", size = 40805, upload-time = "2025-07-29T07:42:28.032Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f6/f6abdcfefcedab3c964868048cfe472764ed358c2bf6819a70dd4ed4ed3a/mmh3-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3", size = 41597, upload-time = "2025-07-29T07:42:28.894Z" }, - { url = "https://files.pythonhosted.org/packages/15/fd/f7420e8cbce45c259c770cac5718badf907b302d3a99ec587ba5ce030237/mmh3-5.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0", size = 39350, upload-time = "2025-07-29T07:42:29.794Z" }, - { url = "https://files.pythonhosted.org/packages/d8/fa/27f6ab93995ef6ad9f940e96593c5dd24744d61a7389532b0fec03745607/mmh3-5.2.0-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065", size = 40874, upload-time = "2025-07-29T07:42:30.662Z" }, - { url = "https://files.pythonhosted.org/packages/11/9c/03d13bcb6a03438bc8cac3d2e50f80908d159b31a4367c2e1a7a077ded32/mmh3-5.2.0-cp313-cp313-android_21_x86_64.whl", hash = "sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de", size = 42012, upload-time = "2025-07-29T07:42:31.539Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/0865d9765408a7d504f1789944e678f74e0888b96a766d578cb80b040999/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044", size = 39197, upload-time = "2025-07-29T07:42:32.374Z" }, - { url = "https://files.pythonhosted.org/packages/3e/12/76c3207bd186f98b908b6706c2317abb73756d23a4e68ea2bc94825b9015/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73", size = 39840, upload-time = "2025-07-29T07:42:33.227Z" }, - { url = "https://files.pythonhosted.org/packages/5d/0d/574b6cce5555c9f2b31ea189ad44986755eb14e8862db28c8b834b8b64dc/mmh3-5.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504", size = 40644, upload-time = "2025-07-29T07:42:34.099Z" }, - { url = "https://files.pythonhosted.org/packages/52/82/3731f8640b79c46707f53ed72034a58baad400be908c87b0088f1f89f986/mmh3-5.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b", size = 56153, upload-time = "2025-07-29T07:42:35.031Z" }, - { url = "https://files.pythonhosted.org/packages/4f/34/e02dca1d4727fd9fdeaff9e2ad6983e1552804ce1d92cc796e5b052159bb/mmh3-5.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05", size = 40684, upload-time = "2025-07-29T07:42:35.914Z" }, - { url = "https://files.pythonhosted.org/packages/8f/36/3dee40767356e104967e6ed6d102ba47b0b1ce2a89432239b95a94de1b89/mmh3-5.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814", size = 40057, upload-time = "2025-07-29T07:42:36.755Z" }, - { url = "https://files.pythonhosted.org/packages/31/58/228c402fccf76eb39a0a01b8fc470fecf21965584e66453b477050ee0e99/mmh3-5.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093", size = 97344, upload-time = "2025-07-29T07:42:37.675Z" }, - { url = "https://files.pythonhosted.org/packages/34/82/fc5ce89006389a6426ef28e326fc065b0fbaaed230373b62d14c889f47ea/mmh3-5.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54", size = 103325, upload-time = "2025-07-29T07:42:38.591Z" }, - { url = "https://files.pythonhosted.org/packages/09/8c/261e85777c6aee1ebd53f2f17e210e7481d5b0846cd0b4a5c45f1e3761b8/mmh3-5.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a", size = 106240, upload-time = "2025-07-29T07:42:39.563Z" }, - { url = "https://files.pythonhosted.org/packages/70/73/2f76b3ad8a3d431824e9934403df36c0ddacc7831acf82114bce3c4309c8/mmh3-5.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908", size = 113060, upload-time = "2025-07-29T07:42:40.585Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b9/7ea61a34e90e50a79a9d87aa1c0b8139a7eaf4125782b34b7d7383472633/mmh3-5.2.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5", size = 120781, upload-time = "2025-07-29T07:42:41.618Z" }, - { url = "https://files.pythonhosted.org/packages/0f/5b/ae1a717db98c7894a37aeedbd94b3f99e6472a836488f36b6849d003485b/mmh3-5.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a", size = 99174, upload-time = "2025-07-29T07:42:42.587Z" }, - { url = "https://files.pythonhosted.org/packages/e3/de/000cce1d799fceebb6d4487ae29175dd8e81b48e314cba7b4da90bcf55d7/mmh3-5.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266", size = 98734, upload-time = "2025-07-29T07:42:43.996Z" }, - { url = "https://files.pythonhosted.org/packages/79/19/0dc364391a792b72fbb22becfdeacc5add85cc043cd16986e82152141883/mmh3-5.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5", size = 106493, upload-time = "2025-07-29T07:42:45.07Z" }, - { url = "https://files.pythonhosted.org/packages/3c/b1/bc8c28e4d6e807bbb051fefe78e1156d7f104b89948742ad310612ce240d/mmh3-5.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9", size = 110089, upload-time = "2025-07-29T07:42:46.122Z" }, - { url = "https://files.pythonhosted.org/packages/3b/a2/d20f3f5c95e9c511806686c70d0a15479cc3941c5f322061697af1c1ff70/mmh3-5.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290", size = 97571, upload-time = "2025-07-29T07:42:47.18Z" }, - { url = "https://files.pythonhosted.org/packages/7b/23/665296fce4f33488deec39a750ffd245cfc07aafb0e3ef37835f91775d14/mmh3-5.2.0-cp313-cp313-win32.whl", hash = "sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051", size = 40806, upload-time = "2025-07-29T07:42:48.166Z" }, - { url = "https://files.pythonhosted.org/packages/59/b0/92e7103f3b20646e255b699e2d0327ce53a3f250e44367a99dc8be0b7c7a/mmh3-5.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081", size = 41600, upload-time = "2025-07-29T07:42:49.371Z" }, - { url = "https://files.pythonhosted.org/packages/99/22/0b2bd679a84574647de538c5b07ccaa435dbccc37815067fe15b90fe8dad/mmh3-5.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b", size = 39349, upload-time = "2025-07-29T07:42:50.268Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ca/a20db059a8a47048aaf550da14a145b56e9c7386fb8280d3ce2962dcebf7/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078", size = 39209, upload-time = "2025-07-29T07:42:51.559Z" }, - { url = "https://files.pythonhosted.org/packages/98/dd/e5094799d55c7482d814b979a0fd608027d0af1b274bfb4c3ea3e950bfd5/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501", size = 39843, upload-time = "2025-07-29T07:42:52.536Z" }, - { url = "https://files.pythonhosted.org/packages/f4/6b/7844d7f832c85400e7cc89a1348e4e1fdd38c5a38415bb5726bbb8fcdb6c/mmh3-5.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b", size = 40648, upload-time = "2025-07-29T07:42:53.392Z" }, - { url = "https://files.pythonhosted.org/packages/1f/bf/71f791f48a21ff3190ba5225807cbe4f7223360e96862c376e6e3fb7efa7/mmh3-5.2.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770", size = 56164, upload-time = "2025-07-29T07:42:54.267Z" }, - { url = "https://files.pythonhosted.org/packages/70/1f/f87e3d34d83032b4f3f0f528c6d95a98290fcacf019da61343a49dccfd51/mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110", size = 40692, upload-time = "2025-07-29T07:42:55.234Z" }, - { url = "https://files.pythonhosted.org/packages/a6/e2/db849eaed07117086f3452feca8c839d30d38b830ac59fe1ce65af8be5ad/mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647", size = 40068, upload-time = "2025-07-29T07:42:56.158Z" }, - { url = "https://files.pythonhosted.org/packages/df/6b/209af927207af77425b044e32f77f49105a0b05d82ff88af6971d8da4e19/mmh3-5.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63", size = 97367, upload-time = "2025-07-29T07:42:57.037Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e0/78adf4104c425606a9ce33fb351f790c76a6c2314969c4a517d1ffc92196/mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12", size = 103306, upload-time = "2025-07-29T07:42:58.522Z" }, - { url = "https://files.pythonhosted.org/packages/a3/79/c2b89f91b962658b890104745b1b6c9ce38d50a889f000b469b91eeb1b9e/mmh3-5.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22", size = 106312, upload-time = "2025-07-29T07:42:59.552Z" }, - { url = "https://files.pythonhosted.org/packages/4b/14/659d4095528b1a209be90934778c5ffe312177d51e365ddcbca2cac2ec7c/mmh3-5.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5", size = 113135, upload-time = "2025-07-29T07:43:00.745Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6f/cd7734a779389a8a467b5c89a48ff476d6f2576e78216a37551a97e9e42a/mmh3-5.2.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07", size = 120775, upload-time = "2025-07-29T07:43:02.124Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ca/8256e3b96944408940de3f9291d7e38a283b5761fe9614d4808fcf27bd62/mmh3-5.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935", size = 99178, upload-time = "2025-07-29T07:43:03.182Z" }, - { url = "https://files.pythonhosted.org/packages/8a/32/39e2b3cf06b6e2eb042c984dab8680841ac2a0d3ca6e0bea30db1f27b565/mmh3-5.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7", size = 98738, upload-time = "2025-07-29T07:43:04.207Z" }, - { url = "https://files.pythonhosted.org/packages/61/d3/7bbc8e0e8cf65ebbe1b893ffa0467b7ecd1bd07c3bbf6c9db4308ada22ec/mmh3-5.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5", size = 106510, upload-time = "2025-07-29T07:43:05.656Z" }, - { url = "https://files.pythonhosted.org/packages/10/99/b97e53724b52374e2f3859046f0eb2425192da356cb19784d64bc17bb1cf/mmh3-5.2.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384", size = 110053, upload-time = "2025-07-29T07:43:07.204Z" }, - { url = "https://files.pythonhosted.org/packages/ac/62/3688c7d975ed195155671df68788c83fed6f7909b6ec4951724c6860cb97/mmh3-5.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e", size = 97546, upload-time = "2025-07-29T07:43:08.226Z" }, - { url = "https://files.pythonhosted.org/packages/ca/3b/c6153250f03f71a8b7634cded82939546cdfba02e32f124ff51d52c6f991/mmh3-5.2.0-cp314-cp314-win32.whl", hash = "sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0", size = 41422, upload-time = "2025-07-29T07:43:09.216Z" }, - { url = "https://files.pythonhosted.org/packages/74/01/a27d98bab083a435c4c07e9d1d720d4c8a578bf4c270bae373760b1022be/mmh3-5.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b", size = 42135, upload-time = "2025-07-29T07:43:10.183Z" }, - { url = "https://files.pythonhosted.org/packages/cb/c9/dbba5507e95429b8b380e2ba091eff5c20a70a59560934dff0ad8392b8c8/mmh3-5.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115", size = 39879, upload-time = "2025-07-29T07:43:11.106Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d1/c8c0ef839c17258b9de41b84f663574fabcf8ac2007b7416575e0f65ff6e/mmh3-5.2.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932", size = 57696, upload-time = "2025-07-29T07:43:11.989Z" }, - { url = "https://files.pythonhosted.org/packages/2f/55/95e2b9ff201e89f9fe37036037ab61a6c941942b25cdb7b6a9df9b931993/mmh3-5.2.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c", size = 41421, upload-time = "2025-07-29T07:43:13.269Z" }, - { url = "https://files.pythonhosted.org/packages/77/79/9be23ad0b7001a4b22752e7693be232428ecc0a35068a4ff5c2f14ef8b20/mmh3-5.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be", size = 40853, upload-time = "2025-07-29T07:43:14.888Z" }, - { url = "https://files.pythonhosted.org/packages/ac/1b/96b32058eda1c1dee8264900c37c359a7325c1f11f5ff14fd2be8e24eff9/mmh3-5.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb", size = 109694, upload-time = "2025-07-29T07:43:15.816Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6f/a2ae44cd7dad697b6dea48390cbc977b1e5ca58fda09628cbcb2275af064/mmh3-5.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65", size = 117438, upload-time = "2025-07-29T07:43:16.865Z" }, - { url = "https://files.pythonhosted.org/packages/a0/08/bfb75451c83f05224a28afeaf3950c7b793c0b71440d571f8e819cfb149a/mmh3-5.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991", size = 120409, upload-time = "2025-07-29T07:43:18.207Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ea/8b118b69b2ff8df568f742387d1a159bc654a0f78741b31437dd047ea28e/mmh3-5.2.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645", size = 125909, upload-time = "2025-07-29T07:43:19.39Z" }, - { url = "https://files.pythonhosted.org/packages/3e/11/168cc0b6a30650032e351a3b89b8a47382da541993a03af91e1ba2501234/mmh3-5.2.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3", size = 135331, upload-time = "2025-07-29T07:43:20.435Z" }, - { url = "https://files.pythonhosted.org/packages/31/05/e3a9849b1c18a7934c64e831492c99e67daebe84a8c2f2c39a7096a830e3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279", size = 110085, upload-time = "2025-07-29T07:43:21.92Z" }, - { url = "https://files.pythonhosted.org/packages/d9/d5/a96bcc306e3404601418b2a9a370baec92af84204528ba659fdfe34c242f/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513", size = 111195, upload-time = "2025-07-29T07:43:23.066Z" }, - { url = "https://files.pythonhosted.org/packages/af/29/0fd49801fec5bff37198684e0849b58e0dab3a2a68382a357cfffb0fafc3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db", size = 116919, upload-time = "2025-07-29T07:43:24.178Z" }, - { url = "https://files.pythonhosted.org/packages/2d/04/4f3c32b0a2ed762edca45d8b46568fc3668e34f00fb1e0a3b5451ec1281c/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667", size = 123160, upload-time = "2025-07-29T07:43:25.26Z" }, - { url = "https://files.pythonhosted.org/packages/91/76/3d29eaa38821730633d6a240d36fa8ad2807e9dfd432c12e1a472ed211eb/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5", size = 110206, upload-time = "2025-07-29T07:43:26.699Z" }, - { url = "https://files.pythonhosted.org/packages/44/1c/ccf35892684d3a408202e296e56843743e0b4fb1629e59432ea88cdb3909/mmh3-5.2.0-cp314-cp314t-win32.whl", hash = "sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7", size = 41970, upload-time = "2025-07-29T07:43:27.666Z" }, - { url = "https://files.pythonhosted.org/packages/75/b2/b9e4f1e5adb5e21eb104588fcee2cd1eaa8308255173481427d5ecc4284e/mmh3-5.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d", size = 43063, upload-time = "2025-07-29T07:43:28.582Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fc/0e61d9a4e29c8679356795a40e48f647b4aad58d71bfc969f0f8f56fb912/mmh3-5.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9", size = 40455, upload-time = "2025-07-29T07:43:29.563Z" }, -] - -[[package]] -name = "mpmath" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, -] - -[[package]] -name = "multidict" -version = "6.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, - { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, - { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, - { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, - { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, - { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, - { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, - { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, - { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, - { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, - { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, - { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, - { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, - { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, - { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, - { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, - { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, - { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, - { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, - { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, - { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, - { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, - { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, - { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, - { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, - { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, - { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, - { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, - { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, - { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, - { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, - { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, - { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, - { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, - { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, - { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, - { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, - { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, - { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, - { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, - { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, - { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, - { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, - { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, - { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, - { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, - { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, - { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, - { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, - { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, - { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, - { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, - { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, - { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, - { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, - { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, - { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, - { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, - { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, - { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, - { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, - { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, - { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, - { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, - { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, - { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, - { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, - { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, - { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, - { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, - { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, - { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, - { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, - { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, - { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, -] - [[package]] name = "mypy" version = "1.19.0" @@ -1231,47 +565,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] -[[package]] -name = "nemoguardrails" -version = "0.19.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "annoy" }, - { name = "fastapi" }, - { name = "fastembed", marker = "python_full_version < '3.14'" }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "langchain" }, - { name = "langchain-community" }, - { name = "langchain-core" }, - { name = "lark" }, - { name = "nest-asyncio" }, - { name = "pandas" }, - { name = "prompt-toolkit" }, - { name = "protobuf" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "rich" }, - { name = "simpleeval" }, - { name = "starlette" }, - { name = "typer" }, - { name = "uvicorn" }, - { name = "watchdog" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/b2/95cf4aa45c8d32c012ecde508cf9a9526b4825b7d8e66128f4b16dfa8bf0/nemoguardrails-0.19.0-py3-none-any.whl", hash = "sha256:1a2de59a942b6d79a8e7c70a3fe92c154d76451db987a411e8e6b641f78f7c77", size = 11317602, upload-time = "2025-12-03T17:26:23.338Z" }, -] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, -] - [[package]] name = "nodeenv" version = "1.9.1" @@ -1281,69 +574,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] -[[package]] -name = "numpy" -version = "2.3.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, - { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, - { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, - { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, - { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, - { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, - { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, - { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, - { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, - { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, - { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, - { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, - { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, - { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, - { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, - { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, - { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, - { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, - { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, - { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, - { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, - { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, - { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, - { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, - { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, - { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, - { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, - { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, - { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, - { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, - { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, - { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, - { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, - { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, - { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, - { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, - { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, - { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, - { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, - { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, - { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, - { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, - { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, - { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, - { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, - { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, - { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, - { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, - { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, - { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, -] - [[package]] name = "ollama" version = "0.6.1" @@ -1370,33 +600,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, ] -[[package]] -name = "onnxruntime" -version = "1.23.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "coloredlogs" }, - { name = "flatbuffers" }, - { name = "numpy" }, - { name = "packaging" }, - { name = "protobuf" }, - { name = "sympy" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/9e/f748cd64161213adeef83d0cb16cb8ace1e62fa501033acdd9f9341fff57/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:b8f029a6b98d3cf5be564d52802bb50a8489ab73409fa9db0bf583eabb7c2321", size = 17195929, upload-time = "2025-10-22T03:47:36.24Z" }, - { url = "https://files.pythonhosted.org/packages/91/9d/a81aafd899b900101988ead7fb14974c8a58695338ab6a0f3d6b0100f30b/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:218295a8acae83905f6f1aed8cacb8e3eb3bd7513a13fe4ba3b2664a19fc4a6b", size = 19157705, upload-time = "2025-10-22T03:46:40.415Z" }, - { url = "https://files.pythonhosted.org/packages/3c/35/4e40f2fba272a6698d62be2cd21ddc3675edfc1a4b9ddefcc4648f115315/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76ff670550dc23e58ea9bc53b5149b99a44e63b34b524f7b8547469aaa0dcb8c", size = 15226915, upload-time = "2025-10-22T03:46:27.773Z" }, - { url = "https://files.pythonhosted.org/packages/ef/88/9cc25d2bafe6bc0d4d3c1db3ade98196d5b355c0b273e6a5dc09c5d5d0d5/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f9b4ae77f8e3c9bee50c27bc1beede83f786fe1d52e99ac85aa8d65a01e9b77", size = 17382649, upload-time = "2025-10-22T03:47:02.782Z" }, - { url = "https://files.pythonhosted.org/packages/c0/b4/569d298f9fc4d286c11c45e85d9ffa9e877af12ace98af8cab52396e8f46/onnxruntime-1.23.2-cp312-cp312-win_amd64.whl", hash = "sha256:25de5214923ce941a3523739d34a520aac30f21e631de53bba9174dc9c004435", size = 13470528, upload-time = "2025-10-22T03:47:28.106Z" }, - { url = "https://files.pythonhosted.org/packages/3d/41/fba0cabccecefe4a1b5fc8020c44febb334637f133acefc7ec492029dd2c/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:2ff531ad8496281b4297f32b83b01cdd719617e2351ffe0dba5684fb283afa1f", size = 17196337, upload-time = "2025-10-22T03:46:35.168Z" }, - { url = "https://files.pythonhosted.org/packages/fe/f9/2d49ca491c6a986acce9f1d1d5fc2099108958cc1710c28e89a032c9cfe9/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:162f4ca894ec3de1a6fd53589e511e06ecdc3ff646849b62a9da7489dee9ce95", size = 19157691, upload-time = "2025-10-22T03:46:43.518Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a1/428ee29c6eaf09a6f6be56f836213f104618fb35ac6cc586ff0f477263eb/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45d127d6e1e9b99d1ebeae9bcd8f98617a812f53f46699eafeb976275744826b", size = 15226898, upload-time = "2025-10-22T03:46:30.039Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2b/b57c8a2466a3126dbe0a792f56ad7290949b02f47b86216cd47d857e4b77/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8bace4e0d46480fbeeb7bbe1ffe1f080e6663a42d1086ff95c1551f2d39e7872", size = 17382518, upload-time = "2025-10-22T03:47:05.407Z" }, - { url = "https://files.pythonhosted.org/packages/4a/93/aba75358133b3a941d736816dd392f687e7eab77215a6e429879080b76b6/onnxruntime-1.23.2-cp313-cp313-win_amd64.whl", hash = "sha256:1f9cc0a55349c584f083c1c076e611a7c35d5b867d5d6e6d6c823bf821978088", size = 13470276, upload-time = "2025-10-22T03:47:31.193Z" }, - { url = "https://files.pythonhosted.org/packages/7c/3d/6830fa61c69ca8e905f237001dbfc01689a4e4ab06147020a4518318881f/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d2385e774f46ac38f02b3a91a91e30263d41b2f1f4f26ae34805b2a9ddef466", size = 15229610, upload-time = "2025-10-22T03:46:32.239Z" }, - { url = "https://files.pythonhosted.org/packages/b6/ca/862b1e7a639460f0ca25fd5b6135fb42cf9deea86d398a92e44dfda2279d/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2b9233c4947907fd1818d0e581c049c41ccc39b2856cc942ff6d26317cee145", size = 17394184, upload-time = "2025-10-22T03:47:08.127Z" }, -] - [[package]] name = "orjson" version = "3.11.5" @@ -1450,6 +653,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/dd/f4fff4a6fe601b4f8f3ba3aa6da8ac33d17d124491a3b804c662a70e1636/orjson-3.11.5-cp314-cp314-win_arm64.whl", hash = "sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5", size = 126713, upload-time = "2025-12-06T15:55:19.738Z" }, ] +[[package]] +name = "ormsgpack" +version = "1.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/96/34c40d621996c2f377a18decbd3c59f031dde73c3ba47d1e1e8f29a05aaa/ormsgpack-1.12.1.tar.gz", hash = "sha256:a3877fde1e4f27a39f92681a0aab6385af3a41d0c25375d33590ae20410ea2ac", size = 39476, upload-time = "2025-12-14T07:57:43.248Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/fe/ab9167ca037406b5703add24049cf3e18021a3b16133ea20615b1f160ea4/ormsgpack-1.12.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4d7fb0e1b6fbc701d75269f7405a4f79230a6ce0063fb1092e4f6577e312f86d", size = 376725, upload-time = "2025-12-14T07:57:07.894Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ea/2820e65f506894c459b840d1091ae6e327fde3d5a3f3b002a11a1b9bdf7d/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43a9353e2db5b024c91a47d864ef15eaa62d81824cfc7740fed4cef7db738694", size = 202466, upload-time = "2025-12-14T07:57:09.049Z" }, + { url = "https://files.pythonhosted.org/packages/45/8b/def01c13339c5bbec2ee1469ef53e7fadd66c8d775df974ee4def1572515/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc8fe866b7706fc25af0adf1f600bc06ece5b15ca44e34641327198b821e5c3c", size = 210748, upload-time = "2025-12-14T07:57:10.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d2/bf350c92f7f067dd9484499705f2d8366d8d9008a670e3d1d0add1908f85/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813755b5f598a78242042e05dfd1ada4e769e94b98c9ab82554550f97ff4d641", size = 211510, upload-time = "2025-12-14T07:57:11.165Z" }, + { url = "https://files.pythonhosted.org/packages/74/92/9d689bcb95304a6da26c4d59439c350940c25d1b35f146d402ccc6344c51/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8eea2a13536fae45d78f93f2cc846c9765c7160c85f19cfefecc20873c137cdd", size = 386237, upload-time = "2025-12-14T07:57:12.306Z" }, + { url = "https://files.pythonhosted.org/packages/17/fe/bd3107547f8b6129265dd957f40b9cd547d2445db2292aacb13335a7ea89/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7a02ebda1a863cbc604740e76faca8eee1add322db2dcbe6cf32669fffdff65c", size = 479589, upload-time = "2025-12-14T07:57:13.475Z" }, + { url = "https://files.pythonhosted.org/packages/c1/7c/e8e5cc9edb967d44f6f85e9ebdad440b59af3fae00b137a4327dc5aed9bb/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c0bd63897c439931cdf29348e5e6e8c330d529830e848d10767615c0f3d1b82", size = 388077, upload-time = "2025-12-14T07:57:14.551Z" }, + { url = "https://files.pythonhosted.org/packages/35/6b/5031797e43b58506f28a8760b26dc23f2620fb4f2200c4c1b3045603e67e/ormsgpack-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:362f2e812f8d7035dc25a009171e09d7cc97cb30d3c9e75a16aeae00ca3c1dcf", size = 116190, upload-time = "2025-12-14T07:57:15.575Z" }, + { url = "https://files.pythonhosted.org/packages/1e/fd/9f43ea6425e383a6b2dbfafebb06fd60e8d68c700ef715adfbcdb499f75d/ormsgpack-1.12.1-cp312-cp312-win_arm64.whl", hash = "sha256:6190281e381db2ed0045052208f47a995ccf61eed48f1215ae3cce3fbccd59c5", size = 109990, upload-time = "2025-12-14T07:57:16.419Z" }, + { url = "https://files.pythonhosted.org/packages/11/42/f110dfe7cf23a52a82e23eb23d9a6a76ae495447d474686dfa758f3d71d6/ormsgpack-1.12.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9663d6b3ecc917c063d61a99169ce196a80f3852e541ae404206836749459279", size = 376746, upload-time = "2025-12-14T07:57:17.699Z" }, + { url = "https://files.pythonhosted.org/packages/11/76/b386e508a8ae207daec240201a81adb26467bf99b163560724e86bd9ff33/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32e85cfbaf01a94a92520e7fe7851cfcfe21a5698299c28ab86194895f9b9233", size = 202489, upload-time = "2025-12-14T07:57:18.807Z" }, + { url = "https://files.pythonhosted.org/packages/ea/0e/5db7a63f387149024572daa3d9512fe8fb14bf4efa0722d6d491bed280e7/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dabfd2c24b59c7c69870a5ecee480dfae914a42a0c2e7c9d971cf531e2ba471a", size = 210757, upload-time = "2025-12-14T07:57:19.893Z" }, + { url = "https://files.pythonhosted.org/packages/64/79/3a9899e57cb57430bd766fc1b4c9ad410cb2ba6070bc8cf6301e7d385768/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bbf2b64afeded34ccd8e25402e4bca038757913931fa0d693078d75563f6f9", size = 211518, upload-time = "2025-12-14T07:57:20.972Z" }, + { url = "https://files.pythonhosted.org/packages/d7/cd/4f41710ae9fe50d7fcbe476793b3c487746d0e1cc194cc0fee42ff6d989b/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9959a71dde1bd0ced84af17facc06a8afada495a34e9cb1bad8e9b20d4c59cef", size = 386251, upload-time = "2025-12-14T07:57:22.099Z" }, + { url = "https://files.pythonhosted.org/packages/bf/54/ba0c97d6231b1f01daafaa520c8cce1e1b7fceaae6fdc1c763925874a7de/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:e9be0e3b62d758f21f5b20e0e06b3a240ec546c4a327bf771f5825462aa74714", size = 479607, upload-time = "2025-12-14T07:57:23.525Z" }, + { url = "https://files.pythonhosted.org/packages/18/75/19a9a97a462776d525baf41cfb7072734528775f0a3d5fbfab3aa7756b9b/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a29d49ab7fdd77ea787818e60cb4ef491708105b9c4c9b0f919201625eb036b5", size = 388062, upload-time = "2025-12-14T07:57:24.616Z" }, + { url = "https://files.pythonhosted.org/packages/a8/6a/ec26e3f44e9632ecd2f43638b7b37b500eaea5d79cab984ad0b94be14f82/ormsgpack-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:c418390b47a1d367e803f6c187f77e4d67c7ae07ba962e3a4a019001f4b0291a", size = 116195, upload-time = "2025-12-14T07:57:25.626Z" }, + { url = "https://files.pythonhosted.org/packages/7d/64/bfa5f4a34d0f15c6aba1b73e73f7441a66d635bd03249d334a4796b7a924/ormsgpack-1.12.1-cp313-cp313-win_arm64.whl", hash = "sha256:cfa22c91cffc10a7fbd43729baff2de7d9c28cef2509085a704168ae31f02568", size = 109986, upload-time = "2025-12-14T07:57:26.569Z" }, + { url = "https://files.pythonhosted.org/packages/87/0e/78e5697164e3223b9b216c13e99f1acbc1ee9833490d68842b13da8ba883/ormsgpack-1.12.1-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b93c91efb1a70751a1902a5b43b27bd8fd38e0ca0365cf2cde2716423c15c3a6", size = 376758, upload-time = "2025-12-14T07:57:27.641Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/3a3cbb64703263d7bbaed7effa3ce78cb9add360a60aa7c544d7df28b641/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf0ea0389167b5fa8d2933dd3f33e887ec4ba68f89c25214d7eec4afd746d22", size = 202487, upload-time = "2025-12-14T07:57:29.051Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2c/807ebe2b77995599bbb1dec8c3f450d5d7dddee14ce3e1e71dc60e2e2a74/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f4c29af837f35af3375070689e781161e7cf019eb2f7cd641734ae45cd001c0d", size = 210853, upload-time = "2025-12-14T07:57:30.508Z" }, + { url = "https://files.pythonhosted.org/packages/25/57/2cdfc354e3ad8e847628f511f4d238799d90e9e090941e50b9d5ba955ae2/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336fc65aa0fe65896a3dabaae31e332a0a98b4a00ad7b0afde21a7505fd23ff3", size = 211545, upload-time = "2025-12-14T07:57:31.585Z" }, + { url = "https://files.pythonhosted.org/packages/76/1d/c6fda560e4a8ff865b3aec8a86f7c95ab53f4532193a6ae4ab9db35f85aa/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:940f60aabfefe71dd6b82cb33f4ff10b2e7f5fcfa5f103cdb0a23b6aae4c713c", size = 386333, upload-time = "2025-12-14T07:57:32.957Z" }, + { url = "https://files.pythonhosted.org/packages/fc/3e/715081b36fceb8b497c68b87d384e1cc6d9c9c130ce3b435634d3d785b86/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:596ad9e1b6d4c95595c54aaf49b1392609ca68f562ce06f4f74a5bc4053bcda4", size = 479701, upload-time = "2025-12-14T07:57:34.686Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cf/01ad04def42b3970fc1a302c07f4b46339edf62ef9650247097260471f40/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:575210e8fcbc7b0375026ba040a5eef223e9f66a4453d9623fc23282ae09c3c8", size = 388148, upload-time = "2025-12-14T07:57:35.771Z" }, + { url = "https://files.pythonhosted.org/packages/15/91/1fff2fc2b5943c740028f339154e7103c8f2edf1a881d9fbba2ce11c3b1d/ormsgpack-1.12.1-cp314-cp314-win_amd64.whl", hash = "sha256:647daa3718572280893456be44c60aea6690b7f2edc54c55648ee66e8f06550f", size = 116201, upload-time = "2025-12-14T07:57:36.763Z" }, + { url = "https://files.pythonhosted.org/packages/ed/66/142b542aed3f96002c7d1c33507ca6e1e0d0a42b9253ab27ef7ed5793bd9/ormsgpack-1.12.1-cp314-cp314-win_arm64.whl", hash = "sha256:a8b3ab762a6deaf1b6490ab46dda0c51528cf8037e0246c40875c6fe9e37b699", size = 110029, upload-time = "2025-12-14T07:57:37.703Z" }, + { url = "https://files.pythonhosted.org/packages/38/b3/ef4494438c90359e1547eaed3c5ec46e2c431d59a3de2af4e70ebd594c49/ormsgpack-1.12.1-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:12087214e436c1f6c28491949571abea759a63111908c4f7266586d78144d7a8", size = 376777, upload-time = "2025-12-14T07:57:38.795Z" }, + { url = "https://files.pythonhosted.org/packages/05/a0/1149a7163f8b0dfbc64bf9099b6f16d102ad3b03bcc11afee198d751da2d/ormsgpack-1.12.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e6d54c14cf86ef13f10ccade94d1e7de146aa9b17d371e18b16e95f329393b7", size = 202490, upload-time = "2025-12-14T07:57:40.168Z" }, + { url = "https://files.pythonhosted.org/packages/68/82/f2ec5e758d6a7106645cca9bb7137d98bce5d363789fa94075be6572057c/ormsgpack-1.12.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f3584d07882b7ea2a1a589f795a3af97fe4c2932b739408e6d1d9d286cad862", size = 211733, upload-time = "2025-12-14T07:57:42.253Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -1459,53 +700,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] -[[package]] -name = "pandas" -version = "2.3.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, - { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, - { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, - { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, - { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, - { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, -] - [[package]] name = "pathspec" version = "0.12.1" @@ -1515,72 +709,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] -[[package]] -name = "pillow" -version = "11.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, - { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, - { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, - { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, - { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, - { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, - { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, - { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, -] - [[package]] name = "platformdirs" version = "4.5.1" @@ -1606,145 +734,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/c4/b2d28e9d2edf4f1713eb3c29307f1a63f3d67cf09bdda29715a36a68921a/pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1", size = 226429, upload-time = "2025-11-22T21:02:40.836Z" }, ] -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wcwidth" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, -] - -[[package]] -name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, - { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, - { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, - { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, - { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, - { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, - { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, - { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, - { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, - { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, - { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, - { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, - { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, - { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, - { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, - { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, - { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, - { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, - { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, - { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, - { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, - { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, - { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, - { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, - { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, - { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, - { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, - { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, - { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, - { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, - { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, - { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, -] - -[[package]] -name = "protobuf" -version = "6.33.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" }, - { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" }, - { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" }, - { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" }, - { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" }, - { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" }, - { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" }, -] - -[[package]] -name = "py-rust-stemmers" -version = "0.1.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/63/4fbc14810c32d2a884e2e94e406a7d5bf8eee53e1103f558433817230342/py_rust_stemmers-0.1.5.tar.gz", hash = "sha256:e9c310cfb5c2470d7c7c8a0484725965e7cab8b1237e106a0863d5741da3e1f7", size = 9388, upload-time = "2025-02-19T13:56:28.708Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e1/ea8ac92454a634b1bb1ee0a89c2f75a4e6afec15a8412527e9bbde8c6b7b/py_rust_stemmers-0.1.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:29772837126a28263bf54ecd1bc709dd569d15a94d5e861937813ce51e8a6df4", size = 286085, upload-time = "2025-02-19T13:55:23.871Z" }, - { url = "https://files.pythonhosted.org/packages/cb/32/fe1cc3d36a19c1ce39792b1ed151ddff5ee1d74c8801f0e93ff36e65f885/py_rust_stemmers-0.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d62410ada44a01e02974b85d45d82f4b4c511aae9121e5f3c1ba1d0bea9126b", size = 272021, upload-time = "2025-02-19T13:55:25.685Z" }, - { url = "https://files.pythonhosted.org/packages/0a/38/b8f94e5e886e7ab181361a0911a14fb923b0d05b414de85f427e773bf445/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b28ef729a4c83c7d9418be3c23c0372493fcccc67e86783ff04596ef8a208cdf", size = 310547, upload-time = "2025-02-19T13:55:26.891Z" }, - { url = "https://files.pythonhosted.org/packages/a9/08/62e97652d359b75335486f4da134a6f1c281f38bd3169ed6ecfb276448c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a979c3f4ff7ad94a0d4cf566ca7bfecebb59e66488cc158e64485cf0c9a7879f", size = 315237, upload-time = "2025-02-19T13:55:28.116Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b9/fc0278432f288d2be4ee4d5cc80fd8013d604506b9b0503e8b8cae4ba1c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c3593d895453fa06bf70a7b76d6f00d06def0f91fc253fe4260920650c5e078", size = 324419, upload-time = "2025-02-19T13:55:29.211Z" }, - { url = "https://files.pythonhosted.org/packages/6b/5b/74e96eaf622fe07e83c5c389d101540e305e25f76a6d0d6fb3d9e0506db8/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:96ccc7fd042ffc3f7f082f2223bb7082ed1423aa6b43d5d89ab23e321936c045", size = 324792, upload-time = "2025-02-19T13:55:30.948Z" }, - { url = "https://files.pythonhosted.org/packages/4f/f7/b76816d7d67166e9313915ad486c21d9e7da0ac02703e14375bb1cb64b5a/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef18cfced2c9c676e0d7d172ba61c3fab2aa6969db64cc8f5ca33a7759efbefe", size = 488014, upload-time = "2025-02-19T13:55:32.066Z" }, - { url = "https://files.pythonhosted.org/packages/b9/ed/7d9bed02f78d85527501f86a867cd5002d97deb791b9a6b1b45b00100010/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:541d4b5aa911381e3d37ec483abb6a2cf2351b4f16d5e8d77f9aa2722956662a", size = 575582, upload-time = "2025-02-19T13:55:34.005Z" }, - { url = "https://files.pythonhosted.org/packages/93/40/eafd1b33688e8e8ae946d1ef25c4dc93f5b685bd104b9c5573405d7e1d30/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ffd946a36e9ac17ca96821963663012e04bc0ee94d21e8b5ae034721070b436c", size = 493267, upload-time = "2025-02-19T13:55:35.294Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6a/15135b69e4fd28369433eb03264d201b1b0040ba534b05eddeb02a276684/py_rust_stemmers-0.1.5-cp312-none-win_amd64.whl", hash = "sha256:6ed61e1207f3b7428e99b5d00c055645c6415bb75033bff2d06394cbe035fd8e", size = 209395, upload-time = "2025-02-19T13:55:36.519Z" }, - { url = "https://files.pythonhosted.org/packages/80/b8/030036311ec25952bf3083b6c105be5dee052a71aa22d5fbeb857ebf8c1c/py_rust_stemmers-0.1.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:398b3a843a9cd4c5d09e726246bc36f66b3d05b0a937996814e91f47708f5db5", size = 286086, upload-time = "2025-02-19T13:55:37.581Z" }, - { url = "https://files.pythonhosted.org/packages/ed/be/0465dcb3a709ee243d464e89231e3da580017f34279d6304de291d65ccb0/py_rust_stemmers-0.1.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e308fc7687901f0c73603203869908f3156fa9c17c4ba010a7fcc98a7a1c5f2", size = 272019, upload-time = "2025-02-19T13:55:39.183Z" }, - { url = "https://files.pythonhosted.org/packages/ab/b6/76ca5b1f30cba36835938b5d9abee0c130c81833d51b9006264afdf8df3c/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9efc4da5e734bdd00612e7506de3d0c9b7abc4b89d192742a0569d0d1fe749", size = 310545, upload-time = "2025-02-19T13:55:40.339Z" }, - { url = "https://files.pythonhosted.org/packages/56/8f/5be87618cea2fe2e70e74115a20724802bfd06f11c7c43514b8288eb6514/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc2cc8d2b36bc05b8b06506199ac63d437360ae38caefd98cd19e479d35afd42", size = 315236, upload-time = "2025-02-19T13:55:41.55Z" }, - { url = "https://files.pythonhosted.org/packages/00/02/ea86a316aee0f0a9d1449ad4dbffff38f4cf0a9a31045168ae8b95d8bdf8/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a231dc6f0b2a5f12a080dfc7abd9e6a4ea0909290b10fd0a4620e5a0f52c3d17", size = 324419, upload-time = "2025-02-19T13:55:42.693Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fd/1612c22545dcc0abe2f30fc08f30a2332f2224dd536fa1508444a9ca0e39/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5845709d48afc8b29e248f42f92431155a3d8df9ba30418301c49c6072b181b0", size = 324794, upload-time = "2025-02-19T13:55:43.896Z" }, - { url = "https://files.pythonhosted.org/packages/66/18/8a547584d7edac9e7ac9c7bdc53228d6f751c0f70a317093a77c386c8ddc/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e48bfd5e3ce9d223bfb9e634dc1425cf93ee57eef6f56aa9a7120ada3990d4be", size = 488014, upload-time = "2025-02-19T13:55:45.088Z" }, - { url = "https://files.pythonhosted.org/packages/3b/87/4619c395b325e26048a6e28a365afed754614788ba1f49b2eefb07621a03/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:35d32f6e7bdf6fd90e981765e32293a8be74def807147dea9fdc1f65d6ce382f", size = 575582, upload-time = "2025-02-19T13:55:46.436Z" }, - { url = "https://files.pythonhosted.org/packages/98/6e/214f1a889142b7df6d716e7f3fea6c41e87bd6c29046aa57e175d452b104/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:191ea8bf922c984631ffa20bf02ef0ad7eec0465baeaed3852779e8f97c7e7a3", size = 493269, upload-time = "2025-02-19T13:55:49.057Z" }, - { url = "https://files.pythonhosted.org/packages/e1/b9/c5185df277576f995ae34418eb2b2ac12f30835412270f9e05c52face521/py_rust_stemmers-0.1.5-cp313-none-win_amd64.whl", hash = "sha256:e564c9efdbe7621704e222b53bac265b0e4fbea788f07c814094f0ec6b80adcf", size = 209397, upload-time = "2025-02-19T13:55:50.853Z" }, -] - [[package]] name = "pycodestyle" version = "2.14.0" @@ -1840,29 +829,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, ] -[[package]] -name = "pydantic-settings" -version = "2.12.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, -] - -[[package]] -name = "pygments" -version = "2.19.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, -] - [[package]] name = "pylint" version = "4.0.4" @@ -1881,45 +847,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/92/d40f5d937517cc489ad848fc4414ecccc7592e4686b9071e09e64f5e378e/pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0", size = 536425, upload-time = "2025-11-30T13:29:02.53Z" }, ] -[[package]] -name = "pyreadline3" -version = "3.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload-time = "2024-09-19T02:40:10.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, -] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, -] - -[[package]] -name = "python-dotenv" -version = "1.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, -] - -[[package]] -name = "pytz" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, -] - [[package]] name = "pyyaml" version = "6.0.3" @@ -1993,81 +920,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, ] -[[package]] -name = "rich" -version = "14.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - -[[package]] -name = "simpleeval" -version = "1.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/6f/15be211749430f52f2c8f0c69158a6fc961c03aac93fa28d44d1a6f5ebc7/simpleeval-1.0.3.tar.gz", hash = "sha256:67bbf246040ac3b57c29cf048657b9cf31d4e7b9d6659684daa08ca8f1e45829", size = 24358, upload-time = "2024-11-02T10:29:46.912Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e9/e58082fbb8cecbb6fb4133033c40cc50c248b1a331582be3a0f39138d65b/simpleeval-1.0.3-py3-none-any.whl", hash = "sha256:e3bdbb8c82c26297c9a153902d0fd1858a6c3774bf53ff4f134788c3f2035c38", size = 15762, upload-time = "2024-11-02T10:29:45.706Z" }, -] - -[[package]] -name = "six" -version = "1.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.45" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/c7/1900b56ce19bff1c26f39a4ce427faec7716c81ac792bfac8b6a9f3dca93/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f", size = 3333760, upload-time = "2025-12-09T22:11:02.66Z" }, - { url = "https://files.pythonhosted.org/packages/0a/93/3be94d96bb442d0d9a60e55a6bb6e0958dd3457751c6f8502e56ef95fed0/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d", size = 3348268, upload-time = "2025-12-09T22:13:49.054Z" }, - { url = "https://files.pythonhosted.org/packages/48/4b/f88ded696e61513595e4a9778f9d3f2bf7332cce4eb0c7cedaabddd6687b/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4", size = 3278144, upload-time = "2025-12-09T22:11:04.14Z" }, - { url = "https://files.pythonhosted.org/packages/ed/6a/310ecb5657221f3e1bd5288ed83aa554923fb5da48d760a9f7622afeb065/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6", size = 3313907, upload-time = "2025-12-09T22:13:50.598Z" }, - { url = "https://files.pythonhosted.org/packages/5c/39/69c0b4051079addd57c84a5bfb34920d87456dd4c90cf7ee0df6efafc8ff/sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953", size = 2112182, upload-time = "2025-12-09T21:39:30.824Z" }, - { url = "https://files.pythonhosted.org/packages/f7/4e/510db49dd89fc3a6e994bee51848c94c48c4a00dc905e8d0133c251f41a7/sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1", size = 2139200, upload-time = "2025-12-09T21:39:32.321Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, - { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, - { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, - { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, - { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, - { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, - { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, - { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, - { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, - { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, - { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, - { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, -] - [[package]] name = "starlette" version = "0.50.0" @@ -2081,18 +933,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, ] -[[package]] -name = "sympy" -version = "1.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mpmath" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, -] - [[package]] name = "tenacity" version = "9.1.2" @@ -2102,31 +942,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" }, ] -[[package]] -name = "tokenizers" -version = "0.22.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "huggingface-hub" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/46/fb6854cec3278fbfa4a75b50232c77622bc517ac886156e6afbfa4d8fc6e/tokenizers-0.22.1.tar.gz", hash = "sha256:61de6522785310a309b3407bac22d99c4db5dba349935e99e4d15ea2226af2d9", size = 363123, upload-time = "2025-09-19T09:49:23.424Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/33/f4b2d94ada7ab297328fc671fed209368ddb82f965ec2224eb1892674c3a/tokenizers-0.22.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59fdb013df17455e5f950b4b834a7b3ee2e0271e6378ccb33aa74d178b513c73", size = 3069318, upload-time = "2025-09-19T09:49:11.848Z" }, - { url = "https://files.pythonhosted.org/packages/1c/58/2aa8c874d02b974990e89ff95826a4852a8b2a273c7d1b4411cdd45a4565/tokenizers-0.22.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d4e484f7b0827021ac5f9f71d4794aaef62b979ab7608593da22b1d2e3c4edc", size = 2926478, upload-time = "2025-09-19T09:49:09.759Z" }, - { url = "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a", size = 3256994, upload-time = "2025-09-19T09:48:56.701Z" }, - { url = "https://files.pythonhosted.org/packages/71/0b/fbfecf42f67d9b7b80fde4aabb2b3110a97fac6585c9470b5bff103a80cb/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38201f15cdb1f8a6843e6563e6e79f4abd053394992b9bbdf5213ea3469b4ae7", size = 3153141, upload-time = "2025-09-19T09:48:59.749Z" }, - { url = "https://files.pythonhosted.org/packages/17/a9/b38f4e74e0817af8f8ef925507c63c6ae8171e3c4cb2d5d4624bf58fca69/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1cbe5454c9a15df1b3443c726063d930c16f047a3cc724b9e6e1a91140e5a21", size = 3508049, upload-time = "2025-09-19T09:49:05.868Z" }, - { url = "https://files.pythonhosted.org/packages/d2/48/dd2b3dac46bb9134a88e35d72e1aa4869579eacc1a27238f1577270773ff/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7d094ae6312d69cc2a872b54b91b309f4f6fbce871ef28eb27b52a98e4d0214", size = 3710730, upload-time = "2025-09-19T09:49:01.832Z" }, - { url = "https://files.pythonhosted.org/packages/93/0e/ccabc8d16ae4ba84a55d41345207c1e2ea88784651a5a487547d80851398/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afd7594a56656ace95cdd6df4cca2e4059d294c5cfb1679c57824b605556cb2f", size = 3412560, upload-time = "2025-09-19T09:49:03.867Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c6/dc3a0db5a6766416c32c034286d7c2d406da1f498e4de04ab1b8959edd00/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ef6063d7a84994129732b47e7915e8710f27f99f3a3260b8a38fc7ccd083f4", size = 3250221, upload-time = "2025-09-19T09:49:07.664Z" }, - { url = "https://files.pythonhosted.org/packages/d7/a6/2c8486eef79671601ff57b093889a345dd3d576713ef047776015dc66de7/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba0a64f450b9ef412c98f6bcd2a50c6df6e2443b560024a09fa6a03189726879", size = 9345569, upload-time = "2025-09-19T09:49:14.214Z" }, - { url = "https://files.pythonhosted.org/packages/6b/16/32ce667f14c35537f5f605fe9bea3e415ea1b0a646389d2295ec348d5657/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:331d6d149fa9c7d632cde4490fb8bbb12337fa3a0232e77892be656464f4b446", size = 9271599, upload-time = "2025-09-19T09:49:16.639Z" }, - { url = "https://files.pythonhosted.org/packages/51/7c/a5f7898a3f6baa3fc2685c705e04c98c1094c523051c805cdd9306b8f87e/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:607989f2ea68a46cb1dfbaf3e3aabdf3f21d8748312dbeb6263d1b3b66c5010a", size = 9533862, upload-time = "2025-09-19T09:49:19.146Z" }, - { url = "https://files.pythonhosted.org/packages/36/65/7e75caea90bc73c1dd8d40438adf1a7bc26af3b8d0a6705ea190462506e1/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a0f307d490295717726598ef6fa4f24af9d484809223bbc253b201c740a06390", size = 9681250, upload-time = "2025-09-19T09:49:21.501Z" }, - { url = "https://files.pythonhosted.org/packages/30/2c/959dddef581b46e6209da82df3b78471e96260e2bc463f89d23b1bf0e52a/tokenizers-0.22.1-cp39-abi3-win32.whl", hash = "sha256:b5120eed1442765cd90b903bb6cfef781fd8fe64e34ccaecbae4c619b7b12a82", size = 2472003, upload-time = "2025-09-19T09:49:27.089Z" }, - { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, -] - [[package]] name = "tomlkit" version = "0.13.3" @@ -2136,33 +951,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] -[[package]] -name = "tqdm" -version = "4.67.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, -] - -[[package]] -name = "typer" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, -] - [[package]] name = "typing-extensions" version = "4.15.0" @@ -2172,19 +960,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] -[[package]] -name = "typing-inspect" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mypy-extensions" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/dc/74/1789779d91f1961fa9438e9a8710cdae6bd138c80d7303996933d117264a/typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78", size = 13825, upload-time = "2023-05-24T20:25:47.612Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/65/f3/107a22063bf27bdccf2024833d3445f4eea42b2e598abfbd46f6a63b6cb0/typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", size = 8827, upload-time = "2023-05-24T20:25:45.287Z" }, -] - [[package]] name = "typing-inspection" version = "0.4.2" @@ -2197,15 +972,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] -[[package]] -name = "tzdata" -version = "2025.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, -] - [[package]] name = "urllib3" version = "2.6.2" @@ -2265,139 +1031,86 @@ wheels = [ ] [[package]] -name = "watchdog" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, -] - -[[package]] -name = "wcwidth" -version = "0.2.14" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, -] - -[[package]] -name = "win32-setctime" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, -] - -[[package]] -name = "yarl" -version = "1.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, - { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, - { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, - { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, - { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, - { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, - { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, - { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, - { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, - { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, - { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, - { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, - { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, - { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, - { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, - { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, - { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, - { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, - { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, - { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, - { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, - { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, - { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, - { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, - { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, - { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, - { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, - { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, - { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, - { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, - { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, - { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, - { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, - { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, - { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, - { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, - { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, - { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, - { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, - { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, - { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, - { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, - { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, - { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, - { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, - { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, - { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, - { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, - { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, - { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, - { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, - { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, - { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, - { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, - { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, - { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, - { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, - { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, - { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, - { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, - { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, - { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, - { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, - { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, - { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, - { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, - { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, - { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, - { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, - { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, - { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +name = "xxhash" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160, upload-time = "2025-10-02T14:37:08.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914, upload-time = "2025-10-02T14:34:38.6Z" }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163, upload-time = "2025-10-02T14:34:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411, upload-time = "2025-10-02T14:34:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883, upload-time = "2025-10-02T14:34:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392, upload-time = "2025-10-02T14:34:45.042Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898, upload-time = "2025-10-02T14:34:46.302Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655, upload-time = "2025-10-02T14:34:47.571Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001, upload-time = "2025-10-02T14:34:49.273Z" }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431, upload-time = "2025-10-02T14:34:50.798Z" }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617, upload-time = "2025-10-02T14:34:51.954Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534, upload-time = "2025-10-02T14:34:53.276Z" }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876, upload-time = "2025-10-02T14:34:54.371Z" }, + { url = "https://files.pythonhosted.org/packages/33/76/35d05267ac82f53ae9b0e554da7c5e281ee61f3cad44c743f0fcd354f211/xxhash-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec", size = 32738, upload-time = "2025-10-02T14:34:55.839Z" }, + { url = "https://files.pythonhosted.org/packages/31/a8/3fbce1cd96534a95e35d5120637bf29b0d7f5d8fa2f6374e31b4156dd419/xxhash-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1", size = 30821, upload-time = "2025-10-02T14:34:57.219Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ea/d387530ca7ecfa183cb358027f1833297c6ac6098223fd14f9782cd0015c/xxhash-3.6.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6", size = 194127, upload-time = "2025-10-02T14:34:59.21Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/71435dcb99874b09a43b8d7c54071e600a7481e42b3e3ce1eb5226a5711a/xxhash-3.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263", size = 212975, upload-time = "2025-10-02T14:35:00.816Z" }, + { url = "https://files.pythonhosted.org/packages/84/7a/c2b3d071e4bb4a90b7057228a99b10d51744878f4a8a6dd643c8bd897620/xxhash-3.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546", size = 212241, upload-time = "2025-10-02T14:35:02.207Z" }, + { url = "https://files.pythonhosted.org/packages/81/5f/640b6eac0128e215f177df99eadcd0f1b7c42c274ab6a394a05059694c5a/xxhash-3.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89", size = 445471, upload-time = "2025-10-02T14:35:03.61Z" }, + { url = "https://files.pythonhosted.org/packages/5e/1e/3c3d3ef071b051cc3abbe3721ffb8365033a172613c04af2da89d5548a87/xxhash-3.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d", size = 193936, upload-time = "2025-10-02T14:35:05.013Z" }, + { url = "https://files.pythonhosted.org/packages/2c/bd/4a5f68381939219abfe1c22a9e3a5854a4f6f6f3c4983a87d255f21f2e5d/xxhash-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7", size = 210440, upload-time = "2025-10-02T14:35:06.239Z" }, + { url = "https://files.pythonhosted.org/packages/eb/37/b80fe3d5cfb9faff01a02121a0f4d565eb7237e9e5fc66e73017e74dcd36/xxhash-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db", size = 197990, upload-time = "2025-10-02T14:35:07.735Z" }, + { url = "https://files.pythonhosted.org/packages/d7/fd/2c0a00c97b9e18f72e1f240ad4e8f8a90fd9d408289ba9c7c495ed7dc05c/xxhash-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42", size = 210689, upload-time = "2025-10-02T14:35:09.438Z" }, + { url = "https://files.pythonhosted.org/packages/93/86/5dd8076a926b9a95db3206aba20d89a7fc14dd5aac16e5c4de4b56033140/xxhash-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11", size = 414068, upload-time = "2025-10-02T14:35:11.162Z" }, + { url = "https://files.pythonhosted.org/packages/af/3c/0bb129170ee8f3650f08e993baee550a09593462a5cddd8e44d0011102b1/xxhash-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd", size = 191495, upload-time = "2025-10-02T14:35:12.971Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3a/6797e0114c21d1725e2577508e24006fd7ff1d8c0c502d3b52e45c1771d8/xxhash-3.6.0-cp313-cp313-win32.whl", hash = "sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799", size = 30620, upload-time = "2025-10-02T14:35:14.129Z" }, + { url = "https://files.pythonhosted.org/packages/86/15/9bc32671e9a38b413a76d24722a2bf8784a132c043063a8f5152d390b0f9/xxhash-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392", size = 31542, upload-time = "2025-10-02T14:35:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/39/c5/cc01e4f6188656e56112d6a8e0dfe298a16934b8c47a247236549a3f7695/xxhash-3.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6", size = 27880, upload-time = "2025-10-02T14:35:16.315Z" }, + { url = "https://files.pythonhosted.org/packages/f3/30/25e5321c8732759e930c555176d37e24ab84365482d257c3b16362235212/xxhash-3.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702", size = 32956, upload-time = "2025-10-02T14:35:17.413Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3c/0573299560d7d9f8ab1838f1efc021a280b5ae5ae2e849034ef3dee18810/xxhash-3.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db", size = 31072, upload-time = "2025-10-02T14:35:18.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1c/52d83a06e417cd9d4137722693424885cc9878249beb3a7c829e74bf7ce9/xxhash-3.6.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54", size = 196409, upload-time = "2025-10-02T14:35:20.31Z" }, + { url = "https://files.pythonhosted.org/packages/e3/8e/c6d158d12a79bbd0b878f8355432075fc82759e356ab5a111463422a239b/xxhash-3.6.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f", size = 215736, upload-time = "2025-10-02T14:35:21.616Z" }, + { url = "https://files.pythonhosted.org/packages/bc/68/c4c80614716345d55071a396cf03d06e34b5f4917a467faf43083c995155/xxhash-3.6.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5", size = 214833, upload-time = "2025-10-02T14:35:23.32Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e9/ae27c8ffec8b953efa84c7c4a6c6802c263d587b9fc0d6e7cea64e08c3af/xxhash-3.6.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1", size = 448348, upload-time = "2025-10-02T14:35:25.111Z" }, + { url = "https://files.pythonhosted.org/packages/d7/6b/33e21afb1b5b3f46b74b6bd1913639066af218d704cc0941404ca717fc57/xxhash-3.6.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee", size = 196070, upload-time = "2025-10-02T14:35:26.586Z" }, + { url = "https://files.pythonhosted.org/packages/96/b6/fcabd337bc5fa624e7203aa0fa7d0c49eed22f72e93229431752bddc83d9/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd", size = 212907, upload-time = "2025-10-02T14:35:28.087Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d3/9ee6160e644d660fcf176c5825e61411c7f62648728f69c79ba237250143/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729", size = 200839, upload-time = "2025-10-02T14:35:29.857Z" }, + { url = "https://files.pythonhosted.org/packages/0d/98/e8de5baa5109394baf5118f5e72ab21a86387c4f89b0e77ef3e2f6b0327b/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292", size = 213304, upload-time = "2025-10-02T14:35:31.222Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1d/71056535dec5c3177eeb53e38e3d367dd1d16e024e63b1cee208d572a033/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf", size = 416930, upload-time = "2025-10-02T14:35:32.517Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6c/5cbde9de2cd967c322e651c65c543700b19e7ae3e0aae8ece3469bf9683d/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033", size = 193787, upload-time = "2025-10-02T14:35:33.827Z" }, + { url = "https://files.pythonhosted.org/packages/19/fa/0172e350361d61febcea941b0cc541d6e6c8d65d153e85f850a7b256ff8a/xxhash-3.6.0-cp313-cp313t-win32.whl", hash = "sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec", size = 30916, upload-time = "2025-10-02T14:35:35.107Z" }, + { url = "https://files.pythonhosted.org/packages/ad/e6/e8cf858a2b19d6d45820f072eff1bea413910592ff17157cabc5f1227a16/xxhash-3.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8", size = 31799, upload-time = "2025-10-02T14:35:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/56/15/064b197e855bfb7b343210e82490ae672f8bc7cdf3ddb02e92f64304ee8a/xxhash-3.6.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746", size = 28044, upload-time = "2025-10-02T14:35:37.195Z" }, + { url = "https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e", size = 32754, upload-time = "2025-10-02T14:35:38.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405", size = 30846, upload-time = "2025-10-02T14:35:39.6Z" }, + { url = "https://files.pythonhosted.org/packages/fe/71/8bc5be2bb00deb5682e92e8da955ebe5fa982da13a69da5a40a4c8db12fb/xxhash-3.6.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3", size = 194343, upload-time = "2025-10-02T14:35:40.69Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/52badfb2aecec2c377ddf1ae75f55db3ba2d321c5e164f14461c90837ef3/xxhash-3.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6", size = 213074, upload-time = "2025-10-02T14:35:42.29Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/ae46b4e9b92e537fa30d03dbc19cdae57ed407e9c26d163895e968e3de85/xxhash-3.6.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063", size = 212388, upload-time = "2025-10-02T14:35:43.929Z" }, + { url = "https://files.pythonhosted.org/packages/f5/80/49f88d3afc724b4ac7fbd664c8452d6db51b49915be48c6982659e0e7942/xxhash-3.6.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7", size = 445614, upload-time = "2025-10-02T14:35:45.216Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b", size = 194024, upload-time = "2025-10-02T14:35:46.959Z" }, + { url = "https://files.pythonhosted.org/packages/78/d1/8e225ff7113bf81545cfdcd79eef124a7b7064a0bba53605ff39590b95c2/xxhash-3.6.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd", size = 210541, upload-time = "2025-10-02T14:35:48.301Z" }, + { url = "https://files.pythonhosted.org/packages/6f/58/0f89d149f0bad89def1a8dd38feb50ccdeb643d9797ec84707091d4cb494/xxhash-3.6.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0", size = 198305, upload-time = "2025-10-02T14:35:49.584Z" }, + { url = "https://files.pythonhosted.org/packages/11/38/5eab81580703c4df93feb5f32ff8fa7fe1e2c51c1f183ee4e48d4bb9d3d7/xxhash-3.6.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152", size = 210848, upload-time = "2025-10-02T14:35:50.877Z" }, + { url = "https://files.pythonhosted.org/packages/5e/6b/953dc4b05c3ce678abca756416e4c130d2382f877a9c30a20d08ee6a77c0/xxhash-3.6.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11", size = 414142, upload-time = "2025-10-02T14:35:52.15Z" }, + { url = "https://files.pythonhosted.org/packages/08/a9/238ec0d4e81a10eb5026d4a6972677cbc898ba6c8b9dbaec12ae001b1b35/xxhash-3.6.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5", size = 191547, upload-time = "2025-10-02T14:35:53.547Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ee/3cf8589e06c2164ac77c3bf0aa127012801128f1feebf2a079272da5737c/xxhash-3.6.0-cp314-cp314-win32.whl", hash = "sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f", size = 31214, upload-time = "2025-10-02T14:35:54.746Z" }, + { url = "https://files.pythonhosted.org/packages/02/5d/a19552fbc6ad4cb54ff953c3908bbc095f4a921bc569433d791f755186f1/xxhash-3.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad", size = 32290, upload-time = "2025-10-02T14:35:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/b1/11/dafa0643bc30442c887b55baf8e73353a344ee89c1901b5a5c54a6c17d39/xxhash-3.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679", size = 28795, upload-time = "2025-10-02T14:35:57.162Z" }, + { url = "https://files.pythonhosted.org/packages/2c/db/0e99732ed7f64182aef4a6fb145e1a295558deec2a746265dcdec12d191e/xxhash-3.6.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4", size = 32955, upload-time = "2025-10-02T14:35:58.267Z" }, + { url = "https://files.pythonhosted.org/packages/55/f4/2a7c3c68e564a099becfa44bb3d398810cc0ff6749b0d3cb8ccb93f23c14/xxhash-3.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67", size = 31072, upload-time = "2025-10-02T14:35:59.382Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d9/72a29cddc7250e8a5819dad5d466facb5dc4c802ce120645630149127e73/xxhash-3.6.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad", size = 196579, upload-time = "2025-10-02T14:36:00.838Z" }, + { url = "https://files.pythonhosted.org/packages/63/93/b21590e1e381040e2ca305a884d89e1c345b347404f7780f07f2cdd47ef4/xxhash-3.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b", size = 215854, upload-time = "2025-10-02T14:36:02.207Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b8/edab8a7d4fa14e924b29be877d54155dcbd8b80be85ea00d2be3413a9ed4/xxhash-3.6.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b", size = 214965, upload-time = "2025-10-02T14:36:03.507Z" }, + { url = "https://files.pythonhosted.org/packages/27/67/dfa980ac7f0d509d54ea0d5a486d2bb4b80c3f1bb22b66e6a05d3efaf6c0/xxhash-3.6.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca", size = 448484, upload-time = "2025-10-02T14:36:04.828Z" }, + { url = "https://files.pythonhosted.org/packages/8c/63/8ffc2cc97e811c0ca5d00ab36604b3ea6f4254f20b7bc658ca825ce6c954/xxhash-3.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a", size = 196162, upload-time = "2025-10-02T14:36:06.182Z" }, + { url = "https://files.pythonhosted.org/packages/4b/77/07f0e7a3edd11a6097e990f6e5b815b6592459cb16dae990d967693e6ea9/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99", size = 213007, upload-time = "2025-10-02T14:36:07.733Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d8/bc5fa0d152837117eb0bef6f83f956c509332ce133c91c63ce07ee7c4873/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3", size = 200956, upload-time = "2025-10-02T14:36:09.106Z" }, + { url = "https://files.pythonhosted.org/packages/26/a5/d749334130de9411783873e9b98ecc46688dad5db64ca6e04b02acc8b473/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6", size = 213401, upload-time = "2025-10-02T14:36:10.585Z" }, + { url = "https://files.pythonhosted.org/packages/89/72/abed959c956a4bfc72b58c0384bb7940663c678127538634d896b1195c10/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93", size = 417083, upload-time = "2025-10-02T14:36:12.276Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b3/62fd2b586283b7d7d665fb98e266decadf31f058f1cf6c478741f68af0cb/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518", size = 193913, upload-time = "2025-10-02T14:36:14.025Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/c19c42c5b3f5a4aad748a6d5b4f23df3bed7ee5445accc65a0fb3ff03953/xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119", size = 31586, upload-time = "2025-10-02T14:36:15.603Z" }, + { url = "https://files.pythonhosted.org/packages/03/d6/4cc450345be9924fd5dc8c590ceda1db5b43a0a889587b0ae81a95511360/xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f", size = 32526, upload-time = "2025-10-02T14:36:16.708Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c9/7243eb3f9eaabd1a88a5a5acadf06df2d83b100c62684b7425c6a11bcaa8/xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95", size = 28898, upload-time = "2025-10-02T14:36:17.843Z" }, ] [[package]] From dea9caf7a3a7f0edfb88c4e3e465c0909184eab6 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 4 Jan 2026 15:19:54 +0000 Subject: [PATCH 038/108] Upgrade type annotations --- services/llm-proxy/main.py | 8 +++----- services/llm-proxy/src/llm_proxy/chat_llm_service.py | 4 +--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 1dd6a4d..76f4e75 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -4,8 +4,6 @@ from contextlib import asynccontextmanager from datetime import datetime from typing import Any -from typing import Dict -from typing import List import json import sys @@ -52,7 +50,7 @@ async def lifespan(_): # type: ignore @app.get('/ping') -async def read_ping() -> Dict[str, str]: +async def read_ping() -> dict[str, str]: """Health check endpoint.""" return {'message': 'Service is running'} @@ -60,8 +58,8 @@ async def read_ping() -> Dict[str, str]: class RequestStreamChatResponse(pydantic.BaseModel): """Request to return the LLM response for a given query and retrieved context.""" user_message: str - chat_history: List[Dict[str, Any]] - context_docs: List[Dict[str, Any]] + chat_history: list[dict[str, Any]] + context_docs: list[dict[str, Any]] @app.post('/stream_chat_response') diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index a9ec4dd..b6eefa2 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -3,8 +3,6 @@ import logging from typing import Any from typing import AsyncIterator -from typing import Dict -from typing import List from langchain_ollama import OllamaLLM, ChatOllama @@ -33,7 +31,7 @@ def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: async def stream_chat_response(self, user_query: str, - chat_history: List[Dict[str, Any]]) -> AsyncIterator[bytes]: + chat_history: list[dict[str, Any]]) -> AsyncIterator[bytes]: """Streams, chunk by chunk, LLM response for a given query and chat history. The input is checkes according to the guardrails specification. From 9ea3d70c94823af8dc3b386c6faafd5e0889731e Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 11:49:42 +0000 Subject: [PATCH 039/108] Replace generic llm with chat model in safety rail --- .../llm-proxy/src/llm_proxy/chat_llm_service.py | 4 ++-- services/llm-proxy/src/llm_proxy/rails/rails.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index b6eefa2..6b4a272 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -4,7 +4,7 @@ from typing import Any from typing import AsyncIterator -from langchain_ollama import OllamaLLM, ChatOllama +from langchain_ollama import ChatOllama from llm_proxy.rails.core import LLMCallContext, Guardrail from llm_proxy.rails import rails @@ -22,7 +22,7 @@ def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: self._input_guardrails: list[Guardrail] = [ rails.ConversationSafetyGuardrail( - llm=OllamaLLM(**models_cfg['conversation_safety_guardrail'])) + llm=ChatOllama(**models_cfg['conversation_safety_guardrail'])) ] self._chat_response_action = llm_actions.ChatResponseAction( diff --git a/services/llm-proxy/src/llm_proxy/rails/rails.py b/services/llm-proxy/src/llm_proxy/rails/rails.py index 2eacd96..ce9e5e4 100644 --- a/services/llm-proxy/src/llm_proxy/rails/rails.py +++ b/services/llm-proxy/src/llm_proxy/rails/rails.py @@ -2,7 +2,8 @@ import logging -from langchain_core.language_models.llms import BaseLLM +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import HumanMessage, SystemMessage from llm_proxy.rails.core import Guardrail, LLMCallContext, GuardrailDecision @@ -41,20 +42,20 @@ class ConversationSafetyGuardrail(Guardrail): 2. A brief explanation of your decision based on the guidelines. """ - def __init__(self, llm: BaseLLM) -> None: + def __init__(self, llm: BaseChatModel) -> None: self._llm = llm async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecision: """Returns true if the conversation is safe, false otherwise.""" - response = await self._llm.agenerate( - [self._MAIN_PROMPT_TEMPLATE.format( - conversation=self._format_conversation(llm_call_context) - )] - ) + messages = [SystemMessage(self._SYSTEM_PROMPT), + HumanMessage(self._MAIN_PROMPT_TEMPLATE.format( + conversation=self._format_conversation(llm_call_context)))] + + response = await self._llm.ainvoke(messages) - decision = response.generations[0][0].text.strip().lower() + decision = str(response.content) decision_lines = [line.strip() for line in decision.split('\n') if line.strip()] _logger().debug('Guardrail \'%s\' response:\n%s', self.name, decision) From ee2bd9960aef66f1fd31cae593038897470df720 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 11:50:10 +0000 Subject: [PATCH 040/108] Fix ollama models names in config --- services/llm-proxy/cfg/main.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index d59ebf9..9a311c2 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -5,9 +5,9 @@ n_server_workers: 1 persist_data_path: data/ models: main_chat: - model: llama3.1:8b + model: local_ollama_model base_url: http://localhost:11434 conversation_safety_guardrail: - model: llama3.1:8b + model: local_ollama_model base_url: http://localhost:11435 \ No newline at end of file From 5fc60f7a26094edd9da0dc9af62b8cb53fba35de Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 11:50:47 +0000 Subject: [PATCH 041/108] Add custom Modelfile for building models in llm-endpoint --- services/llm-endpoint/Modelfile | 22 +++++++++++++++++++ services/llm-endpoint/entrypoint.sh | 7 ++++-- services/llm-endpoint/llm-endpoint.Dockerfile | 2 ++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 services/llm-endpoint/Modelfile diff --git a/services/llm-endpoint/Modelfile b/services/llm-endpoint/Modelfile new file mode 100644 index 0000000..44e21fc --- /dev/null +++ b/services/llm-endpoint/Modelfile @@ -0,0 +1,22 @@ +FROM ${LLM_GENERATOR_MODEL} + +TEMPLATE """ +{{- if .System}}<|start_header_id|>system<|end_header_id|> +{{ .System }}<|eot_id|> +{{- end }} + +{{- range $i, $_ := .Messages }} +{{- $last := eq (len (slice $.Messages $i)) 1 }} + +{{- if eq .Role "user" }}<|start_header_id|>user<|end_header_id|> +{{ .Content }}<|eot_id|> +{{ if $last }}<|start_header_id|>assistant<|end_header_id|>{{ end }} + +{{- else if eq .Role "assistant" }}<|start_header_id|>assistant<|end_header_id|> +{{ .Content }} +{{ if not $last }}<|eot_id|>{{ end }} +{{- end }} +{{- end }} +""" + + diff --git a/services/llm-endpoint/entrypoint.sh b/services/llm-endpoint/entrypoint.sh index 1a6d7ad..7de3ae2 100644 --- a/services/llm-endpoint/entrypoint.sh +++ b/services/llm-endpoint/entrypoint.sh @@ -6,7 +6,10 @@ SERVER_PID=$! echo "Waiting for ollama server to start..." sleep 5 -echo "Pulling the model..." -ollama run "${LLM_GENERATOR_MODEL}" +echo "Creating model from Modelfile..." +sed -i "s/\${LLM_GENERATOR_MODEL}/${LLM_GENERATOR_MODEL}/g" Modelfile +ollama create -f Modelfile local_ollama_model + +ollama run local_ollama_model wait $SERVER_PID \ No newline at end of file diff --git a/services/llm-endpoint/llm-endpoint.Dockerfile b/services/llm-endpoint/llm-endpoint.Dockerfile index 873cc31..7cc0cc3 100644 --- a/services/llm-endpoint/llm-endpoint.Dockerfile +++ b/services/llm-endpoint/llm-endpoint.Dockerfile @@ -3,6 +3,8 @@ FROM ollama/ollama:latest COPY ./entrypoint.sh /root/entrypoint.sh RUN chmod +x /root/entrypoint.sh +COPY ./Modelfile /root/Modelfile + WORKDIR /root EXPOSE ${EXPOSED_PORT} From 06ecd6e30b0db97630fb2cdc9d2bf6e9402feb28 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 12:25:42 +0000 Subject: [PATCH 042/108] Update guard-llm model --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b996cf4..8bedfcb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,7 @@ services: - rag-net environment: - LLM_GENERATOR_MODEL=llama3.1:8b - - OLLAMA_DEBUG=2 + - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11434 guard-llm: @@ -36,8 +36,8 @@ services: networks: - rag-net environment: - - LLM_GENERATOR_MODEL=llama3.1:8b - - OLLAMA_DEBUG=2 + - LLM_GENERATOR_MODEL=dolphin3:8b + - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11435 From 2c7502d91140b10a6f2a02f21310db87aeef8857 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 12:26:06 +0000 Subject: [PATCH 043/108] Debug guard model call Up --- .../src/llm_proxy/chat_llm_service.py | 3 +- .../llm-proxy/src/llm_proxy/rails/rails.py | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 6b4a272..8395140 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -22,7 +22,8 @@ def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: self._input_guardrails: list[Guardrail] = [ rails.ConversationSafetyGuardrail( - llm=ChatOllama(**models_cfg['conversation_safety_guardrail'])) + llm=ChatOllama(**models_cfg['conversation_safety_guardrail'], + temperature=0.0)) ] self._chat_response_action = llm_actions.ChatResponseAction( diff --git a/services/llm-proxy/src/llm_proxy/rails/rails.py b/services/llm-proxy/src/llm_proxy/rails/rails.py index ce9e5e4..41e2260 100644 --- a/services/llm-proxy/src/llm_proxy/rails/rails.py +++ b/services/llm-proxy/src/llm_proxy/rails/rails.py @@ -24,22 +24,28 @@ class ConversationSafetyGuardrail(Guardrail): guidelines.""" _MAIN_PROMPT_TEMPLATE = """ - Your task is to determine whether the given user query is safe and appropriate, according - to the following guidelines: - - - S1. Hate Speech. - - - Pay heed to the entire conversation history when making your decision. - - - {conversation} - - - Your response should contain two lines: - 1. One word: 'safe' if the conversation is safe, or 'unsafe' if it is not. - 2. A brief explanation of your decision based on the guidelines. + Your task is to determine whether the given user query is safe and appropriate, according + to the following guidelines: + + + S1. Sexual content + S2. Sexual exploitation of minors + S3. Hate speech or discriminatory language + S4. Violent or graphic content + S5. Illegal activities + S6. Vulgar or offensive language + + + Pay heed to the entire conversation history when making your decision. + + + {conversation} + + + Your response should contain two lines: + 1. One word: 'safe' if the conversation is safe, or 'unsafe' if it is not. + 2. A brief explanation IN WORDS of your decision based on the guidelines. Do not use + policy category codes, instead use your words. I the conversation is safe, write 'N/A'. """ def __init__(self, llm: BaseChatModel) -> None: From ba66118ec51223b66f63e40a2ab3eb3a19e6db47 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Mon, 5 Jan 2026 12:30:08 +0000 Subject: [PATCH 044/108] Apply pre-commit checks --- services/llm-proxy/cfg/main.yaml | 2 +- services/llm-proxy/main.py | 5 ++--- .../src/llm_proxy/chat_llm_service.py | 6 +++--- .../llm-proxy/src/llm_proxy/llm_actions.py | 19 +++++++++++-------- .../llm-proxy/src/llm_proxy/rails/core.py | 4 ++-- .../llm-proxy/src/llm_proxy/rails/rails.py | 11 ++++++----- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index 9a311c2..db57e1e 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -10,4 +10,4 @@ models: conversation_safety_guardrail: model: local_ollama_model - base_url: http://localhost:11435 \ No newline at end of file + base_url: http://localhost:11435 diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 76f4e75..beb0b1b 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -1,11 +1,11 @@ """"Starts the backend server for the entrypoint service.""" +import json import logging import os +import sys from contextlib import asynccontextmanager from datetime import datetime from typing import Any -import json -import sys import fastapi import hydra @@ -13,7 +13,6 @@ import pydantic import uvicorn from fastapi.responses import StreamingResponse - from llm_proxy import chat_llm_service diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 8395140..5790240 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -5,10 +5,10 @@ from typing import AsyncIterator from langchain_ollama import ChatOllama - -from llm_proxy.rails.core import LLMCallContext, Guardrail -from llm_proxy.rails import rails from llm_proxy import llm_actions +from llm_proxy.rails import rails +from llm_proxy.rails.core import Guardrail +from llm_proxy.rails.core import LLMCallContext def _logger() -> logging.Logger: diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py index ba8ce7f..f58cacd 100644 --- a/services/llm-proxy/src/llm_proxy/llm_actions.py +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -1,18 +1,21 @@ """Contains modules performing LLM-related isolated actions.""" - -from typing import Any, AsyncIterator +from typing import Any +from typing import AsyncIterator from langchain_core.language_models.chat_models import BaseChatModel -from langchain_core.messages import HumanMessage, AIMessage, SystemMessage, BaseMessage +from langchain_core.messages import AIMessage +from langchain_core.messages import BaseMessage +from langchain_core.messages import HumanMessage +from langchain_core.messages import SystemMessage class ChatResponseAction: """Generates chat response for a given user query and chat history.""" _SYSTEM_PROMPT = ( - "You are a helpful AI assistant. Respond to the user query based on the conversation " - "history, i.e. fall back to the chat history when the query refers to previous messages." - "If any context documents are provided, use them to ground your response." + 'You are a helpful AI assistant. Respond to the user query based on the conversation ' + 'history, i.e. fall back to the chat history when the query refers to previous messages.' + 'If any context documents are provided, use them to ground your response.' ) def __init__(self, @@ -38,9 +41,9 @@ async def run(self, messages.append(AIMessage(content=content)) if context_documents: - context_content = "\n\n".join(context_documents) + context_content = '\n\n'.join(context_documents) context_message = ( - "The following context documents are provided to help you answer the user query:\n" + 'The following context documents are provided to help you answer the user query:\n' f"{context_content}" ) messages.append(SystemMessage(content=context_message)) diff --git a/services/llm-proxy/src/llm_proxy/rails/core.py b/services/llm-proxy/src/llm_proxy/rails/core.py index 5c14242..ec10792 100644 --- a/services/llm-proxy/src/llm_proxy/rails/core.py +++ b/services/llm-proxy/src/llm_proxy/rails/core.py @@ -1,7 +1,7 @@ """Contains core guardrails interfaces.""" - -from abc import ABC, abstractmethod import dataclasses +from abc import ABC +from abc import abstractmethod from typing import Any diff --git a/services/llm-proxy/src/llm_proxy/rails/rails.py b/services/llm-proxy/src/llm_proxy/rails/rails.py index 41e2260..d399890 100644 --- a/services/llm-proxy/src/llm_proxy/rails/rails.py +++ b/services/llm-proxy/src/llm_proxy/rails/rails.py @@ -1,11 +1,12 @@ """Contains implementation of input/output/retrieval guardrails.""" - import logging from langchain_core.language_models.chat_models import BaseChatModel -from langchain_core.messages import HumanMessage, SystemMessage - -from llm_proxy.rails.core import Guardrail, LLMCallContext, GuardrailDecision +from langchain_core.messages import HumanMessage +from langchain_core.messages import SystemMessage +from llm_proxy.rails.core import Guardrail +from llm_proxy.rails.core import GuardrailDecision +from llm_proxy.rails.core import LLMCallContext def _logger() -> logging.Logger: @@ -82,7 +83,7 @@ async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecisi @property def name(self) -> str: - return "ConversationSafetyGuardrail" + return 'ConversationSafetyGuardrail' def _format_conversation(self, llm_call_context: LLMCallContext) -> str: From c3810754c8addbfe5415871ccfab5c8c6e72e693 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Tue, 6 Jan 2026 09:59:19 +0100 Subject: [PATCH 045/108] service checsk workflows --- .github/workflows/service-checks.yml | 78 ++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/service-checks.yml diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml new file mode 100644 index 0000000..1eaa175 --- /dev/null +++ b/.github/workflows/service-checks.yml @@ -0,0 +1,78 @@ +name: Service checks + +on: + pull_request: + paths: + - "services/**" + - ".pre-commit-config.yaml" + - "pyproject.toml" + - ".github/workflows/service-checks.yml" + push: + branches: [main] + paths: + - "services/**" + - ".pre-commit-config.yaml" + - "pyproject.toml" + - ".github/workflows/service-checks.yml" + +permissions: + contents: read + +jobs: + changes: + runs-on: ubuntu-latest + outputs: + llm_proxy: ${{ steps.filter.outputs.llm_proxy }} + web_app: ${{ steps.filter.outputs.web_app }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + llm_proxy: + - 'services/llm-proxy/**' + - '.pre-commit-config.yaml' + - 'pyproject.toml' + web_app: + - 'services/web-app/**' + - '.pre-commit-config.yaml' + - 'pyproject.toml' + + precommit-llm-proxy: + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.llm_proxy == 'true' + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v5 + with: + python-version: "3.12" + - name: Install dependencies + working-directory: services/llm-proxy + run: | + uv venv + uv pip install -e ".[dev]" + - name: Run pre-commit + working-directory: services/llm-proxy + run: | + uv run pre-commit run -c ../../.pre-commit-config.yaml --files $(git -C ../.. ls-files services/llm-proxy) + + precommit-web-app: + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.web_app == 'true' + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v5 + with: + python-version: "3.12" + - name: Install dependencies + working-directory: services/web-app + run: | + uv venv + uv pip install -e ".[dev]" + - name: Run pre-commit + working-directory: services/web-app + run: | + uv run pre-commit run -c ../../.pre-commit-config.yaml --files $(git -C ../.. ls-files services/web-app) From 7490d9a1210eb8aee2d5defa94b7175ae6329c21 Mon Sep 17 00:00:00 2001 From: Jan Stryszewski <88140201+yancostrishevsky@users.noreply.github.com> Date: Tue, 6 Jan 2026 10:06:37 +0100 Subject: [PATCH 046/108] Update service-checks.yml --- .github/workflows/service-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 1eaa175..25b6fe7 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -8,7 +8,7 @@ on: - "pyproject.toml" - ".github/workflows/service-checks.yml" push: - branches: [main] + branches: [main, develop] paths: - "services/**" - ".pre-commit-config.yaml" From e1e393d2da0246bcaa357818140e10c08611e969 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:05:11 +0000 Subject: [PATCH 047/108] Add embedding-endpoint service --- docker-compose.yml | 20 +++++++++++++++++++ persist_dir/embedding-endpoint/.gitignore | 2 ++ .../embedding-endpoint.Dockerfile | 10 ++++++++++ services/embedding-endpoint/entrypoint.sh | 12 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 persist_dir/embedding-endpoint/.gitignore create mode 100644 services/embedding-endpoint/embedding-endpoint.Dockerfile create mode 100644 services/embedding-endpoint/entrypoint.sh diff --git a/docker-compose.yml b/docker-compose.yml index 8bedfcb..c06caef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,26 @@ services: - OLLAMA_HOST=0.0.0.0:11435 + + embedding-endpoint: + build: + context: services/embedding-endpoint/ + dockerfile: embedding-endpoint.Dockerfile + args: + EXPOSED_PORT: 11436 + + container_name: embedding-endpoint + ports: + - 11436:11436 + volumes: + - ./persist_dir/embedding-endpoint:/root/.ollama + networks: + - rag-net + environment: + - EMBEDDING_MODEL=nomic-embed-text:v1.5 + - OLLAMA_DEBUG=0 + - OLLAMA_HOST=0.0.0.0:11436 + networks: rag-net: driver: bridge diff --git a/persist_dir/embedding-endpoint/.gitignore b/persist_dir/embedding-endpoint/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/embedding-endpoint/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/services/embedding-endpoint/embedding-endpoint.Dockerfile b/services/embedding-endpoint/embedding-endpoint.Dockerfile new file mode 100644 index 0000000..873cc31 --- /dev/null +++ b/services/embedding-endpoint/embedding-endpoint.Dockerfile @@ -0,0 +1,10 @@ +FROM ollama/ollama:latest + +COPY ./entrypoint.sh /root/entrypoint.sh +RUN chmod +x /root/entrypoint.sh + +WORKDIR /root + +EXPOSE ${EXPOSED_PORT} + +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/services/embedding-endpoint/entrypoint.sh b/services/embedding-endpoint/entrypoint.sh new file mode 100644 index 0000000..2909bb6 --- /dev/null +++ b/services/embedding-endpoint/entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +ollama serve & +SERVER_PID=$! + +echo "Waiting for ollama server to start..." +sleep 5 + +echo "Loading the model..." +ollama pull ${EMBEDDING_MODEL} + +wait $SERVER_PID \ No newline at end of file From bd0213033786388cc31a51e285e792bfa4e0a0f7 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:05:42 +0000 Subject: [PATCH 048/108] Add vector-store service --- docker-compose.yml | 15 +++++++++++++++ persist_dir/vector-store/.gitignore | 2 ++ services/vector-store/vector-store.Dockerfile | 4 ++++ 3 files changed, 21 insertions(+) create mode 100644 persist_dir/vector-store/.gitignore create mode 100644 services/vector-store/vector-store.Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index c06caef..158b02c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,7 +40,22 @@ services: - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11435 + vector-store: + build: + context: services/vector-store/ + dockerfile: vector-store.Dockerfile + args: + EXPOSED_PORT_REST: 6333 + EXPOSED_PORT_GRPC: 6334 + container_name: vector-store + ports: + - 6333:6333 + - 6334:6334 + volumes: + - ./persist_dir/vector-store:/qdrant/storage:z + networks: + - rag-net embedding-endpoint: build: diff --git a/persist_dir/vector-store/.gitignore b/persist_dir/vector-store/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/vector-store/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/services/vector-store/vector-store.Dockerfile b/services/vector-store/vector-store.Dockerfile new file mode 100644 index 0000000..c1d181d --- /dev/null +++ b/services/vector-store/vector-store.Dockerfile @@ -0,0 +1,4 @@ +FROM qdrant/qdrant + +EXPOSE ${EXPOSED_PORT_REST} +EXPOSE ${EXPOSED_PORT_GRPC} From 7a89d8169d9dbcdcf8a68234eae36d0ab3804cdb Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:06:02 +0000 Subject: [PATCH 049/108] Add Devcontainer setup for context-retriever --- .devcontainer/context_retriever/Dockerfile | 21 +++++++++++ .../context_retriever/devcontainer.json | 35 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .devcontainer/context_retriever/Dockerfile create mode 100644 .devcontainer/context_retriever/devcontainer.json diff --git a/.devcontainer/context_retriever/Dockerfile b/.devcontainer/context_retriever/Dockerfile new file mode 100644 index 0000000..67dd575 --- /dev/null +++ b/.devcontainer/context_retriever/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3.12 + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl wget git openssh-client sudo \ + just gcc g++ + +RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash +RUN chown -R appuser:appuser /home/appuser/ + +COPY .devcontainer/scripts/base-setup.sh /tmp/base-setup.sh +RUN chmod +x /tmp/base-setup.sh \ + && USERNAME="appuser" /tmp/base-setup.sh + +USER appuser +WORKDIR /home/appuser/workspace + +RUN wget -qO- https://astral.sh/uv/install.sh | sh \ No newline at end of file diff --git a/.devcontainer/context_retriever/devcontainer.json b/.devcontainer/context_retriever/devcontainer.json new file mode 100644 index 0000000..124c3ac --- /dev/null +++ b/.devcontainer/context_retriever/devcontainer.json @@ -0,0 +1,35 @@ +{ + "name": "context-retriever", + "build": { + "dockerfile": "Dockerfile", + "context": "../.." + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/home/appuser/workspace,type=bind", + "workspaceFolder": "/home/appuser/workspace/services/context-retriever", + "mounts": [ + "type=bind,source=${localEnv:SSH_AUTH_SOCK},target=/ssh-agent" + ], + "remoteUser": "appuser", + "remoteEnv": { + "SSH_AUTH_SOCK": "/ssh-agent", + "GIT_CONFIG_GLOBAL": "/home/appuser/.gitconfig" + }, + "runArgs": [ + "--network=host" + ], + "overrideCommand": true, + "postCreateCommand": "cd /home/appuser/workspace && /bin/bash .devcontainer/res/post_create_command.bash", + "customizations": { + "vscode": { + "extensions": [ + "skellock.just", + "ms-python.python", + "ms-python.pylint", + "ms-python.autopep8", + "tamasfe.even-better-toml", + "VisualStudioExptTeam.vscodeintellicode", + "matangover.mypy" + ] + } + } +} \ No newline at end of file From 537466d478339cb0c306e810d0bd8515e39cf89b Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:06:33 +0000 Subject: [PATCH 050/108] Add basic project configuration --- services/context-retriever/.gitignore | 3 + services/context-retriever/justfile | 20 + services/context-retriever/pyproject.toml | 29 + services/context-retriever/uv.lock | 2074 +++++++++++++++++++++ 4 files changed, 2126 insertions(+) create mode 100644 services/context-retriever/.gitignore create mode 100644 services/context-retriever/justfile create mode 100644 services/context-retriever/pyproject.toml create mode 100644 services/context-retriever/uv.lock diff --git a/services/context-retriever/.gitignore b/services/context-retriever/.gitignore new file mode 100644 index 0000000..a4a2388 --- /dev/null +++ b/services/context-retriever/.gitignore @@ -0,0 +1,3 @@ +src/context_retriever.egg-info/ +data/ +outputs/ diff --git a/services/context-retriever/justfile b/services/context-retriever/justfile new file mode 100644 index 0000000..f8eae92 --- /dev/null +++ b/services/context-retriever/justfile @@ -0,0 +1,20 @@ +# -------------------------------------------------- +# This file contains setup scripts for the project. +# For more info, see: https://github.com/casey/just +# -------------------------------------------------- + +set shell := ["bash", "-c"] + +# Setup virtual environment and install dependencies. +setup-environment: + uv python install 3.12 + uv venv + uv pip install -e .[dev] + +run-server *args: + uv run python main.py "$@" + +# Runs static checks using global pre-commit configuration. +run-precommit: + uv run pre-commit run -c ../../.pre-commit-config.yaml \ + --files `git ls-files --cached --others --exclude-standard` diff --git a/services/context-retriever/pyproject.toml b/services/context-retriever/pyproject.toml new file mode 100644 index 0000000..4813fae --- /dev/null +++ b/services/context-retriever/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "context_retriever" +version = "0.1.0" +requires-python=">=3.12" +dependencies = [ + "hydra-core>=1.3.2", + "requests>=2.32.3", + "uvicorn>=0.38.0", + "fastapi>=0.124.4", + "langchain>=1.2.0", + "langchain-core>=1.2.6", + "langchain-community>=0.4.1", + "langchain-ollama>=1.0.1", + "python-multipart>=0.0.21", + "pypdf>=6.5.0", + "qdrant-client>=1.16.2" +] + +[project.optional-dependencies] +dev = [ + "pylint>=4.0.4", + "autopep8>=2.3.2", + "mypy>=1.19.0", + "pre-commit>=4.5.0" +] diff --git a/services/context-retriever/uv.lock b/services/context-retriever/uv.lock new file mode 100644 index 0000000..0b65641 --- /dev/null +++ b/services/context-retriever/uv.lock @@ -0,0 +1,2074 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version < '3.13'", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/42/32cf8e7704ceb4481406eb87161349abb46a57fee3f008ba9cb610968646/aiohttp-3.13.3.tar.gz", hash = "sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88", size = 7844556, upload-time = "2026-01-03T17:33:05.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/be/4fc11f202955a69e0db803a12a062b8379c970c7c84f4882b6da17337cc1/aiohttp-3.13.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c", size = 739732, upload-time = "2026-01-03T17:30:14.23Z" }, + { url = "https://files.pythonhosted.org/packages/97/2c/621d5b851f94fa0bb7430d6089b3aa970a9d9b75196bc93bb624b0db237a/aiohttp-3.13.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168", size = 494293, upload-time = "2026-01-03T17:30:15.96Z" }, + { url = "https://files.pythonhosted.org/packages/5d/43/4be01406b78e1be8320bb8316dc9c42dbab553d281c40364e0f862d5661c/aiohttp-3.13.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d", size = 493533, upload-time = "2026-01-03T17:30:17.431Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a8/5a35dc56a06a2c90d4742cbf35294396907027f80eea696637945a106f25/aiohttp-3.13.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29", size = 1737839, upload-time = "2026-01-03T17:30:19.422Z" }, + { url = "https://files.pythonhosted.org/packages/bf/62/4b9eeb331da56530bf2e198a297e5303e1c1ebdceeb00fe9b568a65c5a0c/aiohttp-3.13.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3", size = 1703932, upload-time = "2026-01-03T17:30:21.756Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f6/af16887b5d419e6a367095994c0b1332d154f647e7dc2bd50e61876e8e3d/aiohttp-3.13.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d", size = 1771906, upload-time = "2026-01-03T17:30:23.932Z" }, + { url = "https://files.pythonhosted.org/packages/ce/83/397c634b1bcc24292fa1e0c7822800f9f6569e32934bdeef09dae7992dfb/aiohttp-3.13.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463", size = 1871020, upload-time = "2026-01-03T17:30:26Z" }, + { url = "https://files.pythonhosted.org/packages/86/f6/a62cbbf13f0ac80a70f71b1672feba90fdb21fd7abd8dbf25c0105fb6fa3/aiohttp-3.13.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc", size = 1755181, upload-time = "2026-01-03T17:30:27.554Z" }, + { url = "https://files.pythonhosted.org/packages/0a/87/20a35ad487efdd3fba93d5843efdfaa62d2f1479eaafa7453398a44faf13/aiohttp-3.13.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf", size = 1561794, upload-time = "2026-01-03T17:30:29.254Z" }, + { url = "https://files.pythonhosted.org/packages/de/95/8fd69a66682012f6716e1bc09ef8a1a2a91922c5725cb904689f112309c4/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033", size = 1697900, upload-time = "2026-01-03T17:30:31.033Z" }, + { url = "https://files.pythonhosted.org/packages/e5/66/7b94b3b5ba70e955ff597672dad1691333080e37f50280178967aff68657/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f", size = 1728239, upload-time = "2026-01-03T17:30:32.703Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/6f72f77f9f7d74719692ab65a2a0252584bf8d5f301e2ecb4c0da734530a/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679", size = 1740527, upload-time = "2026-01-03T17:30:34.695Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b4/75ec16cbbd5c01bdaf4a05b19e103e78d7ce1ef7c80867eb0ace42ff4488/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423", size = 1554489, upload-time = "2026-01-03T17:30:36.864Z" }, + { url = "https://files.pythonhosted.org/packages/52/8f/bc518c0eea29f8406dcf7ed1f96c9b48e3bc3995a96159b3fc11f9e08321/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce", size = 1767852, upload-time = "2026-01-03T17:30:39.433Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f2/a07a75173124f31f11ea6f863dc44e6f09afe2bca45dd4e64979490deab1/aiohttp-3.13.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a", size = 1722379, upload-time = "2026-01-03T17:30:41.081Z" }, + { url = "https://files.pythonhosted.org/packages/3c/4a/1a3fee7c21350cac78e5c5cef711bac1b94feca07399f3d406972e2d8fcd/aiohttp-3.13.3-cp312-cp312-win32.whl", hash = "sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046", size = 428253, upload-time = "2026-01-03T17:30:42.644Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b7/76175c7cb4eb73d91ad63c34e29fc4f77c9386bba4a65b53ba8e05ee3c39/aiohttp-3.13.3-cp312-cp312-win_amd64.whl", hash = "sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57", size = 455407, upload-time = "2026-01-03T17:30:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/97/8a/12ca489246ca1faaf5432844adbfce7ff2cc4997733e0af120869345643a/aiohttp-3.13.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c", size = 734190, upload-time = "2026-01-03T17:30:45.832Z" }, + { url = "https://files.pythonhosted.org/packages/32/08/de43984c74ed1fca5c014808963cc83cb00d7bb06af228f132d33862ca76/aiohttp-3.13.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9", size = 491783, upload-time = "2026-01-03T17:30:47.466Z" }, + { url = "https://files.pythonhosted.org/packages/17/f8/8dd2cf6112a5a76f81f81a5130c57ca829d101ad583ce57f889179accdda/aiohttp-3.13.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3", size = 490704, upload-time = "2026-01-03T17:30:49.373Z" }, + { url = "https://files.pythonhosted.org/packages/6d/40/a46b03ca03936f832bc7eaa47cfbb1ad012ba1be4790122ee4f4f8cba074/aiohttp-3.13.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf", size = 1720652, upload-time = "2026-01-03T17:30:50.974Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7e/917fe18e3607af92657e4285498f500dca797ff8c918bd7d90b05abf6c2a/aiohttp-3.13.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6", size = 1692014, upload-time = "2026-01-03T17:30:52.729Z" }, + { url = "https://files.pythonhosted.org/packages/71/b6/cefa4cbc00d315d68973b671cf105b21a609c12b82d52e5d0c9ae61d2a09/aiohttp-3.13.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d", size = 1759777, upload-time = "2026-01-03T17:30:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e3/e06ee07b45e59e6d81498b591fc589629be1553abb2a82ce33efe2a7b068/aiohttp-3.13.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261", size = 1861276, upload-time = "2026-01-03T17:30:56.512Z" }, + { url = "https://files.pythonhosted.org/packages/7c/24/75d274228acf35ceeb2850b8ce04de9dd7355ff7a0b49d607ee60c29c518/aiohttp-3.13.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0", size = 1743131, upload-time = "2026-01-03T17:30:58.256Z" }, + { url = "https://files.pythonhosted.org/packages/04/98/3d21dde21889b17ca2eea54fdcff21b27b93f45b7bb94ca029c31ab59dc3/aiohttp-3.13.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730", size = 1556863, upload-time = "2026-01-03T17:31:00.445Z" }, + { url = "https://files.pythonhosted.org/packages/9e/84/da0c3ab1192eaf64782b03971ab4055b475d0db07b17eff925e8c93b3aa5/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91", size = 1682793, upload-time = "2026-01-03T17:31:03.024Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0f/5802ada182f575afa02cbd0ec5180d7e13a402afb7c2c03a9aa5e5d49060/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3", size = 1716676, upload-time = "2026-01-03T17:31:04.842Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8c/714d53bd8b5a4560667f7bbbb06b20c2382f9c7847d198370ec6526af39c/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4", size = 1733217, upload-time = "2026-01-03T17:31:06.868Z" }, + { url = "https://files.pythonhosted.org/packages/7d/79/e2176f46d2e963facea939f5be2d26368ce543622be6f00a12844d3c991f/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998", size = 1552303, upload-time = "2026-01-03T17:31:08.958Z" }, + { url = "https://files.pythonhosted.org/packages/ab/6a/28ed4dea1759916090587d1fe57087b03e6c784a642b85ef48217b0277ae/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0", size = 1763673, upload-time = "2026-01-03T17:31:10.676Z" }, + { url = "https://files.pythonhosted.org/packages/e8/35/4a3daeb8b9fab49240d21c04d50732313295e4bd813a465d840236dd0ce1/aiohttp-3.13.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591", size = 1721120, upload-time = "2026-01-03T17:31:12.575Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9f/d643bb3c5fb99547323e635e251c609fbbc660d983144cfebec529e09264/aiohttp-3.13.3-cp313-cp313-win32.whl", hash = "sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf", size = 427383, upload-time = "2026-01-03T17:31:14.382Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f1/ab0395f8a79933577cdd996dd2f9aa6014af9535f65dddcf88204682fe62/aiohttp-3.13.3-cp313-cp313-win_amd64.whl", hash = "sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e", size = 453899, upload-time = "2026-01-03T17:31:15.958Z" }, + { url = "https://files.pythonhosted.org/packages/99/36/5b6514a9f5d66f4e2597e40dea2e3db271e023eb7a5d22defe96ba560996/aiohttp-3.13.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808", size = 737238, upload-time = "2026-01-03T17:31:17.909Z" }, + { url = "https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415", size = 492292, upload-time = "2026-01-03T17:31:19.919Z" }, + { url = "https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f", size = 493021, upload-time = "2026-01-03T17:31:21.636Z" }, + { url = "https://files.pythonhosted.org/packages/54/d4/438efabdf74e30aeceb890c3290bbaa449780583b1270b00661126b8aae4/aiohttp-3.13.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6", size = 1717263, upload-time = "2026-01-03T17:31:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/71/f2/7bddc7fd612367d1459c5bcf598a9e8f7092d6580d98de0e057eb42697ad/aiohttp-3.13.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687", size = 1669107, upload-time = "2026-01-03T17:31:25.334Z" }, + { url = "https://files.pythonhosted.org/packages/00/5a/1aeaecca40e22560f97610a329e0e5efef5e0b5afdf9f857f0d93839ab2e/aiohttp-3.13.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26", size = 1760196, upload-time = "2026-01-03T17:31:27.394Z" }, + { url = "https://files.pythonhosted.org/packages/f8/f8/0ff6992bea7bd560fc510ea1c815f87eedd745fe035589c71ce05612a19a/aiohttp-3.13.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a", size = 1843591, upload-time = "2026-01-03T17:31:29.238Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1", size = 1720277, upload-time = "2026-01-03T17:31:31.053Z" }, + { url = "https://files.pythonhosted.org/packages/84/45/23f4c451d8192f553d38d838831ebbc156907ea6e05557f39563101b7717/aiohttp-3.13.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25", size = 1548575, upload-time = "2026-01-03T17:31:32.87Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ed/0a42b127a43712eda7807e7892c083eadfaf8429ca8fb619662a530a3aab/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603", size = 1679455, upload-time = "2026-01-03T17:31:34.76Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b5/c05f0c2b4b4fe2c9d55e73b6d3ed4fd6c9dc2684b1d81cbdf77e7fad9adb/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a", size = 1687417, upload-time = "2026-01-03T17:31:36.699Z" }, + { url = "https://files.pythonhosted.org/packages/c9/6b/915bc5dad66aef602b9e459b5a973529304d4e89ca86999d9d75d80cbd0b/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926", size = 1729968, upload-time = "2026-01-03T17:31:38.622Z" }, + { url = "https://files.pythonhosted.org/packages/11/3b/e84581290a9520024a08640b63d07673057aec5ca548177a82026187ba73/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba", size = 1545690, upload-time = "2026-01-03T17:31:40.57Z" }, + { url = "https://files.pythonhosted.org/packages/f5/04/0c3655a566c43fd647c81b895dfe361b9f9ad6d58c19309d45cff52d6c3b/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c", size = 1746390, upload-time = "2026-01-03T17:31:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/71165b26978f719c3419381514c9690bd5980e764a09440a10bb816ea4ab/aiohttp-3.13.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43", size = 1702188, upload-time = "2026-01-03T17:31:44.984Z" }, + { url = "https://files.pythonhosted.org/packages/29/a7/cbe6c9e8e136314fa1980da388a59d2f35f35395948a08b6747baebb6aa6/aiohttp-3.13.3-cp314-cp314-win32.whl", hash = "sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1", size = 433126, upload-time = "2026-01-03T17:31:47.463Z" }, + { url = "https://files.pythonhosted.org/packages/de/56/982704adea7d3b16614fc5936014e9af85c0e34b58f9046655817f04306e/aiohttp-3.13.3-cp314-cp314-win_amd64.whl", hash = "sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984", size = 459128, upload-time = "2026-01-03T17:31:49.2Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2a/3c79b638a9c3d4658d345339d22070241ea341ed4e07b5ac60fb0f418003/aiohttp-3.13.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c", size = 769512, upload-time = "2026-01-03T17:31:51.134Z" }, + { url = "https://files.pythonhosted.org/packages/29/b9/3e5014d46c0ab0db8707e0ac2711ed28c4da0218c358a4e7c17bae0d8722/aiohttp-3.13.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592", size = 506444, upload-time = "2026-01-03T17:31:52.85Z" }, + { url = "https://files.pythonhosted.org/packages/90/03/c1d4ef9a054e151cd7839cdc497f2638f00b93cbe8043983986630d7a80c/aiohttp-3.13.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f", size = 510798, upload-time = "2026-01-03T17:31:54.91Z" }, + { url = "https://files.pythonhosted.org/packages/ea/76/8c1e5abbfe8e127c893fe7ead569148a4d5a799f7cf958d8c09f3eedf097/aiohttp-3.13.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29", size = 1868835, upload-time = "2026-01-03T17:31:56.733Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ac/984c5a6f74c363b01ff97adc96a3976d9c98940b8969a1881575b279ac5d/aiohttp-3.13.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc", size = 1720486, upload-time = "2026-01-03T17:31:58.65Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9a/b7039c5f099c4eb632138728828b33428585031a1e658d693d41d07d89d1/aiohttp-3.13.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2", size = 1847951, upload-time = "2026-01-03T17:32:00.989Z" }, + { url = "https://files.pythonhosted.org/packages/3c/02/3bec2b9a1ba3c19ff89a43a19324202b8eb187ca1e928d8bdac9bbdddebd/aiohttp-3.13.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587", size = 1941001, upload-time = "2026-01-03T17:32:03.122Z" }, + { url = "https://files.pythonhosted.org/packages/37/df/d879401cedeef27ac4717f6426c8c36c3091c6e9f08a9178cc87549c537f/aiohttp-3.13.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8", size = 1797246, upload-time = "2026-01-03T17:32:05.255Z" }, + { url = "https://files.pythonhosted.org/packages/8d/15/be122de1f67e6953add23335c8ece6d314ab67c8bebb3f181063010795a7/aiohttp-3.13.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632", size = 1627131, upload-time = "2026-01-03T17:32:07.607Z" }, + { url = "https://files.pythonhosted.org/packages/12/12/70eedcac9134cfa3219ab7af31ea56bc877395b1ac30d65b1bc4b27d0438/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64", size = 1795196, upload-time = "2026-01-03T17:32:09.59Z" }, + { url = "https://files.pythonhosted.org/packages/32/11/b30e1b1cd1f3054af86ebe60df96989c6a414dd87e27ad16950eee420bea/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0", size = 1782841, upload-time = "2026-01-03T17:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/88/0d/d98a9367b38912384a17e287850f5695c528cff0f14f791ce8ee2e4f7796/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56", size = 1795193, upload-time = "2026-01-03T17:32:13.705Z" }, + { url = "https://files.pythonhosted.org/packages/43/a5/a2dfd1f5ff5581632c7f6a30e1744deda03808974f94f6534241ef60c751/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72", size = 1621979, upload-time = "2026-01-03T17:32:15.965Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/12973c382ae7c1cccbc4417e129c5bf54c374dfb85af70893646e1f0e749/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df", size = 1822193, upload-time = "2026-01-03T17:32:18.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/5f/24155e30ba7f8c96918af1350eb0663e2430aad9e001c0489d89cd708ab1/aiohttp-3.13.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa", size = 1769801, upload-time = "2026-01-03T17:32:20.25Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f8/7314031ff5c10e6ece114da79b338ec17eeff3a079e53151f7e9f43c4723/aiohttp-3.13.3-cp314-cp314t-win32.whl", hash = "sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767", size = 466523, upload-time = "2026-01-03T17:32:22.215Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/278a98c715ae467624eafe375542d8ba9b4383a016df8fdefe0ae28382a7/aiohttp-3.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344", size = 499694, upload-time = "2026-01-03T17:32:24.546Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "antlr4-python3-runtime" +version = "4.9.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/38/7859ff46355f76f8d19459005ca000b6e7012f2f1ca597746cbcd1fbfe5e/antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b", size = 117034, upload-time = "2021-11-06T17:52:23.524Z" } + +[[package]] +name = "anyio" +version = "4.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, +] + +[[package]] +name = "astroid" +version = "4.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/c17d0f83016532a1ad87d1de96837164c99d47a3b6bbba28bd597c25b37a/astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", size = 406224, upload-time = "2026-01-03T22:14:26.096Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/66/686ac4fc6ef48f5bacde625adac698f41d5316a9753c2b20bb0931c9d4e2/astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14", size = 276443, upload-time = "2026-01-03T22:14:24.412Z" }, +] + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "autopep8" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycodestyle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210, upload-time = "2025-01-14T14:46:18.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807, upload-time = "2025-01-14T14:46:15.466Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "context-retriever" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "fastapi" }, + { name = "hydra-core" }, + { name = "langchain" }, + { name = "langchain-community" }, + { name = "langchain-core" }, + { name = "langchain-ollama" }, + { name = "pypdf" }, + { name = "python-multipart" }, + { name = "qdrant-client" }, + { name = "requests" }, + { name = "uvicorn" }, +] + +[package.optional-dependencies] +dev = [ + { name = "autopep8" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pylint" }, +] + +[package.metadata] +requires-dist = [ + { name = "autopep8", marker = "extra == 'dev'", specifier = ">=2.3.2" }, + { name = "fastapi", specifier = ">=0.124.4" }, + { name = "hydra-core", specifier = ">=1.3.2" }, + { name = "langchain", specifier = ">=1.2.0" }, + { name = "langchain-community", specifier = ">=0.4.1" }, + { name = "langchain-core", specifier = ">=1.2.6" }, + { name = "langchain-ollama", specifier = ">=1.0.1" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, + { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, + { name = "pypdf", specifier = ">=6.5.0" }, + { name = "python-multipart", specifier = ">=0.0.21" }, + { name = "qdrant-client", specifier = ">=1.16.2" }, + { name = "requests", specifier = ">=2.32.3" }, + { name = "uvicorn", specifier = ">=0.38.0" }, +] +provides-extras = ["dev"] + +[[package]] +name = "dataclasses-json" +version = "0.6.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marshmallow" }, + { name = "typing-inspect" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227, upload-time = "2024-06-09T16:20:19.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686, upload-time = "2024-06-09T16:20:16.715Z" }, +] + +[[package]] +name = "dill" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "fastapi" +version = "0.128.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/08/8c8508db6c7b9aae8f7175046af41baad690771c9bcde676419965e338c7/fastapi-0.128.0.tar.gz", hash = "sha256:1cc179e1cef10a6be60ffe429f79b829dce99d8de32d7acb7e6c8dfdf7f2645a", size = 365682, upload-time = "2025-12-27T15:21:13.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/05/5cbb59154b093548acd0f4c7c474a118eda06da25aa75c616b72d8fcd92a/fastapi-0.128.0-py3-none-any.whl", hash = "sha256:aebd93f9716ee3b4f4fcfe13ffb7cf308d99c9f3ab5622d8877441072561582d", size = 103094, upload-time = "2025-12-27T15:21:12.154Z" }, +] + +[[package]] +name = "filelock" +version = "3.20.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/e0/a75dbe4bca1e7d41307323dad5ea2efdd95408f74ab2de8bd7dba9b51a1a/filelock-3.20.2.tar.gz", hash = "sha256:a2241ff4ddde2a7cebddf78e39832509cb045d18ec1a09d7248d6bfc6bfbbe64", size = 19510, upload-time = "2026-01-02T15:33:32.582Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/30/ab407e2ec752aa541704ed8f93c11e2a5d92c168b8a755d818b74a3c5c2d/filelock-3.20.2-py3-none-any.whl", hash = "sha256:fbba7237d6ea277175a32c54bb71ef814a8546d8601269e1bfc388de333974e8", size = 16697, upload-time = "2026-01-02T15:33:31.133Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "greenlet" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, + { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, + { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, + { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, + { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, + { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, + { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, + { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, + { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, + { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" }, + { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, + { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, + { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, + { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, + { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, +] + +[[package]] +name = "grpcio" +version = "1.76.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/e0/318c1ce3ae5a17894d5791e87aea147587c9e702f24122cc7a5c8bbaeeb1/grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73", size = 12785182, upload-time = "2025-10-21T16:23:12.106Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/05/8e29121994b8d959ffa0afd28996d452f291b48cfc0875619de0bde2c50c/grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8", size = 5799718, upload-time = "2025-10-21T16:21:17.939Z" }, + { url = "https://files.pythonhosted.org/packages/d9/75/11d0e66b3cdf998c996489581bdad8900db79ebd83513e45c19548f1cba4/grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280", size = 11825627, upload-time = "2025-10-21T16:21:20.466Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/2f0aa0498bc188048f5d9504dcc5c2c24f2eb1a9337cd0fa09a61a2e75f0/grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4", size = 6359167, upload-time = "2025-10-21T16:21:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/66/e5/bbf0bb97d29ede1d59d6588af40018cfc345b17ce979b7b45424628dc8bb/grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11", size = 7044267, upload-time = "2025-10-21T16:21:25.995Z" }, + { url = "https://files.pythonhosted.org/packages/f5/86/f6ec2164f743d9609691115ae8ece098c76b894ebe4f7c94a655c6b03e98/grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6", size = 6573963, upload-time = "2025-10-21T16:21:28.631Z" }, + { url = "https://files.pythonhosted.org/packages/60/bc/8d9d0d8505feccfdf38a766d262c71e73639c165b311c9457208b56d92ae/grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8", size = 7164484, upload-time = "2025-10-21T16:21:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/67/e6/5d6c2fc10b95edf6df9b8f19cf10a34263b7fd48493936fffd5085521292/grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980", size = 8127777, upload-time = "2025-10-21T16:21:33.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c8/dce8ff21c86abe025efe304d9e31fdb0deaaa3b502b6a78141080f206da0/grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882", size = 7594014, upload-time = "2025-10-21T16:21:41.882Z" }, + { url = "https://files.pythonhosted.org/packages/e0/42/ad28191ebf983a5d0ecef90bab66baa5a6b18f2bfdef9d0a63b1973d9f75/grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958", size = 3984750, upload-time = "2025-10-21T16:21:44.006Z" }, + { url = "https://files.pythonhosted.org/packages/9e/00/7bd478cbb851c04a48baccaa49b75abaa8e4122f7d86da797500cccdd771/grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347", size = 4704003, upload-time = "2025-10-21T16:21:46.244Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ed/71467ab770effc9e8cef5f2e7388beb2be26ed642d567697bb103a790c72/grpcio-1.76.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:26ef06c73eb53267c2b319f43e6634c7556ea37672029241a056629af27c10e2", size = 5807716, upload-time = "2025-10-21T16:21:48.475Z" }, + { url = "https://files.pythonhosted.org/packages/2c/85/c6ed56f9817fab03fa8a111ca91469941fb514e3e3ce6d793cb8f1e1347b/grpcio-1.76.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:45e0111e73f43f735d70786557dc38141185072d7ff8dc1829d6a77ac1471468", size = 11821522, upload-time = "2025-10-21T16:21:51.142Z" }, + { url = "https://files.pythonhosted.org/packages/ac/31/2b8a235ab40c39cbc141ef647f8a6eb7b0028f023015a4842933bc0d6831/grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:83d57312a58dcfe2a3a0f9d1389b299438909a02db60e2f2ea2ae2d8034909d3", size = 6362558, upload-time = "2025-10-21T16:21:54.213Z" }, + { url = "https://files.pythonhosted.org/packages/bd/64/9784eab483358e08847498ee56faf8ff6ea8e0a4592568d9f68edc97e9e9/grpcio-1.76.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3e2a27c89eb9ac3d81ec8835e12414d73536c6e620355d65102503064a4ed6eb", size = 7049990, upload-time = "2025-10-21T16:21:56.476Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/8c12319a6369434e7a184b987e8e9f3b49a114c489b8315f029e24de4837/grpcio-1.76.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61f69297cba3950a524f61c7c8ee12e55c486cb5f7db47ff9dcee33da6f0d3ae", size = 6575387, upload-time = "2025-10-21T16:21:59.051Z" }, + { url = "https://files.pythonhosted.org/packages/15/0f/f12c32b03f731f4a6242f771f63039df182c8b8e2cf8075b245b409259d4/grpcio-1.76.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a15c17af8839b6801d554263c546c69c4d7718ad4321e3166175b37eaacca77", size = 7166668, upload-time = "2025-10-21T16:22:02.049Z" }, + { url = "https://files.pythonhosted.org/packages/ff/2d/3ec9ce0c2b1d92dd59d1c3264aaec9f0f7c817d6e8ac683b97198a36ed5a/grpcio-1.76.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25a18e9810fbc7e7f03ec2516addc116a957f8cbb8cbc95ccc80faa072743d03", size = 8124928, upload-time = "2025-10-21T16:22:04.984Z" }, + { url = "https://files.pythonhosted.org/packages/1a/74/fd3317be5672f4856bcdd1a9e7b5e17554692d3db9a3b273879dc02d657d/grpcio-1.76.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:931091142fd8cc14edccc0845a79248bc155425eee9a98b2db2ea4f00a235a42", size = 7589983, upload-time = "2025-10-21T16:22:07.881Z" }, + { url = "https://files.pythonhosted.org/packages/45/bb/ca038cf420f405971f19821c8c15bcbc875505f6ffadafe9ffd77871dc4c/grpcio-1.76.0-cp313-cp313-win32.whl", hash = "sha256:5e8571632780e08526f118f74170ad8d50fb0a48c23a746bef2a6ebade3abd6f", size = 3984727, upload-time = "2025-10-21T16:22:10.032Z" }, + { url = "https://files.pythonhosted.org/packages/41/80/84087dc56437ced7cdd4b13d7875e7439a52a261e3ab4e06488ba6173b0a/grpcio-1.76.0-cp313-cp313-win_amd64.whl", hash = "sha256:f9f7bd5faab55f47231ad8dba7787866b69f5e93bc306e3915606779bbfb4ba8", size = 4702799, upload-time = "2025-10-21T16:22:12.709Z" }, + { url = "https://files.pythonhosted.org/packages/b4/46/39adac80de49d678e6e073b70204091e76631e03e94928b9ea4ecf0f6e0e/grpcio-1.76.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:ff8a59ea85a1f2191a0ffcc61298c571bc566332f82e5f5be1b83c9d8e668a62", size = 5808417, upload-time = "2025-10-21T16:22:15.02Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f5/a4531f7fb8b4e2a60b94e39d5d924469b7a6988176b3422487be61fe2998/grpcio-1.76.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:06c3d6b076e7b593905d04fdba6a0525711b3466f43b3400266f04ff735de0cd", size = 11828219, upload-time = "2025-10-21T16:22:17.954Z" }, + { url = "https://files.pythonhosted.org/packages/4b/1c/de55d868ed7a8bd6acc6b1d6ddc4aa36d07a9f31d33c912c804adb1b971b/grpcio-1.76.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd5ef5932f6475c436c4a55e4336ebbe47bd3272be04964a03d316bbf4afbcbc", size = 6367826, upload-time = "2025-10-21T16:22:20.721Z" }, + { url = "https://files.pythonhosted.org/packages/59/64/99e44c02b5adb0ad13ab3adc89cb33cb54bfa90c74770f2607eea629b86f/grpcio-1.76.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b331680e46239e090f5b3cead313cc772f6caa7d0fc8de349337563125361a4a", size = 7049550, upload-time = "2025-10-21T16:22:23.637Z" }, + { url = "https://files.pythonhosted.org/packages/43/28/40a5be3f9a86949b83e7d6a2ad6011d993cbe9b6bd27bea881f61c7788b6/grpcio-1.76.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2229ae655ec4e8999599469559e97630185fdd53ae1e8997d147b7c9b2b72cba", size = 6575564, upload-time = "2025-10-21T16:22:26.016Z" }, + { url = "https://files.pythonhosted.org/packages/4b/a9/1be18e6055b64467440208a8559afac243c66a8b904213af6f392dc2212f/grpcio-1.76.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:490fa6d203992c47c7b9e4a9d39003a0c2bcc1c9aa3c058730884bbbb0ee9f09", size = 7176236, upload-time = "2025-10-21T16:22:28.362Z" }, + { url = "https://files.pythonhosted.org/packages/0f/55/dba05d3fcc151ce6e81327541d2cc8394f442f6b350fead67401661bf041/grpcio-1.76.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:479496325ce554792dba6548fae3df31a72cef7bad71ca2e12b0e58f9b336bfc", size = 8125795, upload-time = "2025-10-21T16:22:31.075Z" }, + { url = "https://files.pythonhosted.org/packages/4a/45/122df922d05655f63930cf42c9e3f72ba20aadb26c100ee105cad4ce4257/grpcio-1.76.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c9b93f79f48b03ada57ea24725d83a30284a012ec27eab2cf7e50a550cbbbcc", size = 7592214, upload-time = "2025-10-21T16:22:33.831Z" }, + { url = "https://files.pythonhosted.org/packages/4a/6e/0b899b7f6b66e5af39e377055fb4a6675c9ee28431df5708139df2e93233/grpcio-1.76.0-cp314-cp314-win32.whl", hash = "sha256:747fa73efa9b8b1488a95d0ba1039c8e2dca0f741612d80415b1e1c560febf4e", size = 4062961, upload-time = "2025-10-21T16:22:36.468Z" }, + { url = "https://files.pythonhosted.org/packages/19/41/0b430b01a2eb38ee887f88c1f07644a1df8e289353b78e82b37ef988fb64/grpcio-1.76.0-cp314-cp314-win_amd64.whl", hash = "sha256:922fa70ba549fce362d2e2871ab542082d66e2aaf0c19480ea453905b01f384e", size = 4834462, upload-time = "2025-10-21T16:22:39.772Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "h2" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack" }, + { name = "hyperframe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, +] + +[[package]] +name = "hpack" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/48/71de9ed269fdae9c8057e5a4c0aa7402e8bb16f2c6e90b3aa53327b113f8/hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca", size = 51276, upload-time = "2025-01-22T21:44:58.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/c6/80c95b1b2b94682a72cbdbfb85b81ae2daffa4291fbfa1b1464502ede10d/hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496", size = 34357, upload-time = "2025-01-22T21:44:56.92Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[package.optional-dependencies] +http2 = [ + { name = "h2" }, +] + +[[package]] +name = "httpx-sse" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943, upload-time = "2025-10-10T21:48:22.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" }, +] + +[[package]] +name = "hydra-core" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "omegaconf" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/8e/07e42bc434a847154083b315779b0a81d567154504624e181caf2c71cd98/hydra-core-1.3.2.tar.gz", hash = "sha256:8a878ed67216997c3e9d88a8e72e7b4767e81af37afb4ea3334b269a4390a824", size = 3263494, upload-time = "2023-02-23T18:33:43.03Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/50/e0edd38dcd63fb26a8547f13d28f7a008bc4a3fd4eb4ff030673f22ad41a/hydra_core-1.3.2-py3-none-any.whl", hash = "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b", size = 154547, upload-time = "2023-02-23T18:33:40.801Z" }, +] + +[[package]] +name = "hyperframe" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload-time = "2025-01-22T21:41:49.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload-time = "2025-01-22T21:41:47.295Z" }, +] + +[[package]] +name = "identify" +version = "2.6.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "isort" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpointer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699, upload-time = "2023-06-26T12:07:29.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898, upload-time = "2023-06-16T21:01:28.466Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, +] + +[[package]] +name = "langchain" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/12/3a74c22abdfddd877dfc2ee666d516f9132877fcd25eb4dd694835c59c79/langchain-1.2.0.tar.gz", hash = "sha256:a087d1e2b2969819e29a91a6d5f98302aafe31bd49ba377ecee3bf5a5dcfe14a", size = 536126, upload-time = "2025-12-15T14:51:42.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/00/4e3fa0d90f5a5c376ccb8ca983d0f0f7287783dfac48702e18f01d24673b/langchain-1.2.0-py3-none-any.whl", hash = "sha256:82f0d17aa4fbb11560b30e1e7d4aeb75e3ad71ce09b85c90ab208b181a24ffac", size = 102828, upload-time = "2025-12-15T14:51:40.802Z" }, +] + +[[package]] +name = "langchain-classic" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langchain-text-splitters" }, + { name = "langsmith" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/4b/bd03518418ece4c13192a504449b58c28afee915dc4a6f4b02622458cb1b/langchain_classic-1.0.1.tar.gz", hash = "sha256:40a499684df36b005a1213735dc7f8dca8f5eb67978d6ec763e7a49780864fdc", size = 10516020, upload-time = "2025-12-23T22:55:22.615Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/0f/eab87f017d7fe28e8c11fff614f4cdbfae32baadb77d0f79e9f922af1df2/langchain_classic-1.0.1-py3-none-any.whl", hash = "sha256:131d83a02bb80044c68fedc1ab4ae885d5b8f8c2c742d8ab9e7534ad9cda8e80", size = 1040666, upload-time = "2025-12-23T22:55:21.025Z" }, +] + +[[package]] +name = "langchain-community" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "dataclasses-json" }, + { name = "httpx-sse" }, + { name = "langchain-classic" }, + { name = "langchain-core" }, + { name = "langsmith" }, + { name = "numpy" }, + { name = "pydantic-settings" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, + { name = "tenacity" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/97/a03585d42b9bdb6fbd935282d6e3348b10322a24e6ce12d0c99eb461d9af/langchain_community-0.4.1.tar.gz", hash = "sha256:f3b211832728ee89f169ddce8579b80a085222ddb4f4ed445a46e977d17b1e85", size = 33241144, upload-time = "2025-10-27T15:20:32.504Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/a4/c4fde67f193401512337456cabc2148f2c43316e445f5decd9f8806e2992/langchain_community-0.4.1-py3-none-any.whl", hash = "sha256:2135abb2c7748a35c84613108f7ebf30f8505b18c3c18305ffaecfc7651f6c6a", size = 2533285, upload-time = "2025-10-27T15:20:30.767Z" }, +] + +[[package]] +name = "langchain-core" +version = "1.2.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpatch" }, + { name = "langsmith" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "uuid-utils" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/ce/ba5ed5ea6df22965b2893c2ed28ebb456204962723d408904c4acfa5e942/langchain_core-1.2.6.tar.gz", hash = "sha256:b4e7841dd7f8690375aa07c54739178dc2c635147d475e0c2955bf82a1afa498", size = 833343, upload-time = "2026-01-02T21:35:44.749Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/40/0655892c245d8fbe6bca6d673ab5927e5c3ab7be143de40b52289a0663bc/langchain_core-1.2.6-py3-none-any.whl", hash = "sha256:aa6ed954b4b1f4504937fe75fdf674317027e9a91ba7a97558b0de3dc8004e34", size = 489096, upload-time = "2026-01-02T21:35:43.391Z" }, +] + +[[package]] +name = "langchain-ollama" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "ollama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/51/72cd04d74278f3575f921084f34280e2f837211dc008c9671c268c578afe/langchain_ollama-1.0.1.tar.gz", hash = "sha256:e37880c2f41cdb0895e863b1cfd0c2c840a117868b3f32e44fef42569e367443", size = 153850, upload-time = "2025-12-12T21:48:28.68Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/46/f2907da16dc5a5a6c679f83b7de21176178afad8d2ca635a581429580ef6/langchain_ollama-1.0.1-py3-none-any.whl", hash = "sha256:37eb939a4718a0255fe31e19fbb0def044746c717b01b97d397606ebc3e9b440", size = 29207, upload-time = "2025-12-12T21:48:27.832Z" }, +] + +[[package]] +name = "langchain-text-splitters" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/42/c178dcdc157b473330eb7cc30883ea69b8ec60078c7b85e2d521054c4831/langchain_text_splitters-1.1.0.tar.gz", hash = "sha256:75e58acb7585dc9508f3cd9d9809cb14751283226c2d6e21fb3a9ae57582ca22", size = 272230, upload-time = "2025-12-14T01:15:38.659Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/1a/a84ed1c046deecf271356b0179c1b9fba95bfdaa6f934e1849dee26fad7b/langchain_text_splitters-1.1.0-py3-none-any.whl", hash = "sha256:f00341fe883358786104a5f881375ac830a4dd40253ecd42b4c10536c6e4693f", size = 34182, upload-time = "2025-12-14T01:15:37.382Z" }, +] + +[[package]] +name = "langgraph" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, + { name = "langgraph-prebuilt" }, + { name = "langgraph-sdk" }, + { name = "pydantic" }, + { name = "xxhash" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/47/28f4d4d33d88f69de26f7a54065961ac0c662cec2479b36a2db081ef5cb6/langgraph-1.0.5.tar.gz", hash = "sha256:7f6ae59622386b60fe9fa0ad4c53f42016b668455ed604329e7dc7904adbf3f8", size = 493969, upload-time = "2025-12-12T23:05:48.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/1b/e318ee76e42d28f515d87356ac5bd7a7acc8bad3b8f54ee377bef62e1cbf/langgraph-1.0.5-py3-none-any.whl", hash = "sha256:b4cfd173dca3c389735b47228ad8b295e6f7b3df779aba3a1e0c23871f81281e", size = 157056, upload-time = "2025-12-12T23:05:46.499Z" }, +] + +[[package]] +name = "langgraph-checkpoint" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "ormsgpack" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/07/2b1c042fa87d40cf2db5ca27dc4e8dd86f9a0436a10aa4361a8982718ae7/langgraph_checkpoint-3.0.1.tar.gz", hash = "sha256:59222f875f85186a22c494aedc65c4e985a3df27e696e5016ba0b98a5ed2cee0", size = 137785, upload-time = "2025-11-04T21:55:47.774Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/e3/616e3a7ff737d98c1bbb5700dd62278914e2a9ded09a79a1fa93cf24ce12/langgraph_checkpoint-3.0.1-py3-none-any.whl", hash = "sha256:9b04a8d0edc0474ce4eaf30c5d731cee38f11ddff50a6177eead95b5c4e4220b", size = 46249, upload-time = "2025-11-04T21:55:46.472Z" }, +] + +[[package]] +name = "langgraph-prebuilt" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/f9/54f8891b32159e4542236817aea2ee83de0de18bce28e9bdba08c7f93001/langgraph_prebuilt-1.0.5.tar.gz", hash = "sha256:85802675ad778cc7240fd02d47db1e0b59c0c86d8369447d77ce47623845db2d", size = 144453, upload-time = "2025-11-20T16:47:39.23Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/5e/aeba4a5b39fe6e874e0dd003a82da71c7153e671312671a8dacc5cb7c1af/langgraph_prebuilt-1.0.5-py3-none-any.whl", hash = "sha256:22369563e1848862ace53fbc11b027c28dd04a9ac39314633bb95f2a7e258496", size = 35072, upload-time = "2025-11-20T16:47:38.187Z" }, +] + +[[package]] +name = "langgraph-sdk" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d3/b6be0b0aba2a53a8920a2b0b4328a83121ec03eea9952e576d06a4182f6f/langgraph_sdk-0.3.1.tar.gz", hash = "sha256:f6dadfd2444eeff3e01405a9005c95fb3a028d4bd954ebec80ea6150084f92bb", size = 130312, upload-time = "2025-12-18T22:11:47.42Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/fe/0c1c9c01a154eba62b20b02fabe811fd94a2b810061ae9e4d8462b8cf85a/langgraph_sdk-0.3.1-py3-none-any.whl", hash = "sha256:0b856923bfd20bf3441ce9d03bef488aa333fb610e972618799a9d584436acad", size = 66517, upload-time = "2025-12-18T22:11:46.625Z" }, +] + +[[package]] +name = "langsmith" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson", marker = "platform_python_implementation != 'PyPy'" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "uuid-utils" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/48/fb62df712cfd77804999f3bc08e3cba33ecb81064dd2973dd67cd68eaf93/langsmith-0.6.0.tar.gz", hash = "sha256:b60f1785aed4dac5e01f24db01aa18fa1af258bad4531e045e739438daa3f8c2", size = 883012, upload-time = "2026-01-02T18:42:13.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/c6/322df2c18ab462712c968415fb31779ed3e1fd1976357fd78f31f51b2632/langsmith-0.6.0-py3-none-any.whl", hash = "sha256:f7570175aed705b1f4c4dae724c07980a737b8b565252444d11394dda9931e8c", size = 283280, upload-time = "2026-01-02T18:42:11.966Z" }, +] + +[[package]] +name = "librt" +version = "0.7.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/29/47f29026ca17f35cf299290292d5f8331f5077364974b7675a353179afa2/librt-0.7.7.tar.gz", hash = "sha256:81d957b069fed1890953c3b9c3895c7689960f233eea9a1d9607f71ce7f00b2c", size = 145910, upload-time = "2026-01-01T23:52:22.87Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/72/1cd9d752070011641e8aee046c851912d5f196ecd726fffa7aed2070f3e0/librt-0.7.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a85a1fc4ed11ea0eb0a632459ce004a2d14afc085a50ae3463cd3dfe1ce43fc", size = 55687, upload-time = "2026-01-01T23:51:16.291Z" }, + { url = "https://files.pythonhosted.org/packages/50/aa/d5a1d4221c4fe7e76ae1459d24d6037783cb83c7645164c07d7daf1576ec/librt-0.7.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c87654e29a35938baead1c4559858f346f4a2a7588574a14d784f300ffba0efd", size = 57136, upload-time = "2026-01-01T23:51:17.363Z" }, + { url = "https://files.pythonhosted.org/packages/23/6f/0c86b5cb5e7ef63208c8cc22534df10ecc5278efc0d47fb8815577f3ca2f/librt-0.7.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c9faaebb1c6212c20afd8043cd6ed9de0a47d77f91a6b5b48f4e46ed470703fe", size = 165320, upload-time = "2026-01-01T23:51:18.455Z" }, + { url = "https://files.pythonhosted.org/packages/16/37/df4652690c29f645ffe405b58285a4109e9fe855c5bb56e817e3e75840b3/librt-0.7.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1908c3e5a5ef86b23391448b47759298f87f997c3bd153a770828f58c2bb4630", size = 174216, upload-time = "2026-01-01T23:51:19.599Z" }, + { url = "https://files.pythonhosted.org/packages/9a/d6/d3afe071910a43133ec9c0f3e4ce99ee6df0d4e44e4bddf4b9e1c6ed41cc/librt-0.7.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbc4900e95a98fc0729523be9d93a8fedebb026f32ed9ffc08acd82e3e181503", size = 189005, upload-time = "2026-01-01T23:51:21.052Z" }, + { url = "https://files.pythonhosted.org/packages/d5/18/74060a870fe2d9fd9f47824eba6717ce7ce03124a0d1e85498e0e7efc1b2/librt-0.7.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7ea4e1fbd253e5c68ea0fe63d08577f9d288a73f17d82f652ebc61fa48d878d", size = 183961, upload-time = "2026-01-01T23:51:22.493Z" }, + { url = "https://files.pythonhosted.org/packages/7c/5e/918a86c66304af66a3c1d46d54df1b2d0b8894babc42a14fb6f25511497f/librt-0.7.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef7699b7a5a244b1119f85c5bbc13f152cd38240cbb2baa19b769433bae98e50", size = 177610, upload-time = "2026-01-01T23:51:23.874Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d7/b5e58dc2d570f162e99201b8c0151acf40a03a39c32ab824dd4febf12736/librt-0.7.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:955c62571de0b181d9e9e0a0303c8bc90d47670a5eff54cf71bf5da61d1899cf", size = 199272, upload-time = "2026-01-01T23:51:25.341Z" }, + { url = "https://files.pythonhosted.org/packages/18/87/8202c9bd0968bdddc188ec3811985f47f58ed161b3749299f2c0dd0f63fb/librt-0.7.7-cp312-cp312-win32.whl", hash = "sha256:1bcd79be209313b270b0e1a51c67ae1af28adad0e0c7e84c3ad4b5cb57aaa75b", size = 43189, upload-time = "2026-01-01T23:51:26.799Z" }, + { url = "https://files.pythonhosted.org/packages/61/8d/80244b267b585e7aa79ffdac19f66c4861effc3a24598e77909ecdd0850e/librt-0.7.7-cp312-cp312-win_amd64.whl", hash = "sha256:4353ee891a1834567e0302d4bd5e60f531912179578c36f3d0430f8c5e16b456", size = 49462, upload-time = "2026-01-01T23:51:27.813Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1f/75db802d6a4992d95e8a889682601af9b49d5a13bbfa246d414eede1b56c/librt-0.7.7-cp312-cp312-win_arm64.whl", hash = "sha256:a76f1d679beccccdf8c1958e732a1dfcd6e749f8821ee59d7bec009ac308c029", size = 42828, upload-time = "2026-01-01T23:51:28.804Z" }, + { url = "https://files.pythonhosted.org/packages/8d/5e/d979ccb0a81407ec47c14ea68fb217ff4315521730033e1dd9faa4f3e2c1/librt-0.7.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4a0b0a3c86ba9193a8e23bb18f100d647bf192390ae195d84dfa0a10fb6244", size = 55746, upload-time = "2026-01-01T23:51:29.828Z" }, + { url = "https://files.pythonhosted.org/packages/f5/2c/3b65861fb32f802c3783d6ac66fc5589564d07452a47a8cf9980d531cad3/librt-0.7.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5335890fea9f9e6c4fdf8683061b9ccdcbe47c6dc03ab8e9b68c10acf78be78d", size = 57174, upload-time = "2026-01-01T23:51:31.226Z" }, + { url = "https://files.pythonhosted.org/packages/50/df/030b50614b29e443607220097ebaf438531ea218c7a9a3e21ea862a919cd/librt-0.7.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b4346b1225be26def3ccc6c965751c74868f0578cbcba293c8ae9168483d811", size = 165834, upload-time = "2026-01-01T23:51:32.278Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e1/bd8d1eacacb24be26a47f157719553bbd1b3fe812c30dddf121c0436fd0b/librt-0.7.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a10b8eebdaca6e9fdbaf88b5aefc0e324b763a5f40b1266532590d5afb268a4c", size = 174819, upload-time = "2026-01-01T23:51:33.461Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/91d6c3372acf54a019c1ad8da4c9ecf4fc27d039708880bf95f48dbe426a/librt-0.7.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:067be973d90d9e319e6eb4ee2a9b9307f0ecd648b8a9002fa237289a4a07a9e7", size = 189607, upload-time = "2026-01-01T23:51:34.604Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ac/44604d6d3886f791fbd1c6ae12d5a782a8f4aca927484731979f5e92c200/librt-0.7.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:23d2299ed007812cccc1ecef018db7d922733382561230de1f3954db28433977", size = 184586, upload-time = "2026-01-01T23:51:35.845Z" }, + { url = "https://files.pythonhosted.org/packages/5c/26/d8a6e4c17117b7f9b83301319d9a9de862ae56b133efb4bad8b3aa0808c9/librt-0.7.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6b6f8ea465524aa4c7420c7cc4ca7d46fe00981de8debc67b1cc2e9957bb5b9d", size = 178251, upload-time = "2026-01-01T23:51:37.018Z" }, + { url = "https://files.pythonhosted.org/packages/99/ab/98d857e254376f8e2f668e807daccc1f445e4b4fc2f6f9c1cc08866b0227/librt-0.7.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8df32a99cc46eb0ee90afd9ada113ae2cafe7e8d673686cf03ec53e49635439", size = 199853, upload-time = "2026-01-01T23:51:38.195Z" }, + { url = "https://files.pythonhosted.org/packages/7c/55/4523210d6ae5134a5da959900be43ad8bab2e4206687b6620befddb5b5fd/librt-0.7.7-cp313-cp313-win32.whl", hash = "sha256:86f86b3b785487c7760247bcdac0b11aa8bf13245a13ed05206286135877564b", size = 43247, upload-time = "2026-01-01T23:51:39.629Z" }, + { url = "https://files.pythonhosted.org/packages/25/40/3ec0fed5e8e9297b1cf1a3836fb589d3de55f9930e3aba988d379e8ef67c/librt-0.7.7-cp313-cp313-win_amd64.whl", hash = "sha256:4862cb2c702b1f905c0503b72d9d4daf65a7fdf5a9e84560e563471e57a56949", size = 49419, upload-time = "2026-01-01T23:51:40.674Z" }, + { url = "https://files.pythonhosted.org/packages/1c/7a/aab5f0fb122822e2acbc776addf8b9abfb4944a9056c00c393e46e543177/librt-0.7.7-cp313-cp313-win_arm64.whl", hash = "sha256:0996c83b1cb43c00e8c87835a284f9057bc647abd42b5871e5f941d30010c832", size = 42828, upload-time = "2026-01-01T23:51:41.731Z" }, + { url = "https://files.pythonhosted.org/packages/69/9c/228a5c1224bd23809a635490a162e9cbdc68d99f0eeb4a696f07886b8206/librt-0.7.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:23daa1ab0512bafdd677eb1bfc9611d8ffbe2e328895671e64cb34166bc1b8c8", size = 55188, upload-time = "2026-01-01T23:51:43.14Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c2/0e7c6067e2b32a156308205e5728f4ed6478c501947e9142f525afbc6bd2/librt-0.7.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:558a9e5a6f3cc1e20b3168fb1dc802d0d8fa40731f6e9932dcc52bbcfbd37111", size = 56895, upload-time = "2026-01-01T23:51:44.534Z" }, + { url = "https://files.pythonhosted.org/packages/0e/77/de50ff70c80855eb79d1d74035ef06f664dd073fb7fb9d9fb4429651b8eb/librt-0.7.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2567cb48dc03e5b246927ab35cbb343376e24501260a9b5e30b8e255dca0d1d2", size = 163724, upload-time = "2026-01-01T23:51:45.571Z" }, + { url = "https://files.pythonhosted.org/packages/6e/19/f8e4bf537899bdef9e0bb9f0e4b18912c2d0f858ad02091b6019864c9a6d/librt-0.7.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6066c638cdf85ff92fc6f932d2d73c93a0e03492cdfa8778e6d58c489a3d7259", size = 172470, upload-time = "2026-01-01T23:51:46.823Z" }, + { url = "https://files.pythonhosted.org/packages/42/4c/dcc575b69d99076768e8dd6141d9aecd4234cba7f0e09217937f52edb6ed/librt-0.7.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a609849aca463074c17de9cda173c276eb8fee9e441053529e7b9e249dc8b8ee", size = 186806, upload-time = "2026-01-01T23:51:48.009Z" }, + { url = "https://files.pythonhosted.org/packages/fe/f8/4094a2b7816c88de81239a83ede6e87f1138477d7ee956c30f136009eb29/librt-0.7.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:add4e0a000858fe9bb39ed55f31085506a5c38363e6eb4a1e5943a10c2bfc3d1", size = 181809, upload-time = "2026-01-01T23:51:49.35Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ac/821b7c0ab1b5a6cd9aee7ace8309c91545a2607185101827f79122219a7e/librt-0.7.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a3bfe73a32bd0bdb9a87d586b05a23c0a1729205d79df66dee65bb2e40d671ba", size = 175597, upload-time = "2026-01-01T23:51:50.636Z" }, + { url = "https://files.pythonhosted.org/packages/71/f9/27f6bfbcc764805864c04211c6ed636fe1d58f57a7b68d1f4ae5ed74e0e0/librt-0.7.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0ecce0544d3db91a40f8b57ae26928c02130a997b540f908cefd4d279d6c5848", size = 196506, upload-time = "2026-01-01T23:51:52.535Z" }, + { url = "https://files.pythonhosted.org/packages/46/ba/c9b9c6fc931dd7ea856c573174ccaf48714905b1a7499904db2552e3bbaf/librt-0.7.7-cp314-cp314-win32.whl", hash = "sha256:8f7a74cf3a80f0c3b0ec75b0c650b2f0a894a2cec57ef75f6f72c1e82cdac61d", size = 39747, upload-time = "2026-01-01T23:51:53.683Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/cd1269337c4cde3ee70176ee611ab0058aa42fc8ce5c9dce55f48facfcd8/librt-0.7.7-cp314-cp314-win_amd64.whl", hash = "sha256:3d1fe2e8df3268dd6734dba33ededae72ad5c3a859b9577bc00b715759c5aaab", size = 45971, upload-time = "2026-01-01T23:51:54.697Z" }, + { url = "https://files.pythonhosted.org/packages/79/fd/e0844794423f5583108c5991313c15e2b400995f44f6ec6871f8aaf8243c/librt-0.7.7-cp314-cp314-win_arm64.whl", hash = "sha256:2987cf827011907d3dfd109f1be0d61e173d68b1270107bb0e89f2fca7f2ed6b", size = 39075, upload-time = "2026-01-01T23:51:55.726Z" }, + { url = "https://files.pythonhosted.org/packages/42/02/211fd8f7c381e7b2a11d0fdfcd410f409e89967be2e705983f7c6342209a/librt-0.7.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e92c8de62b40bfce91d5e12c6e8b15434da268979b1af1a6589463549d491e6", size = 57368, upload-time = "2026-01-01T23:51:56.706Z" }, + { url = "https://files.pythonhosted.org/packages/4c/b6/aca257affae73ece26041ae76032153266d110453173f67d7603058e708c/librt-0.7.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f683dcd49e2494a7535e30f779aa1ad6e3732a019d80abe1309ea91ccd3230e3", size = 59238, upload-time = "2026-01-01T23:51:58.066Z" }, + { url = "https://files.pythonhosted.org/packages/96/47/7383a507d8e0c11c78ca34c9d36eab9000db5989d446a2f05dc40e76c64f/librt-0.7.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b15e5d17812d4d629ff576699954f74e2cc24a02a4fc401882dd94f81daba45", size = 183870, upload-time = "2026-01-01T23:51:59.204Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b8/50f3d8eec8efdaf79443963624175c92cec0ba84827a66b7fcfa78598e51/librt-0.7.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c084841b879c4d9b9fa34e5d5263994f21aea7fd9c6add29194dbb41a6210536", size = 194608, upload-time = "2026-01-01T23:52:00.419Z" }, + { url = "https://files.pythonhosted.org/packages/23/d9/1b6520793aadb59d891e3b98ee057a75de7f737e4a8b4b37fdbecb10d60f/librt-0.7.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c8fb9966f84737115513fecbaf257f9553d067a7dd45a69c2c7e5339e6a8dc", size = 206776, upload-time = "2026-01-01T23:52:01.705Z" }, + { url = "https://files.pythonhosted.org/packages/ff/db/331edc3bba929d2756fa335bfcf736f36eff4efcb4f2600b545a35c2ae58/librt-0.7.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5fb1ecb2c35362eab2dbd354fd1efa5a8440d3e73a68be11921042a0edc0ff", size = 203206, upload-time = "2026-01-01T23:52:03.315Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e1/6af79ec77204e85f6f2294fc171a30a91bb0e35d78493532ed680f5d98be/librt-0.7.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d1454899909d63cc9199a89fcc4f81bdd9004aef577d4ffc022e600c412d57f3", size = 196697, upload-time = "2026-01-01T23:52:04.857Z" }, + { url = "https://files.pythonhosted.org/packages/f3/46/de55ecce4b2796d6d243295c221082ca3a944dc2fb3a52dcc8660ce7727d/librt-0.7.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7ef28f2e7a016b29792fe0a2dd04dec75725b32a1264e390c366103f834a9c3a", size = 217193, upload-time = "2026-01-01T23:52:06.159Z" }, + { url = "https://files.pythonhosted.org/packages/41/61/33063e271949787a2f8dd33c5260357e3d512a114fc82ca7890b65a76e2d/librt-0.7.7-cp314-cp314t-win32.whl", hash = "sha256:5e419e0db70991b6ba037b70c1d5bbe92b20ddf82f31ad01d77a347ed9781398", size = 40277, upload-time = "2026-01-01T23:52:07.625Z" }, + { url = "https://files.pythonhosted.org/packages/06/21/1abd972349f83a696ea73159ac964e63e2d14086fdd9bc7ca878c25fced4/librt-0.7.7-cp314-cp314t-win_amd64.whl", hash = "sha256:d6b7d93657332c817b8d674ef6bf1ab7796b4f7ce05e420fd45bd258a72ac804", size = 46765, upload-time = "2026-01-01T23:52:08.647Z" }, + { url = "https://files.pythonhosted.org/packages/51/0e/b756c7708143a63fca65a51ca07990fa647db2cc8fcd65177b9e96680255/librt-0.7.7-cp314-cp314t-win_arm64.whl", hash = "sha256:142c2cd91794b79fd0ce113bd658993b7ede0fe93057668c2f98a45ca00b7e91", size = 39724, upload-time = "2026-01-01T23:52:09.745Z" }, +] + +[[package]] +name = "marshmallow" +version = "3.26.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/79/de6c16cc902f4fc372236926b0ce2ab7845268dcc30fb2fbb7f71b418631/marshmallow-3.26.2.tar.gz", hash = "sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57", size = 222095, upload-time = "2025-12-22T06:53:53.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/2f/5108cb3ee4ba6501748c4908b908e55f42a5b66245b4cfe0c99326e1ef6e/marshmallow-3.26.2-py3-none-any.whl", hash = "sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73", size = 50964, upload-time = "2025-12-22T06:53:51.801Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "mypy" +version = "1.19.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" }, + { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size = 13620847, upload-time = "2025-12-15T05:03:39.633Z" }, + { url = "https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size = 13834976, upload-time = "2025-12-15T05:03:08.786Z" }, + { url = "https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size = 10118104, upload-time = "2025-12-15T05:03:10.834Z" }, + { url = "https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size = 13201927, upload-time = "2025-12-15T05:02:29.138Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size = 12206730, upload-time = "2025-12-15T05:03:01.325Z" }, + { url = "https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size = 12724581, upload-time = "2025-12-15T05:03:20.087Z" }, + { url = "https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size = 13616252, upload-time = "2025-12-15T05:02:49.036Z" }, + { url = "https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size = 13840848, upload-time = "2025-12-15T05:02:55.95Z" }, + { url = "https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size = 10135510, upload-time = "2025-12-15T05:02:58.438Z" }, + { url = "https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size = 13199744, upload-time = "2025-12-15T05:03:30.823Z" }, + { url = "https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size = 12215815, upload-time = "2025-12-15T05:02:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size = 12740047, upload-time = "2025-12-15T05:03:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size = 13601998, upload-time = "2025-12-15T05:03:13.056Z" }, + { url = "https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size = 13807476, upload-time = "2025-12-15T05:03:17.977Z" }, + { url = "https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size = 10281872, upload-time = "2025-12-15T05:03:05.549Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size = 2471239, upload-time = "2025-12-15T05:03:07.248Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/7a/6a3d14e205d292b738db449d0de649b373a59edb0d0b4493821d0a3e8718/numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934", size = 20685720, upload-time = "2025-12-20T16:18:19.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ff/f6400ffec95de41c74b8e73df32e3fff1830633193a7b1e409be7fb1bb8c/numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037", size = 16653117, upload-time = "2025-12-20T16:16:06.709Z" }, + { url = "https://files.pythonhosted.org/packages/fd/28/6c23e97450035072e8d830a3c411bf1abd1f42c611ff9d29e3d8f55c6252/numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83", size = 12369711, upload-time = "2025-12-20T16:16:08.758Z" }, + { url = "https://files.pythonhosted.org/packages/bc/af/acbef97b630ab1bb45e6a7d01d1452e4251aa88ce680ac36e56c272120ec/numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344", size = 5198355, upload-time = "2025-12-20T16:16:10.902Z" }, + { url = "https://files.pythonhosted.org/packages/c1/c8/4e0d436b66b826f2e53330adaa6311f5cac9871a5b5c31ad773b27f25a74/numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6", size = 6545298, upload-time = "2025-12-20T16:16:12.607Z" }, + { url = "https://files.pythonhosted.org/packages/ef/27/e1f5d144ab54eac34875e79037011d511ac57b21b220063310cb96c80fbc/numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb", size = 14398387, upload-time = "2025-12-20T16:16:14.257Z" }, + { url = "https://files.pythonhosted.org/packages/67/64/4cb909dd5ab09a9a5d086eff9586e69e827b88a5585517386879474f4cf7/numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63", size = 16363091, upload-time = "2025-12-20T16:16:17.32Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9c/8efe24577523ec6809261859737cf117b0eb6fdb655abdfdc81b2e468ce4/numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95", size = 16176394, upload-time = "2025-12-20T16:16:19.524Z" }, + { url = "https://files.pythonhosted.org/packages/61/f0/1687441ece7b47a62e45a1f82015352c240765c707928edd8aef875d5951/numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6", size = 18287378, upload-time = "2025-12-20T16:16:22.866Z" }, + { url = "https://files.pythonhosted.org/packages/d3/6f/f868765d44e6fc466467ed810ba9d8d6db1add7d4a748abfa2a4c99a3194/numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c", size = 5955432, upload-time = "2025-12-20T16:16:25.06Z" }, + { url = "https://files.pythonhosted.org/packages/d4/b5/94c1e79fcbab38d1ca15e13777477b2914dd2d559b410f96949d6637b085/numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98", size = 12306201, upload-time = "2025-12-20T16:16:26.979Z" }, + { url = "https://files.pythonhosted.org/packages/70/09/c39dadf0b13bb0768cd29d6a3aaff1fb7c6905ac40e9aaeca26b1c086e06/numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667", size = 10308234, upload-time = "2025-12-20T16:16:29.417Z" }, + { url = "https://files.pythonhosted.org/packages/a7/0d/853fd96372eda07c824d24adf02e8bc92bb3731b43a9b2a39161c3667cc4/numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea", size = 16649088, upload-time = "2025-12-20T16:16:31.421Z" }, + { url = "https://files.pythonhosted.org/packages/e3/37/cc636f1f2a9f585434e20a3e6e63422f70bfe4f7f6698e941db52ea1ac9a/numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d", size = 12364065, upload-time = "2025-12-20T16:16:33.491Z" }, + { url = "https://files.pythonhosted.org/packages/ed/69/0b78f37ca3690969beee54103ce5f6021709134e8020767e93ba691a72f1/numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee", size = 5192640, upload-time = "2025-12-20T16:16:35.636Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2a/08569f8252abf590294dbb09a430543ec8f8cc710383abfb3e75cc73aeda/numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e", size = 6541556, upload-time = "2025-12-20T16:16:37.276Z" }, + { url = "https://files.pythonhosted.org/packages/93/e9/a949885a4e177493d61519377952186b6cbfdf1d6002764c664ba28349b5/numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2", size = 14396562, upload-time = "2025-12-20T16:16:38.953Z" }, + { url = "https://files.pythonhosted.org/packages/99/98/9d4ad53b0e9ef901c2ef1d550d2136f5ac42d3fd2988390a6def32e23e48/numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a", size = 16351719, upload-time = "2025-12-20T16:16:41.503Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/5f3711a38341d6e8dd619f6353251a0cdd07f3d6d101a8fd46f4ef87f895/numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681", size = 16176053, upload-time = "2025-12-20T16:16:44.552Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5b/2a3753dc43916501b4183532e7ace862e13211042bceafa253afb5c71272/numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475", size = 18277859, upload-time = "2025-12-20T16:16:47.174Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c5/a18bcdd07a941db3076ef489d036ab16d2bfc2eae0cf27e5a26e29189434/numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344", size = 5953849, upload-time = "2025-12-20T16:16:49.554Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f1/719010ff8061da6e8a26e1980cf090412d4f5f8060b31f0c45d77dd67a01/numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d", size = 12302840, upload-time = "2025-12-20T16:16:51.227Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5a/b3d259083ed8b4d335270c76966cb6cf14a5d1b69e1a608994ac57a659e6/numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d", size = 10308509, upload-time = "2025-12-20T16:16:53.313Z" }, + { url = "https://files.pythonhosted.org/packages/31/01/95edcffd1bb6c0633df4e808130545c4f07383ab629ac7e316fb44fff677/numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6", size = 12491815, upload-time = "2025-12-20T16:16:55.496Z" }, + { url = "https://files.pythonhosted.org/packages/59/ea/5644b8baa92cc1c7163b4b4458c8679852733fa74ca49c942cfa82ded4e0/numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5", size = 5320321, upload-time = "2025-12-20T16:16:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/26/4e/e10938106d70bc21319bd6a86ae726da37edc802ce35a3a71ecdf1fdfe7f/numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3", size = 6641635, upload-time = "2025-12-20T16:16:59.379Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8d/a8828e3eaf5c0b4ab116924df82f24ce3416fa38d0674d8f708ddc6c8aac/numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d", size = 14456053, upload-time = "2025-12-20T16:17:01.768Z" }, + { url = "https://files.pythonhosted.org/packages/68/a1/17d97609d87d4520aa5ae2dcfb32305654550ac6a35effb946d303e594ce/numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3", size = 16401702, upload-time = "2025-12-20T16:17:04.235Z" }, + { url = "https://files.pythonhosted.org/packages/18/32/0f13c1b2d22bea1118356b8b963195446f3af124ed7a5adfa8fdecb1b6ca/numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa", size = 16242493, upload-time = "2025-12-20T16:17:06.856Z" }, + { url = "https://files.pythonhosted.org/packages/ae/23/48f21e3d309fbc137c068a1475358cbd3a901b3987dcfc97a029ab3068e2/numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c", size = 18324222, upload-time = "2025-12-20T16:17:09.392Z" }, + { url = "https://files.pythonhosted.org/packages/ac/52/41f3d71296a3dcaa4f456aaa3c6fc8e745b43d0552b6bde56571bb4b4a0f/numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93", size = 6076216, upload-time = "2025-12-20T16:17:11.437Z" }, + { url = "https://files.pythonhosted.org/packages/35/ff/46fbfe60ab0710d2a2b16995f708750307d30eccbb4c38371ea9e986866e/numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4", size = 12444263, upload-time = "2025-12-20T16:17:13.182Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e3/9189ab319c01d2ed556c932ccf55064c5d75bb5850d1df7a482ce0badead/numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c", size = 10378265, upload-time = "2025-12-20T16:17:15.211Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ed/52eac27de39d5e5a6c9aadabe672bc06f55e24a3d9010cd1183948055d76/numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b", size = 16647476, upload-time = "2025-12-20T16:17:17.671Z" }, + { url = "https://files.pythonhosted.org/packages/77/c0/990ce1b7fcd4e09aeaa574e2a0a839589e4b08b2ca68070f1acb1fea6736/numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e", size = 12374563, upload-time = "2025-12-20T16:17:20.216Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/8c5e389c6ae8f5fd2277a988600d79e9625db3fff011a2d87ac80b881a4c/numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e", size = 5203107, upload-time = "2025-12-20T16:17:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/e6/94/ca5b3bd6a8a70a5eec9a0b8dd7f980c1eff4b8a54970a9a7fef248ef564f/numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51", size = 6538067, upload-time = "2025-12-20T16:17:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/79/43/993eb7bb5be6761dde2b3a3a594d689cec83398e3f58f4758010f3b85727/numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce", size = 14411926, upload-time = "2025-12-20T16:17:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/03/75/d4c43b61de473912496317a854dac54f1efec3eeb158438da6884b70bb90/numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f", size = 16354295, upload-time = "2025-12-20T16:17:28.308Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0a/b54615b47ee8736a6461a4bb6749128dd3435c5a759d5663f11f0e9af4ac/numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded", size = 16190242, upload-time = "2025-12-20T16:17:30.993Z" }, + { url = "https://files.pythonhosted.org/packages/98/ce/ea207769aacad6246525ec6c6bbd66a2bf56c72443dc10e2f90feed29290/numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059", size = 18280875, upload-time = "2025-12-20T16:17:33.327Z" }, + { url = "https://files.pythonhosted.org/packages/17/ef/ec409437aa962ea372ed601c519a2b141701683ff028f894b7466f0ab42b/numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db", size = 6002530, upload-time = "2025-12-20T16:17:35.729Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4a/5cb94c787a3ed1ac65e1271b968686521169a7b3ec0b6544bb3ca32960b0/numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e", size = 12435890, upload-time = "2025-12-20T16:17:37.599Z" }, + { url = "https://files.pythonhosted.org/packages/48/a0/04b89db963af9de1104975e2544f30de89adbf75b9e75f7dd2599be12c79/numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63", size = 10591892, upload-time = "2025-12-20T16:17:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/53/e5/d74b5ccf6712c06c7a545025a6a71bfa03bdc7e0568b405b0d655232fd92/numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df", size = 12494312, upload-time = "2025-12-20T16:17:41.714Z" }, + { url = "https://files.pythonhosted.org/packages/c2/08/3ca9cc2ddf54dfee7ae9a6479c071092a228c68aef08252aa08dac2af002/numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9", size = 5322862, upload-time = "2025-12-20T16:17:44.145Z" }, + { url = "https://files.pythonhosted.org/packages/87/74/0bb63a68394c0c1e52670cfff2e309afa41edbe11b3327d9af29e4383f34/numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9", size = 6644986, upload-time = "2025-12-20T16:17:46.203Z" }, + { url = "https://files.pythonhosted.org/packages/06/8f/9264d9bdbcf8236af2823623fe2f3981d740fc3461e2787e231d97c38c28/numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471", size = 14457958, upload-time = "2025-12-20T16:17:48.017Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d9/f9a69ae564bbc7236a35aa883319364ef5fd41f72aa320cc1cbe66148fe2/numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544", size = 16398394, upload-time = "2025-12-20T16:17:50.409Z" }, + { url = "https://files.pythonhosted.org/packages/34/c7/39241501408dde7f885d241a98caba5421061a2c6d2b2197ac5e3aa842d8/numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c", size = 16241044, upload-time = "2025-12-20T16:17:52.661Z" }, + { url = "https://files.pythonhosted.org/packages/7c/95/cae7effd90e065a95e59fe710eeee05d7328ed169776dfdd9f789e032125/numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac", size = 18321772, upload-time = "2025-12-20T16:17:54.947Z" }, + { url = "https://files.pythonhosted.org/packages/96/df/3c6c279accd2bfb968a76298e5b276310bd55d243df4fa8ac5816d79347d/numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f", size = 6148320, upload-time = "2025-12-20T16:17:57.249Z" }, + { url = "https://files.pythonhosted.org/packages/92/8d/f23033cce252e7a75cae853d17f582e86534c46404dea1c8ee094a9d6d84/numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4", size = 12623460, upload-time = "2025-12-20T16:17:58.963Z" }, + { url = "https://files.pythonhosted.org/packages/a4/4f/1f8475907d1a7c4ef9020edf7f39ea2422ec896849245f00688e4b268a71/numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8", size = 10661799, upload-time = "2025-12-20T16:18:01.078Z" }, +] + +[[package]] +name = "ollama" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/5a/652dac4b7affc2b37b95386f8ae78f22808af09d720689e3d7a86b6ed98e/ollama-0.6.1.tar.gz", hash = "sha256:478c67546836430034b415ed64fa890fd3d1ff91781a9d548b3325274e69d7c6", size = 51620, upload-time = "2025-11-13T23:02:17.416Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/4f/4a617ee93d8208d2bcf26b2d8b9402ceaed03e3853c754940e2290fed063/ollama-0.6.1-py3-none-any.whl", hash = "sha256:fc4c984b345735c5486faeee67d8a265214a31cbb828167782dc642ce0a2bf8c", size = 14354, upload-time = "2025-11-13T23:02:16.292Z" }, +] + +[[package]] +name = "omegaconf" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/48/6388f1bb9da707110532cb70ec4d2822858ddfb44f1cdf1233c20a80ea4b/omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7", size = 3298120, upload-time = "2022-12-08T20:59:22.753Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/94/1843518e420fa3ed6919835845df698c7e27e183cb997394e4a670973a65/omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", size = 79500, upload-time = "2022-12-08T20:59:19.686Z" }, +] + +[[package]] +name = "orjson" +version = "3.11.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/b8/333fdb27840f3bf04022d21b654a35f58e15407183aeb16f3b41aa053446/orjson-3.11.5.tar.gz", hash = "sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5", size = 5972347, upload-time = "2025-12-06T15:55:39.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a4/8052a029029b096a78955eadd68ab594ce2197e24ec50e6b6d2ab3f4e33b/orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d", size = 245347, upload-time = "2025-12-06T15:54:22.061Z" }, + { url = "https://files.pythonhosted.org/packages/64/67/574a7732bd9d9d79ac620c8790b4cfe0717a3d5a6eb2b539e6e8995e24a0/orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626", size = 129435, upload-time = "2025-12-06T15:54:23.615Z" }, + { url = "https://files.pythonhosted.org/packages/52/8d/544e77d7a29d90cf4d9eecd0ae801c688e7f3d1adfa2ebae5e1e94d38ab9/orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f", size = 132074, upload-time = "2025-12-06T15:54:24.694Z" }, + { url = "https://files.pythonhosted.org/packages/6e/57/b9f5b5b6fbff9c26f77e785baf56ae8460ef74acdb3eae4931c25b8f5ba9/orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85", size = 130520, upload-time = "2025-12-06T15:54:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6d/d34970bf9eb33f9ec7c979a262cad86076814859e54eb9a059a52f6dc13d/orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9", size = 136209, upload-time = "2025-12-06T15:54:27.264Z" }, + { url = "https://files.pythonhosted.org/packages/e7/39/bc373b63cc0e117a105ea12e57280f83ae52fdee426890d57412432d63b3/orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626", size = 139837, upload-time = "2025-12-06T15:54:28.75Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7c4818c8d7d324da220f4f1af55c343956003aa4d1ce1857bdc1d396ba69/orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa", size = 137307, upload-time = "2025-12-06T15:54:29.856Z" }, + { url = "https://files.pythonhosted.org/packages/46/bf/0993b5a056759ba65145effe3a79dd5a939d4a070eaa5da2ee3180fbb13f/orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477", size = 139020, upload-time = "2025-12-06T15:54:31.024Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/83a6c95db3039e504eda60fc388f9faedbb4f6472f5aba7084e06552d9aa/orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e", size = 141099, upload-time = "2025-12-06T15:54:32.196Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b4/24fdc024abfce31c2f6812973b0a693688037ece5dc64b7a60c1ce69e2f2/orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69", size = 413540, upload-time = "2025-12-06T15:54:33.361Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/01c0ec95d55ed0c11e4cae3e10427e479bba40c77312b63e1f9665e0737d/orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3", size = 151530, upload-time = "2025-12-06T15:54:34.6Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d4/f9ebc57182705bb4bbe63f5bbe14af43722a2533135e1d2fb7affa0c355d/orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca", size = 141863, upload-time = "2025-12-06T15:54:35.801Z" }, + { url = "https://files.pythonhosted.org/packages/0d/04/02102b8d19fdcb009d72d622bb5781e8f3fae1646bf3e18c53d1bc8115b5/orjson-3.11.5-cp312-cp312-win32.whl", hash = "sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98", size = 135255, upload-time = "2025-12-06T15:54:37.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fb/f05646c43d5450492cb387de5549f6de90a71001682c17882d9f66476af5/orjson-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875", size = 133252, upload-time = "2025-12-06T15:54:38.401Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/7b8c0b26ba18c793533ac1cd145e131e46fcf43952aa94c109b5b913c1f0/orjson-3.11.5-cp312-cp312-win_arm64.whl", hash = "sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe", size = 126777, upload-time = "2025-12-06T15:54:39.515Z" }, + { url = "https://files.pythonhosted.org/packages/10/43/61a77040ce59f1569edf38f0b9faadc90c8cf7e9bec2e0df51d0132c6bb7/orjson-3.11.5-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629", size = 245271, upload-time = "2025-12-06T15:54:40.878Z" }, + { url = "https://files.pythonhosted.org/packages/55/f9/0f79be617388227866d50edd2fd320cb8fb94dc1501184bb1620981a0aba/orjson-3.11.5-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3", size = 129422, upload-time = "2025-12-06T15:54:42.403Z" }, + { url = "https://files.pythonhosted.org/packages/77/42/f1bf1549b432d4a78bfa95735b79b5dac75b65b5bb815bba86ad406ead0a/orjson-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39", size = 132060, upload-time = "2025-12-06T15:54:43.531Z" }, + { url = "https://files.pythonhosted.org/packages/25/49/825aa6b929f1a6ed244c78acd7b22c1481fd7e5fda047dc8bf4c1a807eb6/orjson-3.11.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f", size = 130391, upload-time = "2025-12-06T15:54:45.059Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/de55391858b49e16e1aa8f0bbbb7e5997b7345d8e984a2dec3746d13065b/orjson-3.11.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51", size = 135964, upload-time = "2025-12-06T15:54:46.576Z" }, + { url = "https://files.pythonhosted.org/packages/1c/40/820bc63121d2d28818556a2d0a09384a9f0262407cf9fa305e091a8048df/orjson-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8", size = 139817, upload-time = "2025-12-06T15:54:48.084Z" }, + { url = "https://files.pythonhosted.org/packages/09/c7/3a445ca9a84a0d59d26365fd8898ff52bdfcdcb825bcc6519830371d2364/orjson-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706", size = 137336, upload-time = "2025-12-06T15:54:49.426Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b3/dc0d3771f2e5d1f13368f56b339c6782f955c6a20b50465a91acb79fe961/orjson-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f", size = 138993, upload-time = "2025-12-06T15:54:50.939Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a2/65267e959de6abe23444659b6e19c888f242bf7725ff927e2292776f6b89/orjson-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863", size = 141070, upload-time = "2025-12-06T15:54:52.414Z" }, + { url = "https://files.pythonhosted.org/packages/63/c9/da44a321b288727a322c6ab17e1754195708786a04f4f9d2220a5076a649/orjson-3.11.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228", size = 413505, upload-time = "2025-12-06T15:54:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/7f/17/68dc14fa7000eefb3d4d6d7326a190c99bb65e319f02747ef3ebf2452f12/orjson-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2", size = 151342, upload-time = "2025-12-06T15:54:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c5/ccee774b67225bed630a57478529fc026eda33d94fe4c0eac8fe58d4aa52/orjson-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05", size = 141823, upload-time = "2025-12-06T15:54:56.331Z" }, + { url = "https://files.pythonhosted.org/packages/67/80/5d00e4155d0cd7390ae2087130637671da713959bb558db9bac5e6f6b042/orjson-3.11.5-cp313-cp313-win32.whl", hash = "sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef", size = 135236, upload-time = "2025-12-06T15:54:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/95/fe/792cc06a84808dbdc20ac6eab6811c53091b42f8e51ecebf14b540e9cfe4/orjson-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583", size = 133167, upload-time = "2025-12-06T15:54:58.71Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/d158bd8b50e3b1cfdcf406a7e463f6ffe3f0d167b99634717acdaf5e299f/orjson-3.11.5-cp313-cp313-win_arm64.whl", hash = "sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287", size = 126712, upload-time = "2025-12-06T15:54:59.892Z" }, + { url = "https://files.pythonhosted.org/packages/c2/60/77d7b839e317ead7bb225d55bb50f7ea75f47afc489c81199befc5435b50/orjson-3.11.5-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0", size = 245252, upload-time = "2025-12-06T15:55:01.127Z" }, + { url = "https://files.pythonhosted.org/packages/f1/aa/d4639163b400f8044cef0fb9aa51b0337be0da3a27187a20d1166e742370/orjson-3.11.5-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81", size = 129419, upload-time = "2025-12-06T15:55:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/30/94/9eabf94f2e11c671111139edf5ec410d2f21e6feee717804f7e8872d883f/orjson-3.11.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f", size = 132050, upload-time = "2025-12-06T15:55:03.918Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c8/ca10f5c5322f341ea9a9f1097e140be17a88f88d1cfdd29df522970d9744/orjson-3.11.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e", size = 130370, upload-time = "2025-12-06T15:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/25/d4/e96824476d361ee2edd5c6290ceb8d7edf88d81148a6ce172fc00278ca7f/orjson-3.11.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7", size = 136012, upload-time = "2025-12-06T15:55:06.402Z" }, + { url = "https://files.pythonhosted.org/packages/85/8e/9bc3423308c425c588903f2d103cfcfe2539e07a25d6522900645a6f257f/orjson-3.11.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb", size = 139809, upload-time = "2025-12-06T15:55:07.656Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3c/b404e94e0b02a232b957c54643ce68d0268dacb67ac33ffdee24008c8b27/orjson-3.11.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4", size = 137332, upload-time = "2025-12-06T15:55:08.961Z" }, + { url = "https://files.pythonhosted.org/packages/51/30/cc2d69d5ce0ad9b84811cdf4a0cd5362ac27205a921da524ff42f26d65e0/orjson-3.11.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad", size = 138983, upload-time = "2025-12-06T15:55:10.595Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/de3223944a3e297d4707d2fe3b1ffb71437550e165eaf0ca8bbe43ccbcb1/orjson-3.11.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829", size = 141069, upload-time = "2025-12-06T15:55:11.832Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/81d5087ae74be33bcae3ff2d80f5ccaa4a8fedc6d39bf65a427a95b8977f/orjson-3.11.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac", size = 413491, upload-time = "2025-12-06T15:55:13.314Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6f/f6058c21e2fc1efaf918986dbc2da5cd38044f1a2d4b7b91ad17c4acf786/orjson-3.11.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d", size = 151375, upload-time = "2025-12-06T15:55:14.715Z" }, + { url = "https://files.pythonhosted.org/packages/54/92/c6921f17d45e110892899a7a563a925b2273d929959ce2ad89e2525b885b/orjson-3.11.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439", size = 141850, upload-time = "2025-12-06T15:55:15.94Z" }, + { url = "https://files.pythonhosted.org/packages/88/86/cdecb0140a05e1a477b81f24739da93b25070ee01ce7f7242f44a6437594/orjson-3.11.5-cp314-cp314-win32.whl", hash = "sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499", size = 135278, upload-time = "2025-12-06T15:55:17.202Z" }, + { url = "https://files.pythonhosted.org/packages/e4/97/b638d69b1e947d24f6109216997e38922d54dcdcdb1b11c18d7efd2d3c59/orjson-3.11.5-cp314-cp314-win_amd64.whl", hash = "sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310", size = 133170, upload-time = "2025-12-06T15:55:18.468Z" }, + { url = "https://files.pythonhosted.org/packages/8f/dd/f4fff4a6fe601b4f8f3ba3aa6da8ac33d17d124491a3b804c662a70e1636/orjson-3.11.5-cp314-cp314-win_arm64.whl", hash = "sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5", size = 126713, upload-time = "2025-12-06T15:55:19.738Z" }, +] + +[[package]] +name = "ormsgpack" +version = "1.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/96/34c40d621996c2f377a18decbd3c59f031dde73c3ba47d1e1e8f29a05aaa/ormsgpack-1.12.1.tar.gz", hash = "sha256:a3877fde1e4f27a39f92681a0aab6385af3a41d0c25375d33590ae20410ea2ac", size = 39476, upload-time = "2025-12-14T07:57:43.248Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/fe/ab9167ca037406b5703add24049cf3e18021a3b16133ea20615b1f160ea4/ormsgpack-1.12.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4d7fb0e1b6fbc701d75269f7405a4f79230a6ce0063fb1092e4f6577e312f86d", size = 376725, upload-time = "2025-12-14T07:57:07.894Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ea/2820e65f506894c459b840d1091ae6e327fde3d5a3f3b002a11a1b9bdf7d/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43a9353e2db5b024c91a47d864ef15eaa62d81824cfc7740fed4cef7db738694", size = 202466, upload-time = "2025-12-14T07:57:09.049Z" }, + { url = "https://files.pythonhosted.org/packages/45/8b/def01c13339c5bbec2ee1469ef53e7fadd66c8d775df974ee4def1572515/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc8fe866b7706fc25af0adf1f600bc06ece5b15ca44e34641327198b821e5c3c", size = 210748, upload-time = "2025-12-14T07:57:10.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d2/bf350c92f7f067dd9484499705f2d8366d8d9008a670e3d1d0add1908f85/ormsgpack-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813755b5f598a78242042e05dfd1ada4e769e94b98c9ab82554550f97ff4d641", size = 211510, upload-time = "2025-12-14T07:57:11.165Z" }, + { url = "https://files.pythonhosted.org/packages/74/92/9d689bcb95304a6da26c4d59439c350940c25d1b35f146d402ccc6344c51/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8eea2a13536fae45d78f93f2cc846c9765c7160c85f19cfefecc20873c137cdd", size = 386237, upload-time = "2025-12-14T07:57:12.306Z" }, + { url = "https://files.pythonhosted.org/packages/17/fe/bd3107547f8b6129265dd957f40b9cd547d2445db2292aacb13335a7ea89/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7a02ebda1a863cbc604740e76faca8eee1add322db2dcbe6cf32669fffdff65c", size = 479589, upload-time = "2025-12-14T07:57:13.475Z" }, + { url = "https://files.pythonhosted.org/packages/c1/7c/e8e5cc9edb967d44f6f85e9ebdad440b59af3fae00b137a4327dc5aed9bb/ormsgpack-1.12.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c0bd63897c439931cdf29348e5e6e8c330d529830e848d10767615c0f3d1b82", size = 388077, upload-time = "2025-12-14T07:57:14.551Z" }, + { url = "https://files.pythonhosted.org/packages/35/6b/5031797e43b58506f28a8760b26dc23f2620fb4f2200c4c1b3045603e67e/ormsgpack-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:362f2e812f8d7035dc25a009171e09d7cc97cb30d3c9e75a16aeae00ca3c1dcf", size = 116190, upload-time = "2025-12-14T07:57:15.575Z" }, + { url = "https://files.pythonhosted.org/packages/1e/fd/9f43ea6425e383a6b2dbfafebb06fd60e8d68c700ef715adfbcdb499f75d/ormsgpack-1.12.1-cp312-cp312-win_arm64.whl", hash = "sha256:6190281e381db2ed0045052208f47a995ccf61eed48f1215ae3cce3fbccd59c5", size = 109990, upload-time = "2025-12-14T07:57:16.419Z" }, + { url = "https://files.pythonhosted.org/packages/11/42/f110dfe7cf23a52a82e23eb23d9a6a76ae495447d474686dfa758f3d71d6/ormsgpack-1.12.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9663d6b3ecc917c063d61a99169ce196a80f3852e541ae404206836749459279", size = 376746, upload-time = "2025-12-14T07:57:17.699Z" }, + { url = "https://files.pythonhosted.org/packages/11/76/b386e508a8ae207daec240201a81adb26467bf99b163560724e86bd9ff33/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32e85cfbaf01a94a92520e7fe7851cfcfe21a5698299c28ab86194895f9b9233", size = 202489, upload-time = "2025-12-14T07:57:18.807Z" }, + { url = "https://files.pythonhosted.org/packages/ea/0e/5db7a63f387149024572daa3d9512fe8fb14bf4efa0722d6d491bed280e7/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dabfd2c24b59c7c69870a5ecee480dfae914a42a0c2e7c9d971cf531e2ba471a", size = 210757, upload-time = "2025-12-14T07:57:19.893Z" }, + { url = "https://files.pythonhosted.org/packages/64/79/3a9899e57cb57430bd766fc1b4c9ad410cb2ba6070bc8cf6301e7d385768/ormsgpack-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bbf2b64afeded34ccd8e25402e4bca038757913931fa0d693078d75563f6f9", size = 211518, upload-time = "2025-12-14T07:57:20.972Z" }, + { url = "https://files.pythonhosted.org/packages/d7/cd/4f41710ae9fe50d7fcbe476793b3c487746d0e1cc194cc0fee42ff6d989b/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9959a71dde1bd0ced84af17facc06a8afada495a34e9cb1bad8e9b20d4c59cef", size = 386251, upload-time = "2025-12-14T07:57:22.099Z" }, + { url = "https://files.pythonhosted.org/packages/bf/54/ba0c97d6231b1f01daafaa520c8cce1e1b7fceaae6fdc1c763925874a7de/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:e9be0e3b62d758f21f5b20e0e06b3a240ec546c4a327bf771f5825462aa74714", size = 479607, upload-time = "2025-12-14T07:57:23.525Z" }, + { url = "https://files.pythonhosted.org/packages/18/75/19a9a97a462776d525baf41cfb7072734528775f0a3d5fbfab3aa7756b9b/ormsgpack-1.12.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a29d49ab7fdd77ea787818e60cb4ef491708105b9c4c9b0f919201625eb036b5", size = 388062, upload-time = "2025-12-14T07:57:24.616Z" }, + { url = "https://files.pythonhosted.org/packages/a8/6a/ec26e3f44e9632ecd2f43638b7b37b500eaea5d79cab984ad0b94be14f82/ormsgpack-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:c418390b47a1d367e803f6c187f77e4d67c7ae07ba962e3a4a019001f4b0291a", size = 116195, upload-time = "2025-12-14T07:57:25.626Z" }, + { url = "https://files.pythonhosted.org/packages/7d/64/bfa5f4a34d0f15c6aba1b73e73f7441a66d635bd03249d334a4796b7a924/ormsgpack-1.12.1-cp313-cp313-win_arm64.whl", hash = "sha256:cfa22c91cffc10a7fbd43729baff2de7d9c28cef2509085a704168ae31f02568", size = 109986, upload-time = "2025-12-14T07:57:26.569Z" }, + { url = "https://files.pythonhosted.org/packages/87/0e/78e5697164e3223b9b216c13e99f1acbc1ee9833490d68842b13da8ba883/ormsgpack-1.12.1-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b93c91efb1a70751a1902a5b43b27bd8fd38e0ca0365cf2cde2716423c15c3a6", size = 376758, upload-time = "2025-12-14T07:57:27.641Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/3a3cbb64703263d7bbaed7effa3ce78cb9add360a60aa7c544d7df28b641/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf0ea0389167b5fa8d2933dd3f33e887ec4ba68f89c25214d7eec4afd746d22", size = 202487, upload-time = "2025-12-14T07:57:29.051Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2c/807ebe2b77995599bbb1dec8c3f450d5d7dddee14ce3e1e71dc60e2e2a74/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f4c29af837f35af3375070689e781161e7cf019eb2f7cd641734ae45cd001c0d", size = 210853, upload-time = "2025-12-14T07:57:30.508Z" }, + { url = "https://files.pythonhosted.org/packages/25/57/2cdfc354e3ad8e847628f511f4d238799d90e9e090941e50b9d5ba955ae2/ormsgpack-1.12.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336fc65aa0fe65896a3dabaae31e332a0a98b4a00ad7b0afde21a7505fd23ff3", size = 211545, upload-time = "2025-12-14T07:57:31.585Z" }, + { url = "https://files.pythonhosted.org/packages/76/1d/c6fda560e4a8ff865b3aec8a86f7c95ab53f4532193a6ae4ab9db35f85aa/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:940f60aabfefe71dd6b82cb33f4ff10b2e7f5fcfa5f103cdb0a23b6aae4c713c", size = 386333, upload-time = "2025-12-14T07:57:32.957Z" }, + { url = "https://files.pythonhosted.org/packages/fc/3e/715081b36fceb8b497c68b87d384e1cc6d9c9c130ce3b435634d3d785b86/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:596ad9e1b6d4c95595c54aaf49b1392609ca68f562ce06f4f74a5bc4053bcda4", size = 479701, upload-time = "2025-12-14T07:57:34.686Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cf/01ad04def42b3970fc1a302c07f4b46339edf62ef9650247097260471f40/ormsgpack-1.12.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:575210e8fcbc7b0375026ba040a5eef223e9f66a4453d9623fc23282ae09c3c8", size = 388148, upload-time = "2025-12-14T07:57:35.771Z" }, + { url = "https://files.pythonhosted.org/packages/15/91/1fff2fc2b5943c740028f339154e7103c8f2edf1a881d9fbba2ce11c3b1d/ormsgpack-1.12.1-cp314-cp314-win_amd64.whl", hash = "sha256:647daa3718572280893456be44c60aea6690b7f2edc54c55648ee66e8f06550f", size = 116201, upload-time = "2025-12-14T07:57:36.763Z" }, + { url = "https://files.pythonhosted.org/packages/ed/66/142b542aed3f96002c7d1c33507ca6e1e0d0a42b9253ab27ef7ed5793bd9/ormsgpack-1.12.1-cp314-cp314-win_arm64.whl", hash = "sha256:a8b3ab762a6deaf1b6490ab46dda0c51528cf8037e0246c40875c6fe9e37b699", size = 110029, upload-time = "2025-12-14T07:57:37.703Z" }, + { url = "https://files.pythonhosted.org/packages/38/b3/ef4494438c90359e1547eaed3c5ec46e2c431d59a3de2af4e70ebd594c49/ormsgpack-1.12.1-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:12087214e436c1f6c28491949571abea759a63111908c4f7266586d78144d7a8", size = 376777, upload-time = "2025-12-14T07:57:38.795Z" }, + { url = "https://files.pythonhosted.org/packages/05/a0/1149a7163f8b0dfbc64bf9099b6f16d102ad3b03bcc11afee198d751da2d/ormsgpack-1.12.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e6d54c14cf86ef13f10ccade94d1e7de146aa9b17d371e18b16e95f329393b7", size = 202490, upload-time = "2025-12-14T07:57:40.168Z" }, + { url = "https://files.pythonhosted.org/packages/68/82/f2ec5e758d6a7106645cca9bb7137d98bce5d363789fa94075be6572057c/ormsgpack-1.12.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f3584d07882b7ea2a1a589f795a3af97fe4c2932b739408e6d1d9d286cad862", size = 211733, upload-time = "2025-12-14T07:57:42.253Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pathspec" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/28/2e/83722ece0f6ee24387d6cb830dd562ddbcd6ce0b9d76072c6849670c31b4/pathspec-1.0.1.tar.gz", hash = "sha256:e2769b508d0dd47b09af6ee2c75b2744a2cb1f474ae4b1494fd6a1b7a841613c", size = 129791, upload-time = "2026-01-06T13:02:55.15Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/fe/2257c71721aeab6a6e8aa1f00d01f2a20f58547d249a6c8fef5791f559fc/pathspec-1.0.1-py3-none-any.whl", hash = "sha256:8870061f22c58e6d83463cfce9a7dd6eca0512c772c1001fb09ac64091816721", size = 54584, upload-time = "2026-01-06T13:02:53.601Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, +] + +[[package]] +name = "portalocker" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/77/65b857a69ed876e1951e88aaba60f5ce6120c33703f7cb61a3c894b8c1b6/portalocker-3.2.0.tar.gz", hash = "sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac", size = 95644, upload-time = "2025-06-14T13:20:40.03Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/a6/38c8e2f318bf67d338f4d629e93b0b4b9af331f455f0390ea8ce4a099b26/portalocker-3.2.0-py3-none-any.whl", hash = "sha256:3cdc5f565312224bc570c49337bd21428bba0ef363bbcf58b9ef4a9f11779968", size = 22424, upload-time = "2025-06-14T13:20:38.083Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "protobuf" +version = "6.33.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" }, + { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" }, + { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" }, + { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, +] + +[[package]] +name = "pylint" +version = "4.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d2/b081da1a8930d00e3fc06352a1d449aaf815d4982319fab5d8cdb2e9ab35/pylint-4.0.4.tar.gz", hash = "sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2", size = 1571735, upload-time = "2025-11-30T13:29:04.315Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/92/d40f5d937517cc489ad848fc4414ecccc7592e4686b9071e09e64f5e378e/pylint-4.0.4-py3-none-any.whl", hash = "sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0", size = 536425, upload-time = "2025-11-30T13:29:02.53Z" }, +] + +[[package]] +name = "pypdf" +version = "6.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/9b/db1056a54eda8cd44f9e5128e87e1142cb328295dad92bbec0d39f251641/pypdf-6.5.0.tar.gz", hash = "sha256:9e78950906380ae4f2ce1d9039e9008098ba6366a4d9c7423c4bdbd6e6683404", size = 5277655, upload-time = "2025-12-21T11:07:19.876Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/db/f2e7703791a1f32532618b82789ddddb7173b9e22d97e34cc11950d8e330/pypdf-6.5.0-py3-none-any.whl", hash = "sha256:9cef8002aaedeecf648dfd9ff1ce38f20ae8d88e2534fced6630038906440b25", size = 329560, upload-time = "2025-12-21T11:07:18.173Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/96/804520d0850c7db98e5ccb70282e29208723f0964e88ffd9d0da2f52ea09/python_multipart-0.0.21.tar.gz", hash = "sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92", size = 37196, upload-time = "2025-12-17T09:24:22.446Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/76/03af049af4dcee5d27442f71b6924f01f3efb5d2bd34f23fcd563f2cc5f5/python_multipart-0.0.21-py3-none-any.whl", hash = "sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090", size = 24541, upload-time = "2025-12-17T09:24:21.153Z" }, +] + +[[package]] +name = "pywin32" +version = "311" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, + { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "qdrant-client" +version = "1.16.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "grpcio" }, + { name = "httpx", extra = ["http2"] }, + { name = "numpy" }, + { name = "portalocker" }, + { name = "protobuf" }, + { name = "pydantic" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/7d/3cd10e26ae97b35cf856ca1dc67576e42414ae39502c51165bb36bb1dff8/qdrant_client-1.16.2.tar.gz", hash = "sha256:ca4ef5f9be7b5eadeec89a085d96d5c723585a391eb8b2be8192919ab63185f0", size = 331112, upload-time = "2025-12-12T10:58:30.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/13/8ce16f808297e16968269de44a14f4fef19b64d9766be1d6ba5ba78b579d/qdrant_client-1.16.2-py3-none-any.whl", hash = "sha256:442c7ef32ae0f005e88b5d3c0783c63d4912b97ae756eb5e052523be682f17d3", size = 377186, upload-time = "2025-12-12T10:58:29.282Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.45" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/c7/1900b56ce19bff1c26f39a4ce427faec7716c81ac792bfac8b6a9f3dca93/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f", size = 3333760, upload-time = "2025-12-09T22:11:02.66Z" }, + { url = "https://files.pythonhosted.org/packages/0a/93/3be94d96bb442d0d9a60e55a6bb6e0958dd3457751c6f8502e56ef95fed0/sqlalchemy-2.0.45-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d", size = 3348268, upload-time = "2025-12-09T22:13:49.054Z" }, + { url = "https://files.pythonhosted.org/packages/48/4b/f88ded696e61513595e4a9778f9d3f2bf7332cce4eb0c7cedaabddd6687b/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4", size = 3278144, upload-time = "2025-12-09T22:11:04.14Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6a/310ecb5657221f3e1bd5288ed83aa554923fb5da48d760a9f7622afeb065/sqlalchemy-2.0.45-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6", size = 3313907, upload-time = "2025-12-09T22:13:50.598Z" }, + { url = "https://files.pythonhosted.org/packages/5c/39/69c0b4051079addd57c84a5bfb34920d87456dd4c90cf7ee0df6efafc8ff/sqlalchemy-2.0.45-cp312-cp312-win32.whl", hash = "sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953", size = 2112182, upload-time = "2025-12-09T21:39:30.824Z" }, + { url = "https://files.pythonhosted.org/packages/f7/4e/510db49dd89fc3a6e994bee51848c94c48c4a00dc905e8d0133c251f41a7/sqlalchemy-2.0.45-cp312-cp312-win_amd64.whl", hash = "sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1", size = 2139200, upload-time = "2025-12-09T21:39:32.321Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, + { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, + { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, + { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, + { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "tenacity" +version = "9.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dc/74/1789779d91f1961fa9438e9a8710cdae6bd138c80d7303996933d117264a/typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78", size = 13825, upload-time = "2023-05-24T20:25:47.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/f3/107a22063bf27bdccf2024833d3445f4eea42b2e598abfbd46f6a63b6cb0/typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", size = 8827, upload-time = "2023-05-24T20:25:45.287Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] + +[[package]] +name = "uuid-utils" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/0e/512fb221e4970c2f75ca9dae412d320b7d9ddc9f2b15e04ea8e44710396c/uuid_utils-0.12.0.tar.gz", hash = "sha256:252bd3d311b5d6b7f5dfce7a5857e27bb4458f222586bb439463231e5a9cbd64", size = 20889, upload-time = "2025-12-01T17:29:55.494Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/43/de5cd49a57b6293b911b6a9a62fc03e55db9f964da7d5882d9edbee1e9d2/uuid_utils-0.12.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3b9b30707659292f207b98f294b0e081f6d77e1fbc760ba5b41331a39045f514", size = 603197, upload-time = "2025-12-01T17:29:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/02/fa/5fd1d8c9234e44f0c223910808cde0de43bb69f7df1349e49b1afa7f2baa/uuid_utils-0.12.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:add3d820c7ec14ed37317375bea30249699c5d08ff4ae4dbee9fc9bce3bfbf65", size = 305168, upload-time = "2025-12-01T17:29:31.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c6/8633ac9942bf9dc97a897b5154e5dcffa58816ec4dd780b3b12b559ff05c/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8fce83ecb3b16af29c7809669056c4b6e7cc912cab8c6d07361645de12dd79", size = 340580, upload-time = "2025-12-01T17:29:32.362Z" }, + { url = "https://files.pythonhosted.org/packages/f3/88/8a61307b04b4da1c576373003e6d857a04dade52ab035151d62cb84d5cb5/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec921769afcb905035d785582b0791d02304a7850fbd6ce924c1a8976380dfc6", size = 346771, upload-time = "2025-12-01T17:29:33.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fb/aab2dcf94b991e62aa167457c7825b9b01055b884b888af926562864398c/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f3b060330f5899a92d5c723547dc6a95adef42433e9748f14c66859a7396664", size = 474781, upload-time = "2025-12-01T17:29:35.237Z" }, + { url = "https://files.pythonhosted.org/packages/5a/7a/dbd5e49c91d6c86dba57158bbfa0e559e1ddf377bb46dcfd58aea4f0d567/uuid_utils-0.12.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:908dfef7f0bfcf98d406e5dc570c25d2f2473e49b376de41792b6e96c1d5d291", size = 343685, upload-time = "2025-12-01T17:29:36.677Z" }, + { url = "https://files.pythonhosted.org/packages/1a/19/8c4b1d9f450159733b8be421a4e1fb03533709b80ed3546800102d085572/uuid_utils-0.12.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c6a24148926bd0ca63e8a2dabf4cc9dc329a62325b3ad6578ecd60fbf926506", size = 366482, upload-time = "2025-12-01T17:29:37.979Z" }, + { url = "https://files.pythonhosted.org/packages/82/43/c79a6e45687647f80a159c8ba34346f287b065452cc419d07d2212d38420/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:64a91e632669f059ef605f1771d28490b1d310c26198e46f754e8846dddf12f4", size = 523132, upload-time = "2025-12-01T17:29:39.293Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a2/b2d75a621260a40c438aa88593827dfea596d18316520a99e839f7a5fb9d/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:93c082212470bb4603ca3975916c205a9d7ef1443c0acde8fbd1e0f5b36673c7", size = 614218, upload-time = "2025-12-01T17:29:40.315Z" }, + { url = "https://files.pythonhosted.org/packages/13/6b/ba071101626edd5a6dabf8525c9a1537ff3d885dbc210540574a03901fef/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:431b1fb7283ba974811b22abd365f2726f8f821ab33f0f715be389640e18d039", size = 546241, upload-time = "2025-12-01T17:29:41.656Z" }, + { url = "https://files.pythonhosted.org/packages/01/12/9a942b81c0923268e6d85bf98d8f0a61fcbcd5e432fef94fdf4ce2ef8748/uuid_utils-0.12.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd7838c40149100299fa37cbd8bab5ee382372e8e65a148002a37d380df7c8", size = 511842, upload-time = "2025-12-01T17:29:43.107Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a7/c326f5163dd48b79368b87d8a05f5da4668dd228a3f5ca9d79d5fee2fc40/uuid_utils-0.12.0-cp39-abi3-win32.whl", hash = "sha256:487f17c0fee6cbc1d8b90fe811874174a9b1b5683bf2251549e302906a50fed3", size = 179088, upload-time = "2025-12-01T17:29:44.492Z" }, + { url = "https://files.pythonhosted.org/packages/38/92/41c8734dd97213ee1d5ae435cf4499705dc4f2751e3b957fd12376f61784/uuid_utils-0.12.0-cp39-abi3-win_amd64.whl", hash = "sha256:9598e7c9da40357ae8fffc5d6938b1a7017f09a1acbcc95e14af8c65d48c655a", size = 183003, upload-time = "2025-12-01T17:29:45.47Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/52ab0359618987331a1f739af837d26168a4b16281c9c3ab46519940c628/uuid_utils-0.12.0-cp39-abi3-win_arm64.whl", hash = "sha256:c9bea7c5b2aa6f57937ebebeee4d4ef2baad10f86f1b97b58a3f6f34c14b4e84", size = 182975, upload-time = "2025-12-01T17:29:46.444Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/d1/8f3c683c9561a4e6689dd3b1d345c815f10f86acd044ee1fb9a4dcd0b8c5/uvicorn-0.40.0.tar.gz", hash = "sha256:839676675e87e73694518b5574fd0f24c9d97b46bea16df7b8c05ea1a51071ea", size = 81761, upload-time = "2025-12-21T14:16:22.45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/d8/2083a1daa7439a66f3a48589a57d576aa117726762618f6bb09fe3798796/uvicorn-0.40.0-py3-none-any.whl", hash = "sha256:c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee", size = 68502, upload-time = "2025-12-21T14:16:21.041Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.35.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, +] + +[[package]] +name = "xxhash" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160, upload-time = "2025-10-02T14:37:08.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914, upload-time = "2025-10-02T14:34:38.6Z" }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163, upload-time = "2025-10-02T14:34:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411, upload-time = "2025-10-02T14:34:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883, upload-time = "2025-10-02T14:34:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392, upload-time = "2025-10-02T14:34:45.042Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898, upload-time = "2025-10-02T14:34:46.302Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655, upload-time = "2025-10-02T14:34:47.571Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001, upload-time = "2025-10-02T14:34:49.273Z" }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431, upload-time = "2025-10-02T14:34:50.798Z" }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617, upload-time = "2025-10-02T14:34:51.954Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534, upload-time = "2025-10-02T14:34:53.276Z" }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876, upload-time = "2025-10-02T14:34:54.371Z" }, + { url = "https://files.pythonhosted.org/packages/33/76/35d05267ac82f53ae9b0e554da7c5e281ee61f3cad44c743f0fcd354f211/xxhash-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec", size = 32738, upload-time = "2025-10-02T14:34:55.839Z" }, + { url = "https://files.pythonhosted.org/packages/31/a8/3fbce1cd96534a95e35d5120637bf29b0d7f5d8fa2f6374e31b4156dd419/xxhash-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1", size = 30821, upload-time = "2025-10-02T14:34:57.219Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ea/d387530ca7ecfa183cb358027f1833297c6ac6098223fd14f9782cd0015c/xxhash-3.6.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6", size = 194127, upload-time = "2025-10-02T14:34:59.21Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/71435dcb99874b09a43b8d7c54071e600a7481e42b3e3ce1eb5226a5711a/xxhash-3.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263", size = 212975, upload-time = "2025-10-02T14:35:00.816Z" }, + { url = "https://files.pythonhosted.org/packages/84/7a/c2b3d071e4bb4a90b7057228a99b10d51744878f4a8a6dd643c8bd897620/xxhash-3.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546", size = 212241, upload-time = "2025-10-02T14:35:02.207Z" }, + { url = "https://files.pythonhosted.org/packages/81/5f/640b6eac0128e215f177df99eadcd0f1b7c42c274ab6a394a05059694c5a/xxhash-3.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89", size = 445471, upload-time = "2025-10-02T14:35:03.61Z" }, + { url = "https://files.pythonhosted.org/packages/5e/1e/3c3d3ef071b051cc3abbe3721ffb8365033a172613c04af2da89d5548a87/xxhash-3.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d", size = 193936, upload-time = "2025-10-02T14:35:05.013Z" }, + { url = "https://files.pythonhosted.org/packages/2c/bd/4a5f68381939219abfe1c22a9e3a5854a4f6f6f3c4983a87d255f21f2e5d/xxhash-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7", size = 210440, upload-time = "2025-10-02T14:35:06.239Z" }, + { url = "https://files.pythonhosted.org/packages/eb/37/b80fe3d5cfb9faff01a02121a0f4d565eb7237e9e5fc66e73017e74dcd36/xxhash-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db", size = 197990, upload-time = "2025-10-02T14:35:07.735Z" }, + { url = "https://files.pythonhosted.org/packages/d7/fd/2c0a00c97b9e18f72e1f240ad4e8f8a90fd9d408289ba9c7c495ed7dc05c/xxhash-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42", size = 210689, upload-time = "2025-10-02T14:35:09.438Z" }, + { url = "https://files.pythonhosted.org/packages/93/86/5dd8076a926b9a95db3206aba20d89a7fc14dd5aac16e5c4de4b56033140/xxhash-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11", size = 414068, upload-time = "2025-10-02T14:35:11.162Z" }, + { url = "https://files.pythonhosted.org/packages/af/3c/0bb129170ee8f3650f08e993baee550a09593462a5cddd8e44d0011102b1/xxhash-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd", size = 191495, upload-time = "2025-10-02T14:35:12.971Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3a/6797e0114c21d1725e2577508e24006fd7ff1d8c0c502d3b52e45c1771d8/xxhash-3.6.0-cp313-cp313-win32.whl", hash = "sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799", size = 30620, upload-time = "2025-10-02T14:35:14.129Z" }, + { url = "https://files.pythonhosted.org/packages/86/15/9bc32671e9a38b413a76d24722a2bf8784a132c043063a8f5152d390b0f9/xxhash-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392", size = 31542, upload-time = "2025-10-02T14:35:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/39/c5/cc01e4f6188656e56112d6a8e0dfe298a16934b8c47a247236549a3f7695/xxhash-3.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6", size = 27880, upload-time = "2025-10-02T14:35:16.315Z" }, + { url = "https://files.pythonhosted.org/packages/f3/30/25e5321c8732759e930c555176d37e24ab84365482d257c3b16362235212/xxhash-3.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702", size = 32956, upload-time = "2025-10-02T14:35:17.413Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3c/0573299560d7d9f8ab1838f1efc021a280b5ae5ae2e849034ef3dee18810/xxhash-3.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db", size = 31072, upload-time = "2025-10-02T14:35:18.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1c/52d83a06e417cd9d4137722693424885cc9878249beb3a7c829e74bf7ce9/xxhash-3.6.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54", size = 196409, upload-time = "2025-10-02T14:35:20.31Z" }, + { url = "https://files.pythonhosted.org/packages/e3/8e/c6d158d12a79bbd0b878f8355432075fc82759e356ab5a111463422a239b/xxhash-3.6.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f", size = 215736, upload-time = "2025-10-02T14:35:21.616Z" }, + { url = "https://files.pythonhosted.org/packages/bc/68/c4c80614716345d55071a396cf03d06e34b5f4917a467faf43083c995155/xxhash-3.6.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5", size = 214833, upload-time = "2025-10-02T14:35:23.32Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e9/ae27c8ffec8b953efa84c7c4a6c6802c263d587b9fc0d6e7cea64e08c3af/xxhash-3.6.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1", size = 448348, upload-time = "2025-10-02T14:35:25.111Z" }, + { url = "https://files.pythonhosted.org/packages/d7/6b/33e21afb1b5b3f46b74b6bd1913639066af218d704cc0941404ca717fc57/xxhash-3.6.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee", size = 196070, upload-time = "2025-10-02T14:35:26.586Z" }, + { url = "https://files.pythonhosted.org/packages/96/b6/fcabd337bc5fa624e7203aa0fa7d0c49eed22f72e93229431752bddc83d9/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd", size = 212907, upload-time = "2025-10-02T14:35:28.087Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d3/9ee6160e644d660fcf176c5825e61411c7f62648728f69c79ba237250143/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729", size = 200839, upload-time = "2025-10-02T14:35:29.857Z" }, + { url = "https://files.pythonhosted.org/packages/0d/98/e8de5baa5109394baf5118f5e72ab21a86387c4f89b0e77ef3e2f6b0327b/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292", size = 213304, upload-time = "2025-10-02T14:35:31.222Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1d/71056535dec5c3177eeb53e38e3d367dd1d16e024e63b1cee208d572a033/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf", size = 416930, upload-time = "2025-10-02T14:35:32.517Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6c/5cbde9de2cd967c322e651c65c543700b19e7ae3e0aae8ece3469bf9683d/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033", size = 193787, upload-time = "2025-10-02T14:35:33.827Z" }, + { url = "https://files.pythonhosted.org/packages/19/fa/0172e350361d61febcea941b0cc541d6e6c8d65d153e85f850a7b256ff8a/xxhash-3.6.0-cp313-cp313t-win32.whl", hash = "sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec", size = 30916, upload-time = "2025-10-02T14:35:35.107Z" }, + { url = "https://files.pythonhosted.org/packages/ad/e6/e8cf858a2b19d6d45820f072eff1bea413910592ff17157cabc5f1227a16/xxhash-3.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8", size = 31799, upload-time = "2025-10-02T14:35:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/56/15/064b197e855bfb7b343210e82490ae672f8bc7cdf3ddb02e92f64304ee8a/xxhash-3.6.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746", size = 28044, upload-time = "2025-10-02T14:35:37.195Z" }, + { url = "https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e", size = 32754, upload-time = "2025-10-02T14:35:38.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405", size = 30846, upload-time = "2025-10-02T14:35:39.6Z" }, + { url = "https://files.pythonhosted.org/packages/fe/71/8bc5be2bb00deb5682e92e8da955ebe5fa982da13a69da5a40a4c8db12fb/xxhash-3.6.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3", size = 194343, upload-time = "2025-10-02T14:35:40.69Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/52badfb2aecec2c377ddf1ae75f55db3ba2d321c5e164f14461c90837ef3/xxhash-3.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6", size = 213074, upload-time = "2025-10-02T14:35:42.29Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/ae46b4e9b92e537fa30d03dbc19cdae57ed407e9c26d163895e968e3de85/xxhash-3.6.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063", size = 212388, upload-time = "2025-10-02T14:35:43.929Z" }, + { url = "https://files.pythonhosted.org/packages/f5/80/49f88d3afc724b4ac7fbd664c8452d6db51b49915be48c6982659e0e7942/xxhash-3.6.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7", size = 445614, upload-time = "2025-10-02T14:35:45.216Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b", size = 194024, upload-time = "2025-10-02T14:35:46.959Z" }, + { url = "https://files.pythonhosted.org/packages/78/d1/8e225ff7113bf81545cfdcd79eef124a7b7064a0bba53605ff39590b95c2/xxhash-3.6.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd", size = 210541, upload-time = "2025-10-02T14:35:48.301Z" }, + { url = "https://files.pythonhosted.org/packages/6f/58/0f89d149f0bad89def1a8dd38feb50ccdeb643d9797ec84707091d4cb494/xxhash-3.6.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0", size = 198305, upload-time = "2025-10-02T14:35:49.584Z" }, + { url = "https://files.pythonhosted.org/packages/11/38/5eab81580703c4df93feb5f32ff8fa7fe1e2c51c1f183ee4e48d4bb9d3d7/xxhash-3.6.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152", size = 210848, upload-time = "2025-10-02T14:35:50.877Z" }, + { url = "https://files.pythonhosted.org/packages/5e/6b/953dc4b05c3ce678abca756416e4c130d2382f877a9c30a20d08ee6a77c0/xxhash-3.6.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11", size = 414142, upload-time = "2025-10-02T14:35:52.15Z" }, + { url = "https://files.pythonhosted.org/packages/08/a9/238ec0d4e81a10eb5026d4a6972677cbc898ba6c8b9dbaec12ae001b1b35/xxhash-3.6.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5", size = 191547, upload-time = "2025-10-02T14:35:53.547Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ee/3cf8589e06c2164ac77c3bf0aa127012801128f1feebf2a079272da5737c/xxhash-3.6.0-cp314-cp314-win32.whl", hash = "sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f", size = 31214, upload-time = "2025-10-02T14:35:54.746Z" }, + { url = "https://files.pythonhosted.org/packages/02/5d/a19552fbc6ad4cb54ff953c3908bbc095f4a921bc569433d791f755186f1/xxhash-3.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad", size = 32290, upload-time = "2025-10-02T14:35:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/b1/11/dafa0643bc30442c887b55baf8e73353a344ee89c1901b5a5c54a6c17d39/xxhash-3.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679", size = 28795, upload-time = "2025-10-02T14:35:57.162Z" }, + { url = "https://files.pythonhosted.org/packages/2c/db/0e99732ed7f64182aef4a6fb145e1a295558deec2a746265dcdec12d191e/xxhash-3.6.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4", size = 32955, upload-time = "2025-10-02T14:35:58.267Z" }, + { url = "https://files.pythonhosted.org/packages/55/f4/2a7c3c68e564a099becfa44bb3d398810cc0ff6749b0d3cb8ccb93f23c14/xxhash-3.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67", size = 31072, upload-time = "2025-10-02T14:35:59.382Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d9/72a29cddc7250e8a5819dad5d466facb5dc4c802ce120645630149127e73/xxhash-3.6.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad", size = 196579, upload-time = "2025-10-02T14:36:00.838Z" }, + { url = "https://files.pythonhosted.org/packages/63/93/b21590e1e381040e2ca305a884d89e1c345b347404f7780f07f2cdd47ef4/xxhash-3.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b", size = 215854, upload-time = "2025-10-02T14:36:02.207Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b8/edab8a7d4fa14e924b29be877d54155dcbd8b80be85ea00d2be3413a9ed4/xxhash-3.6.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b", size = 214965, upload-time = "2025-10-02T14:36:03.507Z" }, + { url = "https://files.pythonhosted.org/packages/27/67/dfa980ac7f0d509d54ea0d5a486d2bb4b80c3f1bb22b66e6a05d3efaf6c0/xxhash-3.6.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca", size = 448484, upload-time = "2025-10-02T14:36:04.828Z" }, + { url = "https://files.pythonhosted.org/packages/8c/63/8ffc2cc97e811c0ca5d00ab36604b3ea6f4254f20b7bc658ca825ce6c954/xxhash-3.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a", size = 196162, upload-time = "2025-10-02T14:36:06.182Z" }, + { url = "https://files.pythonhosted.org/packages/4b/77/07f0e7a3edd11a6097e990f6e5b815b6592459cb16dae990d967693e6ea9/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99", size = 213007, upload-time = "2025-10-02T14:36:07.733Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d8/bc5fa0d152837117eb0bef6f83f956c509332ce133c91c63ce07ee7c4873/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3", size = 200956, upload-time = "2025-10-02T14:36:09.106Z" }, + { url = "https://files.pythonhosted.org/packages/26/a5/d749334130de9411783873e9b98ecc46688dad5db64ca6e04b02acc8b473/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6", size = 213401, upload-time = "2025-10-02T14:36:10.585Z" }, + { url = "https://files.pythonhosted.org/packages/89/72/abed959c956a4bfc72b58c0384bb7940663c678127538634d896b1195c10/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93", size = 417083, upload-time = "2025-10-02T14:36:12.276Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b3/62fd2b586283b7d7d665fb98e266decadf31f058f1cf6c478741f68af0cb/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518", size = 193913, upload-time = "2025-10-02T14:36:14.025Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/c19c42c5b3f5a4aad748a6d5b4f23df3bed7ee5445accc65a0fb3ff03953/xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119", size = 31586, upload-time = "2025-10-02T14:36:15.603Z" }, + { url = "https://files.pythonhosted.org/packages/03/d6/4cc450345be9924fd5dc8c590ceda1db5b43a0a889587b0ae81a95511360/xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f", size = 32526, upload-time = "2025-10-02T14:36:16.708Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c9/7243eb3f9eaabd1a88a5a5acadf06df2d83b100c62684b7425c6a11bcaa8/xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95", size = 28898, upload-time = "2025-10-02T14:36:17.843Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] + +[[package]] +name = "zstandard" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, + { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, + { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" }, + { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" }, + { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" }, + { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" }, + { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" }, + { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, + { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" }, + { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" }, + { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" }, + { url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload-time = "2025-09-14T22:17:31.044Z" }, + { url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload-time = "2025-09-14T22:17:32.711Z" }, + { url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload-time = "2025-09-14T22:17:34.41Z" }, + { url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload-time = "2025-09-14T22:17:36.084Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload-time = "2025-09-14T22:17:37.891Z" }, + { url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload-time = "2025-09-14T22:17:40.206Z" }, + { url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload-time = "2025-09-14T22:17:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload-time = "2025-09-14T22:17:43.577Z" }, + { url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload-time = "2025-09-14T22:17:45.271Z" }, + { url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload-time = "2025-09-14T22:17:47.08Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload-time = "2025-09-14T22:17:48.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" }, + { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" }, + { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" }, + { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" }, + { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" }, + { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" }, + { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" }, +] From 2518d83437df73525491a785ce9c613255a70bdc Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:08:02 +0000 Subject: [PATCH 051/108] Add vector proxy interface --- .../vector_store/__init__.py | 0 .../context_retriever/vector_store/core.py | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 services/context-retriever/src/context_retriever/vector_store/__init__.py create mode 100644 services/context-retriever/src/context_retriever/vector_store/core.py diff --git a/services/context-retriever/src/context_retriever/vector_store/__init__.py b/services/context-retriever/src/context_retriever/vector_store/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/context-retriever/src/context_retriever/vector_store/core.py b/services/context-retriever/src/context_retriever/vector_store/core.py new file mode 100644 index 0000000..b6e01a7 --- /dev/null +++ b/services/context-retriever/src/context_retriever/vector_store/core.py @@ -0,0 +1,51 @@ +"""Contains core interfaces and utilities for vector store operations.""" + +from abc import ABC, abstractmethod +from typing import Iterator, TypeVar + +import pydantic +from langchain_core.documents import Document + + +class EmbeddingModelCfg(pydantic.BaseModel): + """Configuration of embedding model endpoint.""" + model_name: str + url: str + + +class VectorStoreProxy(ABC): + """Interface for classes handling vector store operations.""" + + @abstractmethod + def store_documents(self, documents: list[Document]) -> None: + """Stores the given documents in the vector store. + + Args: + documents: List of documents to be stored. + """ + + @abstractmethod + def retrieve_documents(self, query: str) -> list[Document]: + """Retrieves documents from the vector store based on the given query. + + Args: + query: The query string to search for relevant documents. + + Returns: + List of documents matching the query. + """ + + +T = TypeVar('T') + + +def batch_iterate(iterable: list[T], batch_size: int) -> Iterator[list[T]]: + """Yields successive batches from an iterable. + + Args: + iterable: The iterable to be divided into batches. + batch_size: The size of each batch. + """ + + for i in range(0, len(iterable), batch_size): + yield iterable[i:i + batch_size] From b15a37da255542c95cbf238f0ec7f4c72e497bbf Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:11:22 +0000 Subject: [PATCH 052/108] Introduce server entrypoint and pdf uploading logic --- services/context-retriever/cfg/main.yaml | 11 + .../cfg/vector_store/qdrant.yaml | 7 + services/context-retriever/main.py | 196 ++++++++++++++++++ .../src/context_retriever/__init__.py | 0 .../doc_preparation_service.py | 103 +++++++++ .../context_retriever/vector_store/qdrant.py | 102 +++++++++ 6 files changed, 419 insertions(+) create mode 100644 services/context-retriever/cfg/main.yaml create mode 100644 services/context-retriever/cfg/vector_store/qdrant.yaml create mode 100644 services/context-retriever/main.py create mode 100644 services/context-retriever/src/context_retriever/__init__.py create mode 100644 services/context-retriever/src/context_retriever/doc_preparation_service.py create mode 100644 services/context-retriever/src/context_retriever/vector_store/qdrant.py diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml new file mode 100644 index 0000000..8f679e4 --- /dev/null +++ b/services/context-retriever/cfg/main.yaml @@ -0,0 +1,11 @@ +--- +server_host: 0.0.0.0 +server_port: 8081 +n_server_workers: 1 +persist_data_path: data/ +doc_processing: + chunk_size: 2000 + chunk_overlap: 400 + +defaults: + - vector_store: qdrant \ No newline at end of file diff --git a/services/context-retriever/cfg/vector_store/qdrant.yaml b/services/context-retriever/cfg/vector_store/qdrant.yaml new file mode 100644 index 0000000..3807b49 --- /dev/null +++ b/services/context-retriever/cfg/vector_store/qdrant.yaml @@ -0,0 +1,7 @@ +driver: qdrant +url: http://localhost:6333 +collection_name: documents +uploading_batch_size: 8 +embedding_model: + model_name: nomic-embed-text:v1.5 + url: http://localhost:11436 \ No newline at end of file diff --git a/services/context-retriever/main.py b/services/context-retriever/main.py new file mode 100644 index 0000000..0f82788 --- /dev/null +++ b/services/context-retriever/main.py @@ -0,0 +1,196 @@ +""""Starts the backend server for the entrypoint service.""" +import json +import logging +import os +import sys +from contextlib import asynccontextmanager +from datetime import datetime +from typing import Any + +import fastapi +import hydra +import omegaconf +import pydantic +import uvicorn + +from context_retriever import doc_preparation_service +from context_retriever import doc_retrieval_service +from context_retriever.vector_store import qdrant as qdrant_vs +from context_retriever.vector_store.core import EmbeddingModelCfg + + +def _logger() -> logging.Logger: + return logging.getLogger('context_retriever') + + +doc_prep: doc_preparation_service.DocPreparationService | None = None # pylint: disable=invalid-name +doc_retrieval: doc_retrieval_service.DocRetrievalService | None = None # pylint: disable=invalid-name + + +@asynccontextmanager +async def lifespan(_): # type: ignore + """Sets up global contexts used by the server workers.""" + + cfg_serialized = os.environ.get('CONTEXT_RETRIEVER_SERVER_CFG', None) + + if cfg_serialized is None: + _logger().critical('Failed to load context_retriever server config from env.') + sys.exit(1) + + cfg = omegaconf.OmegaConf.create(json.loads(cfg_serialized)) + + # The llm_service is designed to be used by the endpoint handlers as a global service. It is + # not assigned in the `main` function because the uvicorn workers don't call it, as opposed to + # the `lifespan` callback. + global doc_prep # pylint: disable=global-statement + global doc_retrieval # pylint: disable=global-statement + + if cfg.vector_store.driver == 'qdrant': + vector_store_proxy = qdrant_vs.QdrantProxy( + qdrant_vs.QdrantProxyCfg( + url=cfg.vector_store.url, + collection_name=cfg.vector_store.collection_name, + uploading_batch_size=cfg.vector_store.uploading_batch_size, + embedding_model=EmbeddingModelCfg( + **cfg.vector_store.embedding_model + ) + ) + ) + else: + _logger().critical('Unsupported vector store driver: %s', cfg.vector_store.driver) + sys.exit(1) + + doc_prep = doc_preparation_service.DocPreparationService( + vector_store_proxy=vector_store_proxy, + doc_processing_cfg=doc_preparation_service.DocProcessingCfg( + **cfg.doc_processing) + ) + doc_retrieval = doc_retrieval_service.DocRetrievalService() + + yield + + +app = fastapi.FastAPI(lifespan=lifespan) + + +@app.get('/ping') +async def read_ping() -> dict[str, str]: + """Health check endpoint.""" + return {'message': 'Service is running'} + + +class RequestCollectContextInfo(pydantic.BaseModel): + """Request to collect context documents from the vector store.""" + user_message: str + chat_history: list[dict[str, Any]] + + +class ResponseCollectContextInfo(pydantic.BaseModel): + """Response from context-retriever after collecting context documents.""" + context_docs: list[dict[str, Any]] + + +@app.post('/collect_context_info') +async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: + """Collects context documents from the vector store based on user message and chat history.""" + return ResponseCollectContextInfo(context_docs=[]) + + +class ResponseUploadDocument(pydantic.BaseModel): + """Response from context-retriever to web-app after uploading a document.""" + error: str | None = None + + +@app.post('/upload_pdf') +async def upload_pdf(file: fastapi.UploadFile) -> ResponseUploadDocument: + """Processes and saves an uploaded PDF document to the vector store.""" + + assert doc_prep is not None + + if file.content_type is None: + return ResponseUploadDocument(error='Cannot determine content type for the uploaded PDF.') + + if file.size is None: + return ResponseUploadDocument(error='Cannot determine file size for the uploaded PDF.') + + is_ok, error_msg = doc_prep.upload_pdf( + file_size=file.size, + content_type=file.content_type, + file_stream=file.file + ) + + if not is_ok: + return ResponseUploadDocument(error=error_msg) + + return ResponseUploadDocument() + + +def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: + + logging.config.dictConfig({ + 'version': 1, + 'loggers': { + 'root': { + 'level': 'WARNING', + 'handlers': ['console', 'file'] + }, + 'context_retriever': { + 'level': 'DEBUG', + 'handlers': ['console', 'file'], + 'propagate': False + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'level': 'INFO', + 'formatter': 'default' + }, + 'file': { + 'class': 'logging.handlers.RotatingFileHandler', + 'level': 'DEBUG', + 'formatter': 'default', + 'filename': os.path.join(script_cfg.persist_data_path, + 'log', + f'{datetime.now().strftime('%Y-%m-%d_%H:%M:%S')}.log'), + 'maxBytes': 5_000_000, + 'backupCount': 5, + 'encoding': 'utf-8', + } + }, + 'formatters': { + 'default': { + 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + } + } + }) + + +@hydra.main(version_base=None, config_path='cfg', config_name='main') +def main(cfg: omegaconf.DictConfig) -> None: + """Initializes and serves the web app.""" + + _logger().info('Script configuration:\n%s', omegaconf.OmegaConf.to_yaml(cfg)) + + os.makedirs(os.path.join(cfg.persist_data_path, 'log'), exist_ok=True) + + _configure_logging(cfg) + + _logger().info('Starting server on %s:%d with %d workers.', + cfg.server_host, cfg.server_port, cfg.n_server_workers) + + cfg_serialized = json.dumps(omegaconf.OmegaConf.to_container(cfg)) + os.environ['CONTEXT_RETRIEVER_SERVER_CFG'] = cfg_serialized + + uvicorn.run('main:app', + host=cfg.server_host, + port=cfg.server_port, + workers=cfg.n_server_workers, + log_level='info', + access_log=True, + limit_concurrency=1000, + timeout_keep_alive=5) + + +if __name__ == '__main__': + main() # pylint: disable=no-value-for-parameter diff --git a/services/context-retriever/src/context_retriever/__init__.py b/services/context-retriever/src/context_retriever/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/context-retriever/src/context_retriever/doc_preparation_service.py b/services/context-retriever/src/context_retriever/doc_preparation_service.py new file mode 100644 index 0000000..a9b0a4b --- /dev/null +++ b/services/context-retriever/src/context_retriever/doc_preparation_service.py @@ -0,0 +1,103 @@ +"""Contains service that prepares documents for storage in the vector store.""" + +from typing import BinaryIO +import tempfile +import logging + +import pydantic +from langchain_community import document_loaders +import langchain_text_splitters +from langchain_core.documents import Document + +from context_retriever.vector_store.core import VectorStoreProxy + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class DocProcessingCfg(pydantic.BaseModel): + """Configuration for document processing.""" + chunk_size: int + chunk_overlap: int + + +class DocPreparationService: + """Validates, processes and saves documents to the vector store.""" + + _MAX_PDF_SIZE_BYTES = 10 * 1024 * 1024 # 10 MB + _PDF_ALLOWED_FIELDS = ('title', 'author') + + def __init__(self, + vector_store_proxy: VectorStoreProxy, + doc_processing_cfg: DocProcessingCfg) -> None: + + _logger().info('Initializing DocPreparationService with config: %s', + doc_processing_cfg) + + self._vector_store_proxy = vector_store_proxy + + self._text_splitter = langchain_text_splitters.RecursiveCharacterTextSplitter( + separators=["\n\n", "\n", " "], + chunk_size=doc_processing_cfg.chunk_size, + chunk_overlap=doc_processing_cfg.chunk_overlap, + length_function=len, + is_separator_regex=False + ) + + def upload_pdf(self, + file_size: int, + content_type: str, + file_stream: BinaryIO + ) -> tuple[bool, str]: + """Uploads a PDF document to the vector store. + Args: + file_size: Size of the file in bytes. + content_type: Content type of the file. + file_stream: Stream of the file to be uploaded. + + Returns: + A tuple where the first element indicates success, and the second element contains + an error message if any. + """ + + if content_type != 'application/pdf': + return False, 'Invalid content type. Only PDF files are supported.' + + if file_size > self._MAX_PDF_SIZE_BYTES: + return (False, + f'File size exceeds the maximum limit of {self._MAX_PDF_SIZE_BYTES} bytes.') + + with tempfile.NamedTemporaryFile(delete=True) as temp_file: + temp_file.write(file_stream.read()) + temp_file.flush() + + pdf_pages = document_loaders.PyPDFLoader(temp_file.name).load() + + self._sanitize_pdf_metadata(pdf_pages) + + _logger().debug('Uploading PDF: size=%d, title=%s.', + file_size, + pdf_pages[0].metadata['title']) + + chunks = self._text_splitter.split_documents(pdf_pages) + + self._save_chunks_to_store(chunks) + + return True, '' + + def _save_chunks_to_store(self, chunks: list[Document]) -> None: + """Saves the processed document chunks to the vector store.""" + + self._vector_store_proxy.store_documents(chunks) + + def _sanitize_pdf_metadata(self, pdf_pages: list[Document]) -> None: + """Sanitizes metadata of PDF documents to remove unnecessary fields.""" + + for page in pdf_pages: + + page.metadata = { + 'page': page.metadata.get('page_label', 'Unknown'), + 'title': page.metadata.get('title', 'Unknown'), + 'author': page.metadata.get('author', 'Unknown') + } diff --git a/services/context-retriever/src/context_retriever/vector_store/qdrant.py b/services/context-retriever/src/context_retriever/vector_store/qdrant.py new file mode 100644 index 0000000..da27c03 --- /dev/null +++ b/services/context-retriever/src/context_retriever/vector_store/qdrant.py @@ -0,0 +1,102 @@ +"""Contains class for handling communication with Qdrant vector store.""" + +import logging + +import qdrant_client +from qdrant_client.models import VectorParams, Distance +from langchain_ollama.embeddings import OllamaEmbeddings +from langchain_core.documents import Document +import pydantic + +from context_retriever.vector_store import core as vs_core + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class QdrantProxyCfg(pydantic.BaseModel): + """Configuration for vector store proxy.""" + url: str + collection_name: str + uploading_batch_size: int + embedding_model: vs_core.EmbeddingModelCfg + + +class QdrantProxy(vs_core.VectorStoreProxy): + """Handles communication with Qdrant vector store.""" + + def __init__(self, cfg: QdrantProxyCfg) -> None: + + _logger().info('Initializing QdrantProxy with config: %s', cfg) + + self._cfg = cfg + + self._client = qdrant_client.QdrantClient( + url=self._cfg.url + ) + + self._embedding_model = OllamaEmbeddings( + model=self._cfg.embedding_model.model_name, + base_url=self._cfg.embedding_model.url + ) + + self._ensure_collection_exists() + + def store_documents(self, documents: list[Document]) -> None: + """Stores the given documents in the vector store. + + Args: + documents: List of documents to be stored. + """ + + _logger().debug('Storing %d documents in collection \'%s\'', + len(documents), self._cfg.collection_name) + + for batch_docs in vs_core.batch_iterate(documents, self._cfg.uploading_batch_size): + + embedded_docs = self._embedding_model.embed_documents( + [doc.page_content for doc in batch_docs]) + + self._client.upload_collection( + collection_name=self._cfg.collection_name, + vectors=embedded_docs, + payload=[{'text': doc.page_content} for doc in batch_docs], + ) + + def retrieve_documents(self, query: str) -> list[Document]: + """Retrieves documents from the vector store based on the given query. + + Args: + query: The query string to search for relevant documents. + + Returns: + List of documents matching the query. + """ + + _logger().debug('Retrieving documents from collection \'%s\' for query: \'%s\'', + self._cfg.collection_name, query) + + return [] + + def _ensure_collection_exists(self) -> None: + """Ensures that the specified collection exists in the Qdrant vector store.""" + + if not self._client.collection_exists(self._cfg.collection_name): + + _logger().debug('Collection \'%s\' does not exist. Creating new collection.', + self._cfg.collection_name) + + vector_size = self._determine_vector_size() + + self._client.create_collection( + collection_name=self._cfg.collection_name, + vectors_config=VectorParams(size=vector_size, distance=Distance.DOT, on_disk=True) + ) + + def _determine_vector_size(self) -> int: + """Determines the size of the embedding vectors produced by the embedding model.""" + + sample_text = "Sample text for embedding size determination." + embedding = self._embedding_model.embed_query(sample_text) + return len(embedding) From d077c8cf605127b2369049eceaf1756becdf080b Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 13:54:54 +0000 Subject: [PATCH 053/108] Made doc uploading functions async --- services/context-retriever/main.py | 5 ++--- .../doc_preparation_service.py | 17 ++++++----------- .../src/context_retriever/vector_store/core.py | 4 ++-- .../context_retriever/vector_store/qdrant.py | 6 +++--- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/services/context-retriever/main.py b/services/context-retriever/main.py index 0f82788..00e408d 100644 --- a/services/context-retriever/main.py +++ b/services/context-retriever/main.py @@ -62,8 +62,7 @@ async def lifespan(_): # type: ignore doc_prep = doc_preparation_service.DocPreparationService( vector_store_proxy=vector_store_proxy, - doc_processing_cfg=doc_preparation_service.DocProcessingCfg( - **cfg.doc_processing) + doc_processing_cfg=doc_preparation_service.DocProcessingCfg(**cfg.doc_processing) ) doc_retrieval = doc_retrieval_service.DocRetrievalService() @@ -113,7 +112,7 @@ async def upload_pdf(file: fastapi.UploadFile) -> ResponseUploadDocument: if file.size is None: return ResponseUploadDocument(error='Cannot determine file size for the uploaded PDF.') - is_ok, error_msg = doc_prep.upload_pdf( + is_ok, error_msg = await doc_prep.upload_pdf( file_size=file.size, content_type=file.content_type, file_stream=file.file diff --git a/services/context-retriever/src/context_retriever/doc_preparation_service.py b/services/context-retriever/src/context_retriever/doc_preparation_service.py index a9b0a4b..0278660 100644 --- a/services/context-retriever/src/context_retriever/doc_preparation_service.py +++ b/services/context-retriever/src/context_retriever/doc_preparation_service.py @@ -45,11 +45,11 @@ def __init__(self, is_separator_regex=False ) - def upload_pdf(self, - file_size: int, - content_type: str, - file_stream: BinaryIO - ) -> tuple[bool, str]: + async def upload_pdf(self, + file_size: int, + content_type: str, + file_stream: BinaryIO + ) -> tuple[bool, str]: """Uploads a PDF document to the vector store. Args: file_size: Size of the file in bytes. @@ -82,15 +82,10 @@ def upload_pdf(self, chunks = self._text_splitter.split_documents(pdf_pages) - self._save_chunks_to_store(chunks) + await self._vector_store_proxy.store_documents(chunks) return True, '' - def _save_chunks_to_store(self, chunks: list[Document]) -> None: - """Saves the processed document chunks to the vector store.""" - - self._vector_store_proxy.store_documents(chunks) - def _sanitize_pdf_metadata(self, pdf_pages: list[Document]) -> None: """Sanitizes metadata of PDF documents to remove unnecessary fields.""" diff --git a/services/context-retriever/src/context_retriever/vector_store/core.py b/services/context-retriever/src/context_retriever/vector_store/core.py index b6e01a7..229d17b 100644 --- a/services/context-retriever/src/context_retriever/vector_store/core.py +++ b/services/context-retriever/src/context_retriever/vector_store/core.py @@ -17,7 +17,7 @@ class VectorStoreProxy(ABC): """Interface for classes handling vector store operations.""" @abstractmethod - def store_documents(self, documents: list[Document]) -> None: + async def store_documents(self, documents: list[Document]) -> None: """Stores the given documents in the vector store. Args: @@ -25,7 +25,7 @@ def store_documents(self, documents: list[Document]) -> None: """ @abstractmethod - def retrieve_documents(self, query: str) -> list[Document]: + async def retrieve_documents(self, query: str) -> list[Document]: """Retrieves documents from the vector store based on the given query. Args: diff --git a/services/context-retriever/src/context_retriever/vector_store/qdrant.py b/services/context-retriever/src/context_retriever/vector_store/qdrant.py index da27c03..d3daa77 100644 --- a/services/context-retriever/src/context_retriever/vector_store/qdrant.py +++ b/services/context-retriever/src/context_retriever/vector_store/qdrant.py @@ -43,7 +43,7 @@ def __init__(self, cfg: QdrantProxyCfg) -> None: self._ensure_collection_exists() - def store_documents(self, documents: list[Document]) -> None: + async def store_documents(self, documents: list[Document]) -> None: """Stores the given documents in the vector store. Args: @@ -55,7 +55,7 @@ def store_documents(self, documents: list[Document]) -> None: for batch_docs in vs_core.batch_iterate(documents, self._cfg.uploading_batch_size): - embedded_docs = self._embedding_model.embed_documents( + embedded_docs = await self._embedding_model.aembed_documents( [doc.page_content for doc in batch_docs]) self._client.upload_collection( @@ -64,7 +64,7 @@ def store_documents(self, documents: list[Document]) -> None: payload=[{'text': doc.page_content} for doc in batch_docs], ) - def retrieve_documents(self, query: str) -> list[Document]: + async def retrieve_documents(self, query: str) -> list[Document]: """Retrieves documents from the vector store based on the given query. Args: From e068b2babe732779d7aec55029238a561da6b293 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 16:30:05 +0100 Subject: [PATCH 054/108] fix --- .github/workflows/service-checks.yml | 65 +++++++++++++++------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 25b6fe7..de1e661 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -8,7 +8,7 @@ on: - "pyproject.toml" - ".github/workflows/service-checks.yml" push: - branches: [main, develop] + branches: [main, develop, gh-actions] paths: - "services/**" - ".pre-commit-config.yaml" @@ -22,6 +22,7 @@ jobs: changes: runs-on: ubuntu-latest outputs: + context_retriever: ${{ steps.filter.outputs.context_retriever }} llm_proxy: ${{ steps.filter.outputs.llm_proxy }} web_app: ${{ steps.filter.outputs.web_app }} steps: @@ -30,49 +31,51 @@ jobs: id: filter with: filters: | + context_retriever: + - "services/context-retriever/**" + - ".pre-commit-config.yaml" + - "pyproject.toml" llm_proxy: - - 'services/llm-proxy/**' - - '.pre-commit-config.yaml' - - 'pyproject.toml' + - "services/llm-proxy/**" + - ".pre-commit-config.yaml" + - "pyproject.toml" web_app: - - 'services/web-app/**' - - '.pre-commit-config.yaml' - - 'pyproject.toml' + - "services/web-app/**" + - ".pre-commit-config.yaml" + - "pyproject.toml" - precommit-llm-proxy: + precommit-context-retriever: + needs: changes + if: needs.changes.outputs.context_retriever == 'true' runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run just run-precommit (devcontainer) + uses: devcontainers/ci@v0.3 + with: + subFolder: services/context-retriever + runCmd: just run-precommit + + precommit-llm-proxy: needs: changes if: needs.changes.outputs.llm_proxy == 'true' + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v5 + - name: Run just run-precommit (devcontainer) + uses: devcontainers/ci@v0.3 with: - python-version: "3.12" - - name: Install dependencies - working-directory: services/llm-proxy - run: | - uv venv - uv pip install -e ".[dev]" - - name: Run pre-commit - working-directory: services/llm-proxy - run: | - uv run pre-commit run -c ../../.pre-commit-config.yaml --files $(git -C ../.. ls-files services/llm-proxy) + subFolder: services/llm-proxy + runCmd: just run-precommit precommit-web-app: - runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.web_app == 'true' + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v5 + - name: Run just run-precommit (devcontainer) + uses: devcontainers/ci@v0.3 with: - python-version: "3.12" - - name: Install dependencies - working-directory: services/web-app - run: | - uv venv - uv pip install -e ".[dev]" - - name: Run pre-commit - working-directory: services/web-app - run: | - uv run pre-commit run -c ../../.pre-commit-config.yaml --files $(git -C ../.. ls-files services/web-app) + subFolder: services/web-app + runCmd: just run-precommit From b67c2f40ceeeb4c84f729d9dfc0a3ad7b248c196 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 16:38:15 +0100 Subject: [PATCH 055/108] directory fix --- .github/workflows/service-checks.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index de1e661..9bbb8a6 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -69,13 +69,16 @@ jobs: runCmd: just run-precommit precommit-web-app: - needs: changes - if: needs.changes.outputs.web_app == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Run just run-precommit (devcontainer) - uses: devcontainers/ci@v0.3 - with: - subFolder: services/web-app - runCmd: just run-precommit + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.web_app == 'true' + steps: + - uses: actions/checkout@v4 + + - name: Run just run-precommit (devcontainer) + uses: devcontainers/ci@v0.3 + with: + subFolder: services/web-app + configFile: .devcontainer/web-app/devcontainer.json + runCmd: just run-precommit + From 6c35f5dd52af7f36134d11dc232fdcdc0dc3bf14 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 16:40:36 +0100 Subject: [PATCH 056/108] fix --- .github/workflows/service-checks.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 9bbb8a6..0d84697 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -69,16 +69,16 @@ jobs: runCmd: just run-precommit precommit-web-app: - runs-on: ubuntu-latest - needs: changes - if: needs.changes.outputs.web_app == 'true' - steps: - - uses: actions/checkout@v4 + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.web_app == 'true' + steps: + - uses: actions/checkout@v4 - - name: Run just run-precommit (devcontainer) - uses: devcontainers/ci@v0.3 - with: - subFolder: services/web-app - configFile: .devcontainer/web-app/devcontainer.json - runCmd: just run-precommit + - name: Run just run-precommit (devcontainer) + uses: devcontainers/ci@v0.3 + with: + subFolder: services/web-app + configFile: .devcontainer/web-app/devcontainer.json + runCmd: just run-precommit From aea2c870ff46e055eed0cba49b63c1105c892efe Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 16:46:16 +0100 Subject: [PATCH 057/108] mount fix --- .github/workflows/service-checks.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 0d84697..1e89a3c 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -45,11 +45,12 @@ jobs: - "pyproject.toml" precommit-context-retriever: + runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.context_retriever == 'true' - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 with: @@ -57,11 +58,12 @@ jobs: runCmd: just run-precommit precommit-llm-proxy: + runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.llm_proxy == 'true' - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 with: @@ -75,10 +77,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts + run: | + mkdir -p /tmp + touch /tmp/ssh-agent.sock + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 + env: + SSH_AUTH_SOCK: /tmp/ssh-agent.sock with: subFolder: services/web-app configFile: .devcontainer/web-app/devcontainer.json runCmd: just run-precommit - From 79d0fe044c9a7e51e07cda265102134e8fbf82af Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 15:50:29 +0000 Subject: [PATCH 058/108] Implement working document retrieval logic --- services/context-retriever/cfg/main.yaml | 8 + services/context-retriever/main.py | 15 +- .../doc_retrieval_service.py | 145 ++++++++++++++++++ .../context_retriever/vector_store/core.py | 7 +- .../context_retriever/vector_store/qdrant.py | 37 +++-- 5 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 services/context-retriever/src/context_retriever/doc_retrieval_service.py diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml index 8f679e4..ca42d50 100644 --- a/services/context-retriever/cfg/main.yaml +++ b/services/context-retriever/cfg/main.yaml @@ -6,6 +6,14 @@ persist_data_path: data/ doc_processing: chunk_size: 2000 chunk_overlap: 400 +doc_retrieval: + max_context_docs: 3 + similarity_threshold: 0.6 + helper_llm: + model_name: local_ollama_model + url: http://localhost:11434 + temperature: 0.2 + defaults: - vector_store: qdrant \ No newline at end of file diff --git a/services/context-retriever/main.py b/services/context-retriever/main.py index 00e408d..0469f59 100644 --- a/services/context-retriever/main.py +++ b/services/context-retriever/main.py @@ -64,7 +64,10 @@ async def lifespan(_): # type: ignore vector_store_proxy=vector_store_proxy, doc_processing_cfg=doc_preparation_service.DocProcessingCfg(**cfg.doc_processing) ) - doc_retrieval = doc_retrieval_service.DocRetrievalService() + doc_retrieval = doc_retrieval_service.DocRetrievalService( + cfg=doc_retrieval_service.DocRetrievalCfg(**cfg.doc_retrieval), + vector_store_proxy=vector_store_proxy + ) yield @@ -92,7 +95,15 @@ class ResponseCollectContextInfo(pydantic.BaseModel): @app.post('/collect_context_info') async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: """Collects context documents from the vector store based on user message and chat history.""" - return ResponseCollectContextInfo(context_docs=[]) + + assert doc_retrieval is not None + + context_docs = await doc_retrieval.retrieve_context_docs( + user_message=request.user_message, + chat_history=request.chat_history + ) + + return ResponseCollectContextInfo(context_docs=context_docs) class ResponseUploadDocument(pydantic.BaseModel): diff --git a/services/context-retriever/src/context_retriever/doc_retrieval_service.py b/services/context-retriever/src/context_retriever/doc_retrieval_service.py new file mode 100644 index 0000000..eff98a6 --- /dev/null +++ b/services/context-retriever/src/context_retriever/doc_retrieval_service.py @@ -0,0 +1,145 @@ +"""Contains service handling conversation context document retrieval.""" + +import logging +from typing import Any + +import pydantic +from langchain_ollama.chat_models import ChatOllama +from langchain.messages import SystemMessage, HumanMessage + +from context_retriever.vector_store import core as vs_core + + +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + +class HelperLLMConfig(pydantic.BaseModel): + """Configuration for LLM model endpoint.""" + model_name: str + url: str + temperature: float + + +class DocRetrievalCfg(pydantic.BaseModel): + """Configuration for document retrieval.""" + max_context_docs: int + similarity_threshold: float + helper_llm: HelperLLMConfig + + +class DocRetrievalService: + """Retrieves context documents from the vector store. + + The service constructs queries based on user messages and chat history to fetch + relevant documents. + """ + + _CONSTRUCT_QUERY_SYSTEM_PROMPT = """ + You are an expert at reformulating user messages based on conversation history. + """ + + _CONSTRUCT_QUERY_PROMPT_TEMPLATE = """ + Given the following chat history and the latest user message, reformulate the user's message + to better reflect the context of the conversation. + + ### Guidelines + 1. The reformulated message should capture the context of the user's latest + message, taking into account the previous messages in the chat history. + 2. Your response should contain ONLY the reformulated message. + 3. The reformulated message MUST have the same meaning and grammatical structure as the + original user message. E.g. if the user message is a question, the reformulated message + should also be a question, as if the user had asked it. + + ### Chat History: + {chat_history} + + ### Latest User Message: + {user_message} + """ + + def __init__(self, + cfg: DocRetrievalCfg, + vector_store_proxy: vs_core.VectorStoreProxy) -> None: + + _logger().info('Initializing DocRetrievalService with config: %s', cfg) + + self._cfg = cfg + self._vector_store_proxy = vector_store_proxy + self._helper_llm = ChatOllama( + model=self._cfg.helper_llm.model_name, + base_url=self._cfg.helper_llm.url, + temperature=self._cfg.helper_llm.temperature + ) + + async def retrieve_context_docs(self, + user_message: str, + chat_history: list[dict[str, str]] + ) -> list[dict[str, Any]]: + """Retrieves context documents based on user message and chat history. + + Args: + user_message: The latest message from the user. + chat_history: List of previous messages in the conversation. + """ + + _logger().debug('Retrieving context documents for user message: %s and chat history: %s', + user_message, + chat_history) + + query = await self._construct_query(user_message, chat_history) + + _logger().debug('Constructed query for document retrieval: %s', query) + + retrieved_docs = await self._vector_store_proxy.retrieve_documents( + query, + self._cfg.max_context_docs, + self._cfg.similarity_threshold) + + return [ + {'content': doc.page_content, 'metadata': doc.metadata} + for doc in retrieved_docs + ] + + async def _construct_query(self, + user_message: str, + chat_history: list[dict[str, str]] + ) -> str: + """Constructs a query string using the helper LLM based on user message and chat history. + + Args: + user_message: The latest message from the user. + chat_history: List of previous messages in the conversation. + """ + + formatted_chat_history = self._format_chat_history(chat_history) + + messages = [ + SystemMessage(self._CONSTRUCT_QUERY_SYSTEM_PROMPT), + HumanMessage( + self._CONSTRUCT_QUERY_PROMPT_TEMPLATE.format( + chat_history=formatted_chat_history, + user_message=user_message + ) + ) + ] + + response = await self._helper_llm.agenerate([messages]) + + return response.generations[0][0].text.strip() + + def _format_chat_history(self, + chat_history: list[dict[str, str]] + ) -> str: + """Formats the chat history into a string for prompt input. + + Args: + chat_history: List of previous messages in the conversation. + """ + + history_lines = [ + f"{entry['role'].capitalize()}: {entry['content']}" + for entry in chat_history + ] + + return "\n".join(history_lines) diff --git a/services/context-retriever/src/context_retriever/vector_store/core.py b/services/context-retriever/src/context_retriever/vector_store/core.py index 229d17b..f467a7b 100644 --- a/services/context-retriever/src/context_retriever/vector_store/core.py +++ b/services/context-retriever/src/context_retriever/vector_store/core.py @@ -25,11 +25,16 @@ async def store_documents(self, documents: list[Document]) -> None: """ @abstractmethod - async def retrieve_documents(self, query: str) -> list[Document]: + async def retrieve_documents(self, + query: str, + k: int, + sim_thresh: float) -> list[Document]: """Retrieves documents from the vector store based on the given query. Args: query: The query string to search for relevant documents. + k: The number of top documents to retrieve. + sim_thresh: Similarity threshold for document retrieval. Returns: List of documents matching the query. diff --git a/services/context-retriever/src/context_retriever/vector_store/qdrant.py b/services/context-retriever/src/context_retriever/vector_store/qdrant.py index d3daa77..08d17dd 100644 --- a/services/context-retriever/src/context_retriever/vector_store/qdrant.py +++ b/services/context-retriever/src/context_retriever/vector_store/qdrant.py @@ -44,11 +44,7 @@ def __init__(self, cfg: QdrantProxyCfg) -> None: self._ensure_collection_exists() async def store_documents(self, documents: list[Document]) -> None: - """Stores the given documents in the vector store. - - Args: - documents: List of documents to be stored. - """ + """Stores the given documents in the vector store.""" _logger().debug('Storing %d documents in collection \'%s\'', len(documents), self._cfg.collection_name) @@ -61,23 +57,32 @@ async def store_documents(self, documents: list[Document]) -> None: self._client.upload_collection( collection_name=self._cfg.collection_name, vectors=embedded_docs, - payload=[{'text': doc.page_content} for doc in batch_docs], + payload=[{'content': doc.page_content, + 'metadata': doc.metadata} for doc in batch_docs], ) - async def retrieve_documents(self, query: str) -> list[Document]: - """Retrieves documents from the vector store based on the given query. - - Args: - query: The query string to search for relevant documents. - - Returns: - List of documents matching the query. - """ + async def retrieve_documents(self, + query: str, + k: int, + sim_thresh: float) -> list[Document]: + """Retrieves documents from the vector store based on the given query.""" _logger().debug('Retrieving documents from collection \'%s\' for query: \'%s\'', self._cfg.collection_name, query) - return [] + docs = self._client.query_points( + collection_name=self._cfg.collection_name, + query=await self._embedding_model.aembed_query(query), + limit=k, + score_threshold=sim_thresh + ) + + return [ + Document(page_content=point.payload['content'], + metadata=point.payload['metadata']) + for point in docs.points + if point.payload is not None + ] def _ensure_collection_exists(self) -> None: """Ensures that the specified collection exists in the Qdrant vector store.""" From f9c722a19f0782358d2a9518499f13bf8e71491f Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 16:51:29 +0100 Subject: [PATCH 059/108] fix --- .github/workflows/service-checks.yml | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 1e89a3c..b166b02 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -50,11 +50,18 @@ jobs: if: needs.changes.outputs.context_retriever == 'true' steps: - uses: actions/checkout@v4 + - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts + run: | + mkdir -p /tmp + touch /tmp/ssh-agent.sock - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 + env: + SSH_AUTH_SOCK: /tmp/ssh-agent.sock with: subFolder: services/context-retriever + configFile: .devcontainer/context-retriever/devcontainer.json runCmd: just run-precommit precommit-llm-proxy: @@ -64,10 +71,18 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts + run: | + mkdir -p /tmp + touch /tmp/ssh-agent.sock + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 + env: + SSH_AUTH_SOCK: /tmp/ssh-agent.sock with: subFolder: services/llm-proxy + configFile: .devcontainer/llm-proxy/devcontainer.json runCmd: just run-precommit precommit-web-app: @@ -82,11 +97,23 @@ jobs: mkdir -p /tmp touch /tmp/ssh-agent.sock + - name: Generate CI devcontainer config (skip postCreateCommand) + run: | + python - <<'PY' + import json, pathlib + src = pathlib.Path(".devcontainer/web-app/devcontainer.json") + dst = pathlib.Path(".devcontainer/web-app/devcontainer.ci.json") + data = json.loads(src.read_text()) + data.pop("postCreateCommand", None) + dst.write_text(json.dumps(data, indent=2) + "\n") + print(f"Written {dst}") + PY + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 env: SSH_AUTH_SOCK: /tmp/ssh-agent.sock with: subFolder: services/web-app - configFile: .devcontainer/web-app/devcontainer.json + configFile: .devcontainer/web-app/devcontainer.ci.json runCmd: just run-precommit From 80bf41726097491c86bf0070bc914db4a1cf72e2 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 15:55:10 +0000 Subject: [PATCH 060/108] Apply pre-commit checks --- services/context-retriever/cfg/main.yaml | 4 ++-- .../context-retriever/cfg/vector_store/qdrant.yaml | 3 ++- services/context-retriever/main.py | 1 - .../context_retriever/doc_preparation_service.py | 12 +++++------- .../src/context_retriever/doc_retrieval_service.py | 9 ++++----- .../src/context_retriever/vector_store/core.py | 7 ++++--- .../src/context_retriever/vector_store/qdrant.py | 13 ++++++------- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml index ca42d50..f973fd6 100644 --- a/services/context-retriever/cfg/main.yaml +++ b/services/context-retriever/cfg/main.yaml @@ -13,7 +13,7 @@ doc_retrieval: model_name: local_ollama_model url: http://localhost:11434 temperature: 0.2 - + defaults: - - vector_store: qdrant \ No newline at end of file + - vector_store: qdrant diff --git a/services/context-retriever/cfg/vector_store/qdrant.yaml b/services/context-retriever/cfg/vector_store/qdrant.yaml index 3807b49..06dd66c 100644 --- a/services/context-retriever/cfg/vector_store/qdrant.yaml +++ b/services/context-retriever/cfg/vector_store/qdrant.yaml @@ -1,7 +1,8 @@ +--- driver: qdrant url: http://localhost:6333 collection_name: documents uploading_batch_size: 8 embedding_model: model_name: nomic-embed-text:v1.5 - url: http://localhost:11436 \ No newline at end of file + url: http://localhost:11436 diff --git a/services/context-retriever/main.py b/services/context-retriever/main.py index 0469f59..3f40493 100644 --- a/services/context-retriever/main.py +++ b/services/context-retriever/main.py @@ -12,7 +12,6 @@ import omegaconf import pydantic import uvicorn - from context_retriever import doc_preparation_service from context_retriever import doc_retrieval_service from context_retriever.vector_store import qdrant as qdrant_vs diff --git a/services/context-retriever/src/context_retriever/doc_preparation_service.py b/services/context-retriever/src/context_retriever/doc_preparation_service.py index 0278660..78ddfee 100644 --- a/services/context-retriever/src/context_retriever/doc_preparation_service.py +++ b/services/context-retriever/src/context_retriever/doc_preparation_service.py @@ -1,16 +1,14 @@ """Contains service that prepares documents for storage in the vector store.""" - -from typing import BinaryIO -import tempfile import logging +import tempfile +from typing import BinaryIO +import langchain_text_splitters import pydantic +from context_retriever.vector_store.core import VectorStoreProxy from langchain_community import document_loaders -import langchain_text_splitters from langchain_core.documents import Document -from context_retriever.vector_store.core import VectorStoreProxy - def _logger() -> logging.Logger: return logging.getLogger(__name__) @@ -38,7 +36,7 @@ def __init__(self, self._vector_store_proxy = vector_store_proxy self._text_splitter = langchain_text_splitters.RecursiveCharacterTextSplitter( - separators=["\n\n", "\n", " "], + separators=['\n\n', '\n', ' '], chunk_size=doc_processing_cfg.chunk_size, chunk_overlap=doc_processing_cfg.chunk_overlap, length_function=len, diff --git a/services/context-retriever/src/context_retriever/doc_retrieval_service.py b/services/context-retriever/src/context_retriever/doc_retrieval_service.py index eff98a6..05ebc3b 100644 --- a/services/context-retriever/src/context_retriever/doc_retrieval_service.py +++ b/services/context-retriever/src/context_retriever/doc_retrieval_service.py @@ -1,13 +1,12 @@ """Contains service handling conversation context document retrieval.""" - import logging from typing import Any import pydantic -from langchain_ollama.chat_models import ChatOllama -from langchain.messages import SystemMessage, HumanMessage - from context_retriever.vector_store import core as vs_core +from langchain.messages import HumanMessage +from langchain.messages import SystemMessage +from langchain_ollama.chat_models import ChatOllama def _logger() -> logging.Logger: @@ -142,4 +141,4 @@ def _format_chat_history(self, for entry in chat_history ] - return "\n".join(history_lines) + return '\n'.join(history_lines) diff --git a/services/context-retriever/src/context_retriever/vector_store/core.py b/services/context-retriever/src/context_retriever/vector_store/core.py index f467a7b..b37a672 100644 --- a/services/context-retriever/src/context_retriever/vector_store/core.py +++ b/services/context-retriever/src/context_retriever/vector_store/core.py @@ -1,7 +1,8 @@ """Contains core interfaces and utilities for vector store operations.""" - -from abc import ABC, abstractmethod -from typing import Iterator, TypeVar +from abc import ABC +from abc import abstractmethod +from typing import Iterator +from typing import TypeVar import pydantic from langchain_core.documents import Document diff --git a/services/context-retriever/src/context_retriever/vector_store/qdrant.py b/services/context-retriever/src/context_retriever/vector_store/qdrant.py index 08d17dd..81b1cb4 100644 --- a/services/context-retriever/src/context_retriever/vector_store/qdrant.py +++ b/services/context-retriever/src/context_retriever/vector_store/qdrant.py @@ -1,14 +1,13 @@ """Contains class for handling communication with Qdrant vector store.""" - import logging -import qdrant_client -from qdrant_client.models import VectorParams, Distance -from langchain_ollama.embeddings import OllamaEmbeddings -from langchain_core.documents import Document import pydantic - +import qdrant_client from context_retriever.vector_store import core as vs_core +from langchain_core.documents import Document +from langchain_ollama.embeddings import OllamaEmbeddings +from qdrant_client.models import Distance +from qdrant_client.models import VectorParams def _logger() -> logging.Logger: @@ -102,6 +101,6 @@ def _ensure_collection_exists(self) -> None: def _determine_vector_size(self) -> int: """Determines the size of the embedding vectors produced by the embedding model.""" - sample_text = "Sample text for embedding size determination." + sample_text = 'Sample text for embedding size determination.' embedding = self._embedding_model.embed_query(sample_text) return len(embedding) From 0969cd7a0db1f63eb058ad2a0f97d0e43a775b57 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:02:52 +0100 Subject: [PATCH 061/108] fix --- .github/workflows/service-checks.yml | 49 +++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index b166b02..39c5371 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -4,6 +4,9 @@ on: pull_request: paths: - "services/**" + - ".devcontainer/context-retriever/**" + - ".devcontainer/llm-proxy/**" + - ".devcontainer/web-app/**" - ".pre-commit-config.yaml" - "pyproject.toml" - ".github/workflows/service-checks.yml" @@ -11,6 +14,9 @@ on: branches: [main, develop, gh-actions] paths: - "services/**" + - ".devcontainer/context-retriever/**" + - ".devcontainer/llm-proxy/**" + - ".devcontainer/web-app/**" - ".pre-commit-config.yaml" - "pyproject.toml" - ".github/workflows/service-checks.yml" @@ -33,14 +39,17 @@ jobs: filters: | context_retriever: - "services/context-retriever/**" + - ".devcontainer/context-retriever/**" - ".pre-commit-config.yaml" - "pyproject.toml" llm_proxy: - "services/llm-proxy/**" + - ".devcontainer/llm-proxy/**" - ".pre-commit-config.yaml" - "pyproject.toml" web_app: - "services/web-app/**" + - ".devcontainer/web-app/**" - ".pre-commit-config.yaml" - "pyproject.toml" @@ -55,6 +64,18 @@ jobs: mkdir -p /tmp touch /tmp/ssh-agent.sock + - name: Disable post-create/start commands for CI + run: | + python - <<'PY' + import json + import pathlib + path = pathlib.Path(".devcontainer/context-retriever/devcontainer.json") + data = json.loads(path.read_text()) + data.pop("postCreateCommand", None) + data.pop("postStartCommand", None) + path.write_text(json.dumps(data, indent=2) + "\n") + PY + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 env: @@ -76,6 +97,18 @@ jobs: mkdir -p /tmp touch /tmp/ssh-agent.sock + - name: Disable post-create/start commands for CI + run: | + python - <<'PY' + import json + import pathlib + path = pathlib.Path(".devcontainer/llm-proxy/devcontainer.json") + data = json.loads(path.read_text()) + data.pop("postCreateCommand", None) + data.pop("postStartCommand", None) + path.write_text(json.dumps(data, indent=2) + "\n") + PY + - name: Run just run-precommit (devcontainer) uses: devcontainers/ci@v0.3 env: @@ -97,16 +130,16 @@ jobs: mkdir -p /tmp touch /tmp/ssh-agent.sock - - name: Generate CI devcontainer config (skip postCreateCommand) + - name: Disable post-create/start commands for CI run: | python - <<'PY' - import json, pathlib - src = pathlib.Path(".devcontainer/web-app/devcontainer.json") - dst = pathlib.Path(".devcontainer/web-app/devcontainer.ci.json") - data = json.loads(src.read_text()) + import json + import pathlib + path = pathlib.Path(".devcontainer/web-app/devcontainer.json") + data = json.loads(path.read_text()) data.pop("postCreateCommand", None) - dst.write_text(json.dumps(data, indent=2) + "\n") - print(f"Written {dst}") + data.pop("postStartCommand", None) + path.write_text(json.dumps(data, indent=2) + "\n") PY - name: Run just run-precommit (devcontainer) @@ -115,5 +148,5 @@ jobs: SSH_AUTH_SOCK: /tmp/ssh-agent.sock with: subFolder: services/web-app - configFile: .devcontainer/web-app/devcontainer.ci.json + configFile: .devcontainer/web-app/devcontainer.json runCmd: just run-precommit From e1b48583955a3029c35568d18f22c8f49c93ecdb Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:15:06 +0100 Subject: [PATCH 062/108] fix --- .github/workflows/service-checks.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 39c5371..5f1fac8 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -83,7 +83,8 @@ jobs: with: subFolder: services/context-retriever configFile: .devcontainer/context-retriever/devcontainer.json - runCmd: just run-precommit + runCmd: >- + /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' precommit-llm-proxy: runs-on: ubuntu-latest @@ -116,7 +117,8 @@ jobs: with: subFolder: services/llm-proxy configFile: .devcontainer/llm-proxy/devcontainer.json - runCmd: just run-precommit + runCmd: >- + /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' precommit-web-app: runs-on: ubuntu-latest @@ -149,4 +151,5 @@ jobs: with: subFolder: services/web-app configFile: .devcontainer/web-app/devcontainer.json - runCmd: just run-precommit + runCmd: >- + /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' From 38b5e5482b27317d820acb086f72b21dc03f16ea Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:26:44 +0100 Subject: [PATCH 063/108] fix --- .github/workflows/service-checks.yml | 196 ++++++++++----------------- 1 file changed, 69 insertions(+), 127 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 5f1fac8..5a44744 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -1,155 +1,97 @@ -name: Service checks +name: Service Checks on: pull_request: paths: - - "services/**" - - ".devcontainer/context-retriever/**" - - ".devcontainer/llm-proxy/**" - - ".devcontainer/web-app/**" - - ".pre-commit-config.yaml" - - "pyproject.toml" - - ".github/workflows/service-checks.yml" + - .github/workflows/service-checks.yml + - .pre-commit-config.yaml + - pyproject.toml + - services/context-retriever/** + - services/web-app/** + - services/llm-proxy/** push: - branches: [main, develop, gh-actions] paths: - - "services/**" - - ".devcontainer/context-retriever/**" - - ".devcontainer/llm-proxy/**" - - ".devcontainer/web-app/**" - - ".pre-commit-config.yaml" - - "pyproject.toml" - - ".github/workflows/service-checks.yml" + - .github/workflows/service-checks.yml + - .pre-commit-config.yaml + - pyproject.toml + - services/context-retriever/** + - services/web-app/** + - services/llm-proxy/** permissions: contents: read +env: + PRECOMMIT_CMD: just run-precommit + +x-precommit-steps: &precommit_steps + - name: Checkout repository + uses: actions/checkout@v4 + - name: Verify Docker engine + run: docker version + - name: Run pre-commit in devcontainer + uses: devcontainers/ci@v0.3 + with: + configFile: ${{ env.DEVCONTAINER_CONFIG }} + runCmd: ${{ env.PRECOMMIT_CMD }} + jobs: changes: + name: Detect changed services runs-on: ubuntu-latest outputs: - context_retriever: ${{ steps.filter.outputs.context_retriever }} - llm_proxy: ${{ steps.filter.outputs.llm_proxy }} - web_app: ${{ steps.filter.outputs.web_app }} + context-retriever: ${{ steps.filter.outputs.context-retriever }} + web-app: ${{ steps.filter.outputs.web-app }} + llm-proxy: ${{ steps.filter.outputs.llm-proxy }} steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Determine impacted services id: filter + uses: dorny/paths-filter@v3 with: filters: | - context_retriever: - - "services/context-retriever/**" - - ".devcontainer/context-retriever/**" - - ".pre-commit-config.yaml" - - "pyproject.toml" - llm_proxy: - - "services/llm-proxy/**" - - ".devcontainer/llm-proxy/**" - - ".pre-commit-config.yaml" - - "pyproject.toml" - web_app: - - "services/web-app/**" - - ".devcontainer/web-app/**" - - ".pre-commit-config.yaml" - - "pyproject.toml" + context-retriever: + - services/context-retriever/** + - .pre-commit-config.yaml + - pyproject.toml + - .github/workflows/service-checks.yml + web-app: + - services/web-app/** + - .pre-commit-config.yaml + - pyproject.toml + - .github/workflows/service-checks.yml + llm-proxy: + - services/llm-proxy/** + - .pre-commit-config.yaml + - pyproject.toml + - .github/workflows/service-checks.yml precommit-context-retriever: + name: Pre-commit (context-retriever) runs-on: ubuntu-latest needs: changes - if: needs.changes.outputs.context_retriever == 'true' - steps: - - uses: actions/checkout@v4 - - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts - run: | - mkdir -p /tmp - touch /tmp/ssh-agent.sock - - - name: Disable post-create/start commands for CI - run: | - python - <<'PY' - import json - import pathlib - path = pathlib.Path(".devcontainer/context-retriever/devcontainer.json") - data = json.loads(path.read_text()) - data.pop("postCreateCommand", None) - data.pop("postStartCommand", None) - path.write_text(json.dumps(data, indent=2) + "\n") - PY + if: needs.changes.outputs.context-retriever == 'true' + env: + DEVCONTAINER_CONFIG: services/context-retriever/.devcontainer/devcontainer.json + steps: *precommit_steps - - name: Run just run-precommit (devcontainer) - uses: devcontainers/ci@v0.3 - env: - SSH_AUTH_SOCK: /tmp/ssh-agent.sock - with: - subFolder: services/context-retriever - configFile: .devcontainer/context-retriever/devcontainer.json - runCmd: >- - /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' - - precommit-llm-proxy: + precommit-web-app: + name: Pre-commit (web-app) runs-on: ubuntu-latest needs: changes - if: needs.changes.outputs.llm_proxy == 'true' - steps: - - uses: actions/checkout@v4 - - - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts - run: | - mkdir -p /tmp - touch /tmp/ssh-agent.sock + if: needs.changes.outputs.web-app == 'true' + env: + DEVCONTAINER_CONFIG: .devcontainer/web-app/devcontainer.json + steps: *precommit_steps - - name: Disable post-create/start commands for CI - run: | - python - <<'PY' - import json - import pathlib - path = pathlib.Path(".devcontainer/llm-proxy/devcontainer.json") - data = json.loads(path.read_text()) - data.pop("postCreateCommand", None) - data.pop("postStartCommand", None) - path.write_text(json.dumps(data, indent=2) + "\n") - PY - - - name: Run just run-precommit (devcontainer) - uses: devcontainers/ci@v0.3 - env: - SSH_AUTH_SOCK: /tmp/ssh-agent.sock - with: - subFolder: services/llm-proxy - configFile: .devcontainer/llm-proxy/devcontainer.json - runCmd: >- - /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' - - precommit-web-app: + precommit-llm-proxy: + name: Pre-commit (llm-proxy) runs-on: ubuntu-latest needs: changes - if: needs.changes.outputs.web_app == 'true' - steps: - - uses: actions/checkout@v4 - - - name: Provide dummy SSH_AUTH_SOCK for devcontainer mounts - run: | - mkdir -p /tmp - touch /tmp/ssh-agent.sock - - - name: Disable post-create/start commands for CI - run: | - python - <<'PY' - import json - import pathlib - path = pathlib.Path(".devcontainer/web-app/devcontainer.json") - data = json.loads(path.read_text()) - data.pop("postCreateCommand", None) - data.pop("postStartCommand", None) - path.write_text(json.dumps(data, indent=2) + "\n") - PY - - - name: Run just run-precommit (devcontainer) - uses: devcontainers/ci@v0.3 - env: - SSH_AUTH_SOCK: /tmp/ssh-agent.sock - with: - subFolder: services/web-app - configFile: .devcontainer/web-app/devcontainer.json - runCmd: >- - /bin/bash -lc 'export PATH=/home/appuser/.local/bin:/home/appuser/.cargo/bin:$PATH; just run-precommit' + if: needs.changes.outputs.llm-proxy == 'true' + env: + DEVCONTAINER_CONFIG: .devcontainer/llm-proxy/devcontainer.json + steps: *precommit_steps From 644b1061bec73bb32eeefb41659ceca5eb25bd0a Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:29:12 +0100 Subject: [PATCH 064/108] fix --- .github/workflows/service-checks.yml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 5a44744..7b0dc8c 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -24,17 +24,6 @@ permissions: env: PRECOMMIT_CMD: just run-precommit -x-precommit-steps: &precommit_steps - - name: Checkout repository - uses: actions/checkout@v4 - - name: Verify Docker engine - run: docker version - - name: Run pre-commit in devcontainer - uses: devcontainers/ci@v0.3 - with: - configFile: ${{ env.DEVCONTAINER_CONFIG }} - runCmd: ${{ env.PRECOMMIT_CMD }} - jobs: changes: name: Detect changed services @@ -76,7 +65,16 @@ jobs: if: needs.changes.outputs.context-retriever == 'true' env: DEVCONTAINER_CONFIG: services/context-retriever/.devcontainer/devcontainer.json - steps: *precommit_steps + steps: &precommit_steps + - name: Checkout repository + uses: actions/checkout@v4 + - name: Verify Docker engine + run: docker version + - name: Run pre-commit in devcontainer + uses: devcontainers/ci@v0.3 + with: + configFile: ${{ env.DEVCONTAINER_CONFIG }} + runCmd: ${{ env.PRECOMMIT_CMD }} precommit-web-app: name: Pre-commit (web-app) From 6dfc88087263742f2e44a45591f50322c1da7c68 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:32:21 +0100 Subject: [PATCH 065/108] fix --- .github/workflows/service-checks.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 7b0dc8c..1ac8a5d 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -23,6 +23,7 @@ permissions: env: PRECOMMIT_CMD: just run-precommit + SSH_AUTH_SOCK: /tmp/ssh-agent jobs: changes: @@ -70,6 +71,11 @@ jobs: uses: actions/checkout@v4 - name: Verify Docker engine run: docker version + - name: Ensure SSH agent mount path exists + run: | + if [ ! -e "${SSH_AUTH_SOCK}" ]; then + touch "${SSH_AUTH_SOCK}" + fi - name: Run pre-commit in devcontainer uses: devcontainers/ci@v0.3 with: From 6e8fbb6dc19273055fe085534647387002a4045f Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:37:29 +0100 Subject: [PATCH 066/108] fix --- .github/workflows/service-checks.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 1ac8a5d..edf88ea 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -66,6 +66,7 @@ jobs: if: needs.changes.outputs.context-retriever == 'true' env: DEVCONTAINER_CONFIG: services/context-retriever/.devcontainer/devcontainer.json + SERVICE_WORKDIR: /home/appuser/workspace/services/context-retriever steps: &precommit_steps - name: Checkout repository uses: actions/checkout@v4 @@ -80,7 +81,7 @@ jobs: uses: devcontainers/ci@v0.3 with: configFile: ${{ env.DEVCONTAINER_CONFIG }} - runCmd: ${{ env.PRECOMMIT_CMD }} + runCmd: bash -lc "cd ${{ env.SERVICE_WORKDIR }} && ${{ env.PRECOMMIT_CMD }}" precommit-web-app: name: Pre-commit (web-app) @@ -89,6 +90,7 @@ jobs: if: needs.changes.outputs.web-app == 'true' env: DEVCONTAINER_CONFIG: .devcontainer/web-app/devcontainer.json + SERVICE_WORKDIR: /home/appuser/workspace/services/web-app steps: *precommit_steps precommit-llm-proxy: @@ -98,4 +100,5 @@ jobs: if: needs.changes.outputs.llm-proxy == 'true' env: DEVCONTAINER_CONFIG: .devcontainer/llm-proxy/devcontainer.json + SERVICE_WORKDIR: /home/appuser/workspace/services/llm-proxy steps: *precommit_steps From 21a5e9412f8d50c504034f8e3d56e13eaefbe8f4 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:43:54 +0100 Subject: [PATCH 067/108] fix --- services/llm-proxy/justfile | 2 +- services/web-app/justfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/llm-proxy/justfile b/services/llm-proxy/justfile index f8eae92..b5470b9 100644 --- a/services/llm-proxy/justfile +++ b/services/llm-proxy/justfile @@ -16,5 +16,5 @@ run-server *args: # Runs static checks using global pre-commit configuration. run-precommit: - uv run pre-commit run -c ../../.pre-commit-config.yaml \ + uv run --extra dev pre-commit run -c ../../.pre-commit-config.yaml \ --files `git ls-files --cached --others --exclude-standard` diff --git a/services/web-app/justfile b/services/web-app/justfile index fdf4671..6593f1d 100644 --- a/services/web-app/justfile +++ b/services/web-app/justfile @@ -25,5 +25,5 @@ run-mock-backend: # Runs static checks using global pre-commit configuration. run-precommit: - uv run pre-commit run -c ../../.pre-commit-config.yaml \ + uv run --extra dev pre-commit run -c ../../.pre-commit-config.yaml \ --files `git ls-files --cached --others --exclude-standard` From 9ba6a7e75aa8bdc5a4c2e5bbdde7244dd960b9b0 Mon Sep 17 00:00:00 2001 From: Janek Stryszewski Date: Wed, 7 Jan 2026 17:59:05 +0100 Subject: [PATCH 068/108] nio --- .github/workflows/service-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index edf88ea..96d7c61 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -65,7 +65,7 @@ jobs: needs: changes if: needs.changes.outputs.context-retriever == 'true' env: - DEVCONTAINER_CONFIG: services/context-retriever/.devcontainer/devcontainer.json + DEVCONTAINER_CONFIG: .devcontainer/context-retriever/devcontainer.json SERVICE_WORKDIR: /home/appuser/workspace/services/context-retriever steps: &precommit_steps - name: Checkout repository From 23b11d0797cf36932abd56f8d7ba031cb205cdcc Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 17:13:12 +0000 Subject: [PATCH 069/108] Enable running web-app as docker compose service --- docker-compose.yml | 15 +++++++++++++++ persist_dir/web-app/.gitignore | 2 ++ services/web-app/cfg/main.yaml | 2 +- services/web-app/web-app.Dockerfile | 17 +++++++++++++++++ services/web-app/web.Dockerfile | 12 ------------ 5 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 persist_dir/web-app/.gitignore create mode 100644 services/web-app/web-app.Dockerfile delete mode 100644 services/web-app/web.Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 158b02c..2d366ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -76,6 +76,21 @@ services: - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11436 + web-app: + build: + context: services/web-app/ + dockerfile: web-app.Dockerfile + args: + WEB_APP_PORT: 8080 + + container_name: web-app + ports: + - 8080:8080 + volumes: + - ./persist_dir/web-app:/app/data + networks: + - rag-net + networks: rag-net: driver: bridge diff --git a/persist_dir/web-app/.gitignore b/persist_dir/web-app/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/web-app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml index 5f614d2..4db180c 100644 --- a/services/web-app/cfg/main.yaml +++ b/services/web-app/cfg/main.yaml @@ -3,4 +3,4 @@ context_retriever_url: http://context_retriever:8080 llm_proxy_url: http://llm_proxy:8080 persist_data_path: data/ web_app_port: 8080 -web_app_host: localhost +web_app_host: 0.0.0.0 diff --git a/services/web-app/web-app.Dockerfile b/services/web-app/web-app.Dockerfile new file mode 100644 index 0000000..4dcf105 --- /dev/null +++ b/services/web-app/web-app.Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends wget + +RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh + +COPY . /app +WORKDIR /app + +EXPOSE ${WEB_APP_PORT} + +RUN uv python install 3.12 && uv venv && uv pip install . +CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file diff --git a/services/web-app/web.Dockerfile b/services/web-app/web.Dockerfile deleted file mode 100644 index 9e36ed5..0000000 --- a/services/web-app/web.Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM python:3.12-slim - -SHELL ["/bin/bash", "-c"] -WORKDIR /home/appuser/app - -RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash - -RUN chown -R appuser:appuser /home/appuser/ - -USER appuser - -CMD ["/bin/bash", "./entrypoint.dev.bash"] From 52766fc30934c5da7e9ce101f17a7f7e8fdde088 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:03:21 +0000 Subject: [PATCH 070/108] Add health checks for ollama endpoints --- docker-compose.yml | 26 +++++++++++++++++++ .../embedding-endpoint.Dockerfile | 2 ++ services/llm-endpoint/llm-endpoint.Dockerfile | 2 ++ services/vector-store/vector-store.Dockerfile | 2 ++ 4 files changed, 32 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 2d366ef..0b7715c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,12 @@ services: - LLM_GENERATOR_MODEL=llama3.1:8b - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11434 + healthcheck: + test: curl -s http://localhost:11434/api/tags | grep '"model":"local_ollama_model:latest"' + interval: 5m + timeout: 30s + retries: 10 + start_period: 30s guard-llm: build: @@ -39,6 +45,14 @@ services: - LLM_GENERATOR_MODEL=dolphin3:8b - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11435 + healthcheck: + test: curl -s http://localhost:11435/api/tags | grep '"model":"local_ollama_model:latest"' + interval: 5m + timeout: 30s + retries: 10 + start_period: 30s + + vector-store: build: @@ -56,6 +70,12 @@ services: - ./persist_dir/vector-store:/qdrant/storage:z networks: - rag-net + healthcheck: + test: curl --fail http://localhost:6333/livez || exit 1 + interval: 1m30s + timeout: 30s + retries: 5 + start_period: 30s embedding-endpoint: build: @@ -75,6 +95,12 @@ services: - EMBEDDING_MODEL=nomic-embed-text:v1.5 - OLLAMA_DEBUG=0 - OLLAMA_HOST=0.0.0.0:11436 + healthcheck: + test: curl -s http://localhost:11436/api/tags | grep '"model":"nomic-embed-text:v1.5"' + interval: 5m + timeout: 30s + retries: 10 + start_period: 30s web-app: build: diff --git a/services/embedding-endpoint/embedding-endpoint.Dockerfile b/services/embedding-endpoint/embedding-endpoint.Dockerfile index 873cc31..ce2024c 100644 --- a/services/embedding-endpoint/embedding-endpoint.Dockerfile +++ b/services/embedding-endpoint/embedding-endpoint.Dockerfile @@ -1,5 +1,7 @@ FROM ollama/ollama:latest +RUN apt-get update && apt-get install -y curl + COPY ./entrypoint.sh /root/entrypoint.sh RUN chmod +x /root/entrypoint.sh diff --git a/services/llm-endpoint/llm-endpoint.Dockerfile b/services/llm-endpoint/llm-endpoint.Dockerfile index 7cc0cc3..2c56dbb 100644 --- a/services/llm-endpoint/llm-endpoint.Dockerfile +++ b/services/llm-endpoint/llm-endpoint.Dockerfile @@ -1,5 +1,7 @@ FROM ollama/ollama:latest +RUN apt-get update && apt-get install -y curl + COPY ./entrypoint.sh /root/entrypoint.sh RUN chmod +x /root/entrypoint.sh diff --git a/services/vector-store/vector-store.Dockerfile b/services/vector-store/vector-store.Dockerfile index c1d181d..45f6551 100644 --- a/services/vector-store/vector-store.Dockerfile +++ b/services/vector-store/vector-store.Dockerfile @@ -1,4 +1,6 @@ FROM qdrant/qdrant +RUN apt update && apt install -y curl + EXPOSE ${EXPOSED_PORT_REST} EXPOSE ${EXPOSED_PORT_GRPC} From 5fd9f46fb3569f3dadc23f07adc724c3677920e4 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:06:39 +0000 Subject: [PATCH 071/108] Add docker compose services for llm-proxy and context-retriever --- docker-compose.yml | 42 +++++++++++++++++++ persist_dir/context-retriever/.gitignore | 2 + persist_dir/llm-proxy/.gitignore | 2 + .../context-retriever.Dockerfile | 17 ++++++++ services/llm-proxy/llm-proxy.Dockerfile | 17 ++++++++ 5 files changed, 80 insertions(+) create mode 100644 persist_dir/context-retriever/.gitignore create mode 100644 persist_dir/llm-proxy/.gitignore create mode 100644 services/context-retriever/context-retriever.Dockerfile create mode 100644 services/llm-proxy/llm-proxy.Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 0b7715c..52546d1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -117,6 +117,48 @@ services: networks: - rag-net + context-retriever: + build: + context: services/context-retriever/ + dockerfile: context-retriever.Dockerfile + args: + API_PORT: 8899 + + container_name: context-retriever + ports: + - 8899:8899 + volumes: + - ./persist_dir/context-retriever:/app/data + networks: + - rag-net + depends_on: + vector-store: + condition: service_healthy + embedding-endpoint: + condition: service_healthy + main-llm-responder: + condition: service_healthy + + llm-proxy: + build: + context: services/llm-proxy/ + dockerfile: llm-proxy.Dockerfile + args: + API_PORT: 8888 + + container_name: llm-proxy + ports: + - 8888:8888 + volumes: + - ./persist_dir/llm-proxy:/app/data + networks: + - rag-net + depends_on: + main-llm-responder: + condition: service_healthy + guard-llm: + condition: service_healthy + networks: rag-net: driver: bridge diff --git a/persist_dir/context-retriever/.gitignore b/persist_dir/context-retriever/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/context-retriever/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/persist_dir/llm-proxy/.gitignore b/persist_dir/llm-proxy/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/persist_dir/llm-proxy/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/services/context-retriever/context-retriever.Dockerfile b/services/context-retriever/context-retriever.Dockerfile new file mode 100644 index 0000000..199b0e5 --- /dev/null +++ b/services/context-retriever/context-retriever.Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends wget + +RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh + +COPY . /app +WORKDIR /app + +EXPOSE ${API_PORT} + +RUN uv python install 3.12 && uv venv && uv pip install . +CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file diff --git a/services/llm-proxy/llm-proxy.Dockerfile b/services/llm-proxy/llm-proxy.Dockerfile new file mode 100644 index 0000000..199b0e5 --- /dev/null +++ b/services/llm-proxy/llm-proxy.Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.12-slim + +SHELL ["/bin/bash", "-c"] +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y --no-install-recommends wget + +RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh + +COPY . /app +WORKDIR /app + +EXPOSE ${API_PORT} + +RUN uv python install 3.12 && uv venv && uv pip install . +CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file From c699f4e1fc0d7d6813ea282aa45621da2d272bdf Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:07:30 +0000 Subject: [PATCH 072/108] Fix urls to enable service communication --- services/context-retriever/cfg/main.yaml | 4 ++-- services/context-retriever/cfg/vector_store/qdrant.yaml | 4 ++-- services/llm-proxy/cfg/main.yaml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml index f973fd6..13f0cd5 100644 --- a/services/context-retriever/cfg/main.yaml +++ b/services/context-retriever/cfg/main.yaml @@ -1,6 +1,6 @@ --- server_host: 0.0.0.0 -server_port: 8081 +server_port: 8899 n_server_workers: 1 persist_data_path: data/ doc_processing: @@ -11,7 +11,7 @@ doc_retrieval: similarity_threshold: 0.6 helper_llm: model_name: local_ollama_model - url: http://localhost:11434 + url: http://main-llm-responder:11434 temperature: 0.2 diff --git a/services/context-retriever/cfg/vector_store/qdrant.yaml b/services/context-retriever/cfg/vector_store/qdrant.yaml index 06dd66c..6f51bcb 100644 --- a/services/context-retriever/cfg/vector_store/qdrant.yaml +++ b/services/context-retriever/cfg/vector_store/qdrant.yaml @@ -1,8 +1,8 @@ --- driver: qdrant -url: http://localhost:6333 +url: http://vector-store:6333 collection_name: documents uploading_batch_size: 8 embedding_model: model_name: nomic-embed-text:v1.5 - url: http://localhost:11436 + url: http://embedding-endpoint:11436 diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index db57e1e..3ef3b97 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -1,13 +1,13 @@ --- server_host: 0.0.0.0 -server_port: 8080 +server_port: 8888 n_server_workers: 1 persist_data_path: data/ models: main_chat: model: local_ollama_model - base_url: http://localhost:11434 + base_url: http://main-llm-responder:11434 conversation_safety_guardrail: model: local_ollama_model - base_url: http://localhost:11435 + base_url: http://guard-llm:11435 From 60ed9201633081043dc8c2630b4eb9c2ef4b7dc1 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:09:26 +0000 Subject: [PATCH 073/108] Fix bugs in communication with endpoints Fixed bugs with too low timeout Fixed bugs with decoding context docs --- services/web-app/cfg/main.yaml | 9 +++++++-- services/web-app/main.py | 5 +++-- .../src/web_app/backend/context_retriever.py | 14 +++++++------- services/web-app/src/web_app/backend/llm_proxy.py | 14 ++++++++------ services/web-app/src/web_app/backend/utils.py | 15 +++++++++++---- .../web-app/src/web_app/gui/main_controller.py | 2 +- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml index 4db180c..eb68eea 100644 --- a/services/web-app/cfg/main.yaml +++ b/services/web-app/cfg/main.yaml @@ -1,6 +1,11 @@ --- -context_retriever_url: http://context_retriever:8080 -llm_proxy_url: http://llm_proxy:8080 +context_retriever_cfg: + url: http://context-retriever:8899 + connection_timeout: 45 + +llm_proxy_cfg: + url: http://llm-proxy:8888 + connection_timeout: 45 persist_data_path: data/ web_app_port: 8080 web_app_host: 0.0.0.0 diff --git a/services/web-app/main.py b/services/web-app/main.py index 1101c92..2a0060b 100644 --- a/services/web-app/main.py +++ b/services/web-app/main.py @@ -8,6 +8,7 @@ import omegaconf from web_app.backend import context_retriever from web_app.backend import llm_proxy +from web_app.backend import utils as backend_utils from web_app.gui import main_controller from web_app.gui import utils as gui_utils @@ -70,11 +71,11 @@ def main(cfg: omegaconf.DictConfig) -> None: _logger().info('Creating services for backend communication...') context_retriever_service = context_retriever.ContextRetrieverService( - cfg.context_retriever_url + endpoint_cfg=backend_utils.EndpointConnectionCfg(**cfg.context_retriever_cfg) ) llm_proxy_service = llm_proxy.LLMProxyService( - cfg.llm_proxy_url + endpoint_cfg=backend_utils.EndpointConnectionCfg(**cfg.llm_proxy_cfg) ) _logger().info('Rendering GUI...') diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index 4c6b9cb..888a457 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -13,12 +13,12 @@ def _logger() -> logging.Logger: class ContextRetrieverService: """Communicates with the context-retriever module and retrieves context for queries.""" - def __init__(self, context_retriever_url: str): + def __init__(self, endpoint_cfg: utils.EndpointConnectionCfg): - self._context_retriever_url = context_retriever_url + self._endpoint_cfg = endpoint_cfg - _logger().debug('Created service for context-retriever with url: %s', - context_retriever_url) + _logger().info('Created service for context-retriever with cfg: %s', + endpoint_cfg) def collect_context_info(self, user_message: str, @@ -36,16 +36,16 @@ def collect_context_info(self, _logger().debug('Collecting context info with user_message: %s and chat_history: %s', user_message, chat_history) - url = f"{self._context_retriever_url}/collect_context_info" + url = f"{self._endpoint_cfg.url}/collect_context_info" payload = { 'user_message': user_message, 'chat_history': utils.chat_history_to_payload(chat_history) } - response = requests.post(url, json=payload, timeout=5) + response = requests.post(url, json=payload, timeout=self._endpoint_cfg.connection_timeout) response.raise_for_status() response_data = response.json() - return [utils.ContextDocument(doc['title'], doc['content']) + return [utils.ContextDocument(doc['content'], doc['metadata']) for doc in response_data['context_docs']] diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index cda94df..3f70768 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -16,12 +16,12 @@ def _logger() -> logging.Logger: class LLMProxyService: """Communicates with the llm-proxy module and returns model's responses.""" - def __init__(self, llm_proxy_url: str): + def __init__(self, endpoint_cfg: utils.EndpointConnectionCfg): - self._llm_proxy_url = llm_proxy_url + self._endpoint_cfg = endpoint_cfg - _logger().debug('Created service for llm-proxy with url: %s', - llm_proxy_url) + _logger().info('Created service for llm-proxy with cfg: %s', + endpoint_cfg) def stream_chat_response(self, user_message: str, @@ -43,7 +43,7 @@ def stream_chat_response(self, 'chat_history: %s, context_docs: %s'), user_message, chat_history, context_docs) - url = f"{self._llm_proxy_url}/stream_chat_response" + url = f"{self._endpoint_cfg.url}/stream_chat_response" payload = { 'user_message': user_message, @@ -51,6 +51,8 @@ def stream_chat_response(self, 'context_docs': utils.context_docs_to_payload(context_docs) } - with httpx.stream('POST', url, json=payload, timeout=5) as stream: + with httpx.stream('POST', url, + json=payload, + timeout=self._endpoint_cfg.connection_timeout) as stream: for chunk in stream.iter_bytes(): yield json.loads(chunk.decode('utf-8')) diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index 85294ad..446ca0b 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -5,6 +5,14 @@ from typing import List from typing import TypeAlias +import pydantic + + +class EndpointConnectionCfg(pydantic.BaseModel): + """Configuration for connecting to a backend endpoint.""" + + url: str + connection_timeout: float @dataclasses.dataclass class ChatMessage: @@ -25,9 +33,8 @@ class ChatHistory: class ContextDocument: """Represents a single document retrieved from the doc store.""" - title: str content: str - + metadata: Dict[str, Any] UnstructuredChatHistory: TypeAlias = List[Dict[str, Any]] @@ -50,8 +57,8 @@ def context_docs_to_payload(context_docs: List[ContextDocument]) -> Unstructured return [ { - 'title': doc.title, - 'content': doc.content + 'content': doc.content, + 'metadata': doc.metadata, } for doc in context_docs ] diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index a455abb..e508cb1 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -146,7 +146,7 @@ def _create_retrieved_docs_representation(self) -> gr.Markdown: for docs in self._documents_retrieval_history: - docs_repr = (self._DOC_MD_TEMPLATE.format(title=doc.title, + docs_repr = (self._DOC_MD_TEMPLATE.format(title=doc.metadata['title'], content=doc.content) for doc in docs) From e0d3a4ca2dffe7bbcfe8aff331fccd0d233569ee Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:09:38 +0000 Subject: [PATCH 074/108] Introduce helper-llm endpoint --- docker-compose.yml | 25 ++++++++++++++++++++++++- persist_dir/helper-llm/.gitignore | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 persist_dir/helper-llm/.gitignore diff --git a/docker-compose.yml b/docker-compose.yml index 52546d1..cb8598d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,8 +52,31 @@ services: retries: 10 start_period: 30s + helper-llm: + build: + context: services/llm-endpoint/ + dockerfile: llm-endpoint.Dockerfile + args: + EXPOSED_PORT: 11434 + + container_name: helper-llm + ports: + - 11437:11437 + volumes: + - ./persist_dir/helper-llm:/root/.ollama + networks: + - rag-net + environment: + - LLM_GENERATOR_MODEL=dolphin3:8b + - OLLAMA_DEBUG=0 + - OLLAMA_HOST=0.0.0.0:11437 + healthcheck: + test: curl -s http://localhost:11437/api/tags | grep '"model":"local_ollama_model:latest"' + interval: 5m + timeout: 30s + retries: 10 + start_period: 30s - vector-store: build: context: services/vector-store/ diff --git a/persist_dir/helper-llm/.gitignore b/persist_dir/helper-llm/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/persist_dir/helper-llm/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From a988d674679e17ec1e73457d74aca692a4c4073e Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:17:17 +0000 Subject: [PATCH 075/108] Add helper-llm as endpoint used by context-retriever --- services/context-retriever/cfg/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml index 13f0cd5..4b03dcb 100644 --- a/services/context-retriever/cfg/main.yaml +++ b/services/context-retriever/cfg/main.yaml @@ -11,7 +11,7 @@ doc_retrieval: similarity_threshold: 0.6 helper_llm: model_name: local_ollama_model - url: http://main-llm-responder:11434 + url: http://helper-llm:11437 temperature: 0.2 From 0e51faeccc6c59b65a479da82f60076098de06a5 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:44:50 +0000 Subject: [PATCH 076/108] Enable arg overrides in run-server just recipe --- services/llm-proxy/justfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/llm-proxy/justfile b/services/llm-proxy/justfile index f8eae92..6e9daa9 100644 --- a/services/llm-proxy/justfile +++ b/services/llm-proxy/justfile @@ -3,6 +3,8 @@ # For more info, see: https://github.com/casey/just # -------------------------------------------------- +set positional-arguments + set shell := ["bash", "-c"] # Setup virtual environment and install dependencies. From 5af5e913c85c2577cff5f1ccee1dbd253cd367b8 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 7 Jan 2026 22:45:15 +0000 Subject: [PATCH 077/108] Enable using context documents by main llm responder --- services/llm-proxy/main.py | 8 +++++--- .../llm-proxy/src/llm_proxy/chat_llm_service.py | 6 ++++-- services/llm-proxy/src/llm_proxy/llm_actions.py | 17 ++++++++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index beb0b1b..217846c 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -67,9 +67,11 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR assert llm_service is not None - return StreamingResponse(llm_service.stream_chat_response(request.user_message, - chat_history=request.chat_history), - media_type='application/json') + return StreamingResponse( + llm_service.stream_chat_response(request.user_message, + chat_history=request.chat_history, + context_documents=request.context_docs), + media_type='application/json') def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index 5790240..fe58d4b 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -32,7 +32,9 @@ def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: async def stream_chat_response(self, user_query: str, - chat_history: list[dict[str, Any]]) -> AsyncIterator[bytes]: + chat_history: list[dict[str, Any]], + context_documents: list[dict[str, Any]] | None = None, + ) -> AsyncIterator[bytes]: """Streams, chunk by chunk, LLM response for a given query and chat history. The input is checkes according to the guardrails specification. @@ -65,7 +67,7 @@ async def stream_chat_response(self, async for chunk in self._chat_response_action.run( user_query=user_query, chat_history=chat_history, - context_documents=None + context_documents=context_documents ): chunk_struct = {'content': chunk} diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py index f58cacd..ffb8a68 100644 --- a/services/llm-proxy/src/llm_proxy/llm_actions.py +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -26,7 +26,7 @@ def __init__(self, async def run(self, user_query: str, chat_history: list[dict[str, str]], - context_documents: dict[str, Any] | None = None) -> AsyncIterator[str]: + context_documents: list[dict[str, Any]] | None = None) -> AsyncIterator[str]: """Generates chat response for the given user query and chat history.""" messages: list[BaseMessage] = [SystemMessage(content=self._SYSTEM_PROMPT)] @@ -41,10 +41,9 @@ async def run(self, messages.append(AIMessage(content=content)) if context_documents: - context_content = '\n\n'.join(context_documents) context_message = ( 'The following context documents are provided to help you answer the user query:\n' - f"{context_content}" + f"{self._format_context_documents(context_documents)}" ) messages.append(SystemMessage(content=context_message)) @@ -52,3 +51,15 @@ async def run(self, async for chunk in self._llm.astream(messages): yield str(chunk.content) + + def _format_context_documents(self, + context_documents: list[dict[str, Any]]) -> str: + """Formats context documents into a string for inclusion in the system prompt.""" + + formatted_docs = [] + + for doc in context_documents: + formatted_doc = f"Title: {doc['metadata']['title']}\nContent: {doc['content']}" + formatted_docs.append(formatted_doc) + + return '\n\n'.join(formatted_docs) From 868094c448534f85f180c2ae7fbacc914c3aa3df Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 09:36:45 +0000 Subject: [PATCH 078/108] Avoid copying unnecessary files to created services --- services/context-retriever/context-retriever.Dockerfile | 4 +++- services/llm-proxy/llm-proxy.Dockerfile | 4 +++- services/web-app/web-app.Dockerfile | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/services/context-retriever/context-retriever.Dockerfile b/services/context-retriever/context-retriever.Dockerfile index 199b0e5..0c79799 100644 --- a/services/context-retriever/context-retriever.Dockerfile +++ b/services/context-retriever/context-retriever.Dockerfile @@ -8,7 +8,9 @@ RUN apt-get update && \ RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh -COPY . /app +COPY cfg /app/cfg +COPY src /app/src +COPY pyproject.toml main.py /app/ WORKDIR /app EXPOSE ${API_PORT} diff --git a/services/llm-proxy/llm-proxy.Dockerfile b/services/llm-proxy/llm-proxy.Dockerfile index 199b0e5..0c79799 100644 --- a/services/llm-proxy/llm-proxy.Dockerfile +++ b/services/llm-proxy/llm-proxy.Dockerfile @@ -8,7 +8,9 @@ RUN apt-get update && \ RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh -COPY . /app +COPY cfg /app/cfg +COPY src /app/src +COPY pyproject.toml main.py /app/ WORKDIR /app EXPOSE ${API_PORT} diff --git a/services/web-app/web-app.Dockerfile b/services/web-app/web-app.Dockerfile index 4dcf105..ad9f1f0 100644 --- a/services/web-app/web-app.Dockerfile +++ b/services/web-app/web-app.Dockerfile @@ -8,7 +8,9 @@ RUN apt-get update && \ RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh -COPY . /app +COPY cfg /app/cfg +COPY src /app/src +COPY pyproject.toml main.py /app/ WORKDIR /app EXPOSE ${WEB_APP_PORT} From 153552b2014b50de6d663455ae1f47473e72fb81 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 09:37:02 +0000 Subject: [PATCH 079/108] Increase default timeout for endpoint communication in web-app --- services/web-app/cfg/main.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web-app/cfg/main.yaml b/services/web-app/cfg/main.yaml index eb68eea..4475cbc 100644 --- a/services/web-app/cfg/main.yaml +++ b/services/web-app/cfg/main.yaml @@ -1,11 +1,11 @@ --- context_retriever_cfg: url: http://context-retriever:8899 - connection_timeout: 45 + connection_timeout: 90 llm_proxy_cfg: url: http://llm-proxy:8888 - connection_timeout: 45 + connection_timeout: 90 persist_data_path: data/ web_app_port: 8080 web_app_host: 0.0.0.0 From 3ab411e90af9ebe608bfce800a3e5f5c464e6e3d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 10:49:28 +0000 Subject: [PATCH 080/108] Rename context-retriever .devcontainer config for name consistency --- .devcontainer/{context_retriever => context-retriever}/Dockerfile | 0 .../{context_retriever => context-retriever}/devcontainer.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .devcontainer/{context_retriever => context-retriever}/Dockerfile (100%) rename .devcontainer/{context_retriever => context-retriever}/devcontainer.json (100%) diff --git a/.devcontainer/context_retriever/Dockerfile b/.devcontainer/context-retriever/Dockerfile similarity index 100% rename from .devcontainer/context_retriever/Dockerfile rename to .devcontainer/context-retriever/Dockerfile diff --git a/.devcontainer/context_retriever/devcontainer.json b/.devcontainer/context-retriever/devcontainer.json similarity index 100% rename from .devcontainer/context_retriever/devcontainer.json rename to .devcontainer/context-retriever/devcontainer.json From 162a0eb0bc38e560f8bbd7c00bb00374386d2624 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 10:52:32 +0000 Subject: [PATCH 081/108] Enable firing workflows on changes to devcontainer setup --- .github/workflows/service-checks.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 96d7c61..3aa5474 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -9,6 +9,7 @@ on: - services/context-retriever/** - services/web-app/** - services/llm-proxy/** + - .devcontainer/** push: paths: - .github/workflows/service-checks.yml @@ -17,6 +18,7 @@ on: - services/context-retriever/** - services/web-app/** - services/llm-proxy/** + - .devcontainer/** permissions: contents: read @@ -48,16 +50,22 @@ jobs: - .pre-commit-config.yaml - pyproject.toml - .github/workflows/service-checks.yml + - .devcontainer/context-retriever/** + - .devcontainer/scripts/** web-app: - services/web-app/** - .pre-commit-config.yaml - pyproject.toml - .github/workflows/service-checks.yml + - .devcontainer/web-app/** + - .devcontainer/scripts/** llm-proxy: - services/llm-proxy/** - .pre-commit-config.yaml - pyproject.toml - .github/workflows/service-checks.yml + - .devcontainer/llm-proxy/** + - .devcontainer/scripts/** precommit-context-retriever: name: Pre-commit (context-retriever) From 9da7e0122f359e838e8c4c61c4e56a2bc34f1fc7 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 10:58:21 +0000 Subject: [PATCH 082/108] Add environment setup before running precommit --- .github/workflows/service-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 3aa5474..8e62a62 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -24,7 +24,7 @@ permissions: contents: read env: - PRECOMMIT_CMD: just run-precommit + PRECOMMIT_CMD: just setup-environment && just run-precommit SSH_AUTH_SOCK: /tmp/ssh-agent jobs: From 1369bc1b568fd1cf9208356c7f55d2af07c30a2a Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 18:09:39 +0000 Subject: [PATCH 083/108] Add two-lines validation action --- .../llm-proxy/src/llm_proxy/llm_actions.py | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py index ffb8a68..de94081 100644 --- a/services/llm-proxy/src/llm_proxy/llm_actions.py +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -1,6 +1,7 @@ """Contains modules performing LLM-related isolated actions.""" from typing import Any from typing import AsyncIterator +import logging from langchain_core.language_models.chat_models import BaseChatModel from langchain_core.messages import AIMessage @@ -9,6 +10,10 @@ from langchain_core.messages import SystemMessage +def _logger() -> logging.Logger: + return logging.getLogger(__name__) + + class ChatResponseAction: """Generates chat response for a given user query and chat history.""" @@ -63,3 +68,79 @@ def _format_context_documents(self, formatted_docs.append(formatted_doc) return '\n\n'.join(formatted_docs) + + +class SimpleConversationValidateAction: + """Validates a conversation using a two line response format. + + The response is expected to contain: + 1. A single word indicating whether the input is 'good' or 'bad'. + 2. A brief explanation in words of the decision. + """ + + def __init__(self, + system_prompt: str, + main_prompt_template: str, + good_keyword: str, + llm: BaseChatModel + ) -> None: + """Args: + system_prompt: The system prompt to set the behavior of the LLM. + main_prompt_template: The main prompt template containing a placeholder + for the 'conversation' and 'user_input'. + good_keyword: The keyword indicating a 'good' input in the LLM response. + E.g. 'safe'. + llm: The language model to use for validation. + """ + + self._system_prompt = system_prompt + self._main_prompt_template = main_prompt_template + self._good_keyword = good_keyword + self._llm = llm + + async def run(self, + user_query: str, + chat_history: list[dict[str, str]]) -> tuple[bool, str | None]: + """Returns a tuple indicating whether the input is safe and an optional reason.""" + + messages = [SystemMessage(self._system_prompt), + HumanMessage(self._main_prompt_template.format( + conversation_history=self._format_conversation(chat_history), + user_input=user_query))] + + try: + response = await self._llm.ainvoke(messages) + + except Exception as e: # pylint: disable=broad-except + _logger().error('Validation LLM call failed: %s', str(e)) + return False, 'Internal system error during conversation validation.' + + decision = str(response.content) + decision_lines = [line.strip() for line in decision.split('\n') if line.strip()] + + _logger().debug('Validation LLM raw response:\n%s', decision) + + if len(decision_lines) != 2: + return False, 'Validation LLM returned an invalid response format.' + + if decision_lines[0].lower() == self._good_keyword.lower(): + return True, None + + return False, decision_lines[1] + + def _format_conversation(self, + chat_history: list[dict[str, str]]) -> str: + """Formats the conversation history into a string.""" + + conversation_lines = [] + + for message in chat_history: + role = message['role'] + content = message['content'] + + if role == 'user': + conversation_lines.append(f'User: {content}') + else: + conversation_lines.append(f'Assistant: {content}') + + return '\n'.join(conversation_lines) From ad8d0488522f27fdd895d79e4c406b46d3cec026 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 18:11:07 +0000 Subject: [PATCH 084/108] Update rails Add content relevance rail Apply prompt engineering to enhance rail response quality --- services/llm-proxy/cfg/main.yaml | 4 + .../llm-proxy/src/llm_proxy/rails/rails.py | 144 ++++++++++++------ 2 files changed, 101 insertions(+), 47 deletions(-) diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index 3ef3b97..312a5d0 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -11,3 +11,7 @@ models: conversation_safety_guardrail: model: local_ollama_model base_url: http://guard-llm:11435 + + input_relevance_guardrail: + model: local_ollama_model + base_url: http://guard-llm:11435 \ No newline at end of file diff --git a/services/llm-proxy/src/llm_proxy/rails/rails.py b/services/llm-proxy/src/llm_proxy/rails/rails.py index d399890..55e1901 100644 --- a/services/llm-proxy/src/llm_proxy/rails/rails.py +++ b/services/llm-proxy/src/llm_proxy/rails/rails.py @@ -2,8 +2,7 @@ import logging from langchain_core.language_models.chat_models import BaseChatModel -from langchain_core.messages import HumanMessage -from langchain_core.messages import SystemMessage +from llm_proxy import llm_actions from llm_proxy.rails.core import Guardrail from llm_proxy.rails.core import GuardrailDecision from llm_proxy.rails.core import LLMCallContext @@ -25,11 +24,14 @@ class ConversationSafetyGuardrail(Guardrail): guidelines.""" _MAIN_PROMPT_TEMPLATE = """ - Your task is to determine whether the given user query is safe and appropriate, according - to the following guidelines: + Between the and tags, there is a conversation between + user and assistant that represents an official institution. Your task is to determine whether + the LAST user query is safe and appropriate, i.e. it DOES NOT fall under one of the categories + provided between the and tags. + Pay heed to the entire conversation history when making your decision. - S1. Sexual content + S1. Sexual content or any sex-related material S2. Sexual exploitation of minors S3. Hate speech or discriminatory language S4. Violent or graphic content @@ -37,69 +39,117 @@ class ConversationSafetyGuardrail(Guardrail): S6. Vulgar or offensive language - Pay heed to the entire conversation history when making your decision. - - {conversation} + {conversation_history} + User: {user_input} - Your response should contain two lines: - 1. One word: 'safe' if the conversation is safe, or 'unsafe' if it is not. - 2. A brief explanation IN WORDS of your decision based on the guidelines. Do not use - policy category codes, instead use your words. I the conversation is safe, write 'N/A'. + Your response should contain EXACTLY TWO lines: + The first line should contain one word. If the query is safe according to the guidelines, + it should contain the word 'safe', and, if it is unsafe according to the guidelines, it + should contains the word 'unsafe'. It it does not fall under any of the categories, it is 'safe'. + The second line should contain a brief explanation IN WORDS of your decision based on the + guidelines. Do not use policy category codes, instead use your words. Formulate the explanation + in such a way that it can be directly shown to the end user. """ def __init__(self, llm: BaseChatModel) -> None: self._llm = llm + self._action = llm_actions.SimpleConversationValidateAction( + system_prompt=self._SYSTEM_PROMPT, + main_prompt_template=self._MAIN_PROMPT_TEMPLATE, + good_keyword='safe', + llm=llm + ) + async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecision: """Returns true if the conversation is safe, false otherwise.""" - messages = [SystemMessage(self._SYSTEM_PROMPT), - HumanMessage(self._MAIN_PROMPT_TEMPLATE.format( - conversation=self._format_conversation(llm_call_context)))] + decision, reason = await self._action.run( + user_query=llm_call_context.user_message, + chat_history=llm_call_context.chat_history + ) + + _logger().debug('Guardrail \'%s\' response: %s', self.name, decision) - response = await self._llm.ainvoke(messages) + return GuardrailDecision(should_pass=decision, reason=reason) - decision = str(response.content) - decision_lines = [line.strip() for line in decision.split('\n') if line.strip()] + @property + def name(self) -> str: + return 'ConversationSafetyGuardrail' - _logger().debug('Guardrail \'%s\' response:\n%s', self.name, decision) - if len(decision_lines) != 2: - return GuardrailDecision( - should_pass=False, - reason='Guardrail execution failed.' - ) +class ConversationRelevanceGuardrail(Guardrail): + """Guardrail that checks whether the user input follows one of the expected topics. - if decision_lines[0].lower() == 'safe': - return GuardrailDecision(should_pass=True) + The guardrail is designed to ensure that the user cannot ask things about things the chat + is not supposed to answer. For example, if the chat is supposed to answer questions + about cooking, the guardrail will block questions about politics. + """ - return GuardrailDecision( - should_pass=False, - reason=decision_lines[1] - ) + _SYSTEM_PROMPT = """You are a professional content moderator. Your task is to determine + whether the content's topic does not diverge from a specified set of allowed topics.""" - @property - def name(self) -> str: - return 'ConversationSafetyGuardrail' + _MAIN_PROMPT_TEMPLATE = """ + Between the and tags, there is a conversation between + user and assistant that represents AGH University of Krakow institution. The user is supposed + to ask questions on the functioning of the university, but shouldn't ask any other questions. + Your task is to determine whether the LAST user query strictly concerns at least one of the + topics provided between the and + tags. If it is unrelated to them or only barely touches on them but is mostly about other + things, mark it as 'unrelated'. Pay heed to the entire conversation history when making your + decision. + + + 1. Basic information about the AGH University of Krakow. + 2. Academic programs and courses offered at AGH University of Krakow. + 3. Campus facilities and services available to students at AGH University of Krakow. + 4. Admission requirements and application procedures for AGH University of Krakow. + 5. Extracurricular activities and student organizations at AGH University of Krakow. + 6. Events and news related to AGH University of Krakow. + 7. Research opportunities and projects at AGH University of Krakow. + 8. Rules and procedures related to studying at AGH University of Krakow. + + + + {conversation_history} + User: {user_input} + + + Your response should contain EXACTLY TWO lines: + The first line should contain one word. If the query is relevant to the allowed topics, + it should contain the word 'related', and, if it concerns other topics, it should contains + the word 'unrelated'. + The second line should contain a brief explanation IN WORDS of your decision based on the + guidelines. Do not use policy category codes, instead use your words. Formulate the explanation + in such a way that it can be directly shown to the end user. + """ + + def __init__(self, llm: BaseChatModel) -> None: - def _format_conversation(self, - llm_call_context: LLMCallContext) -> str: - """Formats the conversation history into a string.""" + self._llm = llm + + self._action = llm_actions.SimpleConversationValidateAction( + system_prompt=self._SYSTEM_PROMPT, + main_prompt_template=self._MAIN_PROMPT_TEMPLATE, + good_keyword='related', + llm=llm + ) + + async def should_pass(self, llm_call_context: LLMCallContext) -> GuardrailDecision: + """Returns true if the user input is relevant, false otherwise.""" - conversation_lines = [] + decision, reason = await self._action.run( + user_query=llm_call_context.user_message, + chat_history=llm_call_context.chat_history + ) - for message in llm_call_context.chat_history + [ - {'role': 'user', 'content': llm_call_context.user_message} - ]: - role = message['role'] - content = message['content'] + _logger().debug('Guardrail \'%s\' response: %s', self.name, decision) - if role == 'user': - conversation_lines.append(f'User: {content}') - else: - conversation_lines.append(f'Assistant: {content}') + return GuardrailDecision(should_pass=decision, reason=reason) - return '\n'.join(conversation_lines) + @property + def name(self) -> str: + return 'ConversationRelevanceGaurdrail' From faeb56e0f3253add766ebe73e0063a90f3d3f9f1 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 18:13:14 +0000 Subject: [PATCH 085/108] Move input guardrails to separate api methods --- services/llm-proxy/main.py | 55 ++++++++++++-- .../src/llm_proxy/chat_llm_service.py | 71 ++++++++++++------- 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/services/llm-proxy/main.py b/services/llm-proxy/main.py index 217846c..3b65e89 100644 --- a/services/llm-proxy/main.py +++ b/services/llm-proxy/main.py @@ -54,26 +54,71 @@ async def read_ping() -> dict[str, str]: return {'message': 'Service is running'} +class ConversationState(pydantic.BaseModel): + """State of the chat conversation including chat history and current user query.""" + chat_history: list[dict[str, Any]] + user_message: str + + class RequestStreamChatResponse(pydantic.BaseModel): """Request to return the LLM response for a given query and retrieved context.""" - user_message: str - chat_history: list[dict[str, Any]] + conversation_state: ConversationState context_docs: list[dict[str, Any]] @app.post('/stream_chat_response') async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingResponse: - """Streams chat response for the user query based on the provided context.""" + """Streams chat response for the user query based on the provided context. + + The conversation is expected to be safe i.e. no input rails are fired during handling + the request. In order to use the input guardrails, the client should call relevant + endpoints. + """ assert llm_service is not None return StreamingResponse( - llm_service.stream_chat_response(request.user_message, - chat_history=request.chat_history, + llm_service.stream_chat_response(request.conversation_state.user_message, + chat_history=request.conversation_state.chat_history, context_documents=request.context_docs), media_type='application/json') +class ResponseInputCheck(pydantic.BaseModel): + """Response containing the status of input guardrails check.""" + + is_ok: bool + reason: str | None = None + + +@app.post('/check_input_safety') +async def check_input_safety(request: ConversationState) -> ResponseInputCheck: + """Fires the internal safety guardrails on the current conversation state.""" + + assert llm_service is not None + + is_ok, reason = await llm_service.check_input_safety( + user_query=request.user_message, + chat_history=request.chat_history + ) + + return ResponseInputCheck(is_ok=is_ok, reason=reason) + + +@app.post('/check_input_relevance') +async def check_input_relevance(request: ConversationState) -> ResponseInputCheck: + """Fires the internal guardrails responsible for checking the relevance of the user input.""" + + assert llm_service is not None + + is_ok, reason = await llm_service.check_input_relevance( + user_query=request.user_message, + chat_history=request.chat_history + ) + + return ResponseInputCheck(is_ok=is_ok, reason=reason) + + def _configure_logging(script_cfg: omegaconf.DictConfig) -> None: logging.config.dictConfig({ diff --git a/services/llm-proxy/src/llm_proxy/chat_llm_service.py b/services/llm-proxy/src/llm_proxy/chat_llm_service.py index fe58d4b..0cf1c88 100644 --- a/services/llm-proxy/src/llm_proxy/chat_llm_service.py +++ b/services/llm-proxy/src/llm_proxy/chat_llm_service.py @@ -7,7 +7,6 @@ from langchain_ollama import ChatOllama from llm_proxy import llm_actions from llm_proxy.rails import rails -from llm_proxy.rails.core import Guardrail from llm_proxy.rails.core import LLMCallContext @@ -20,11 +19,13 @@ class ChatLLMService: def __init__(self, models_cfg: dict[str, dict[str, Any]]) -> None: - self._input_guardrails: list[Guardrail] = [ - rails.ConversationSafetyGuardrail( - llm=ChatOllama(**models_cfg['conversation_safety_guardrail'], - temperature=0.0)) - ] + self._safety_guardrails = rails.ConversationSafetyGuardrail( + llm=ChatOllama(**models_cfg['conversation_safety_guardrail'], + temperature=0.0)) + + self._relevance_guardrails = rails.ConversationRelevanceGuardrail( + llm=ChatOllama(**models_cfg['input_relevance_guardrail'], + temperature=0.0)) self._chat_response_action = llm_actions.ChatResponseAction( llm=ChatOllama(**models_cfg['main_chat']) @@ -43,26 +44,6 @@ async def stream_chat_response(self, _logger().debug('Streaming llm response for query \'%s\' and conversation %s...', user_query, chat_history) - llm_call_context = LLMCallContext( - user_message=user_query, - chat_history=chat_history, - retrieved_context=[] - ) - - for guardrail in self._input_guardrails: - decision = await guardrail.should_pass(llm_call_context) - - if not decision.should_pass: - error_message = ( - f'Input guardrail \'{guardrail.name}\' blocked the request. ' - f'Reason: {decision.reason}' - ) - - _logger().warning(error_message) - - yield json.dumps({'error': error_message}).encode('utf-8') - return - try: async for chunk in self._chat_response_action.run( user_query=user_query, @@ -77,3 +58,41 @@ async def stream_chat_response(self, _logger().error('Chat call failed: %s', str(e)) yield json.dumps({'error': 'Internal system error.'}).encode('utf-8') + + async def check_input_safety(self, + user_query: str, + chat_history: list[dict[str, Any]], + ) -> tuple[bool, str | None]: + """Checks whether the conversation state passes the input safety guardrails.""" + + _logger().debug('Checking input safety for query \'%s\' and conversation %s...', + user_query, chat_history) + + decision = await self._safety_guardrails.should_pass( + LLMCallContext( + user_message=user_query, + chat_history=chat_history, + retrieved_context=[] + ) + ) + + return decision.should_pass, decision.reason + + async def check_input_relevance(self, + user_query: str, + chat_history: list[dict[str, Any]], + ) -> tuple[bool, str | None]: + """Checks whether the conversation state passes the input relevance guardrails.""" + + _logger().debug('Checking input relevance for query \'%s\' and conversation %s...', + user_query, chat_history) + + decision = await self._relevance_guardrails.should_pass( + LLMCallContext( + user_message=user_query, + chat_history=chat_history, + retrieved_context=[] + ) + ) + + return decision.should_pass, decision.reason From 8fe8e5f43dfcd622d3576483dc9cc758482ba55d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 8 Jan 2026 18:13:51 +0000 Subject: [PATCH 086/108] Add development configuration --- services/llm-proxy/cfg/main-dev.yaml | 17 +++++++++++++++++ services/llm-proxy/justfile | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 services/llm-proxy/cfg/main-dev.yaml diff --git a/services/llm-proxy/cfg/main-dev.yaml b/services/llm-proxy/cfg/main-dev.yaml new file mode 100644 index 0000000..47ae21c --- /dev/null +++ b/services/llm-proxy/cfg/main-dev.yaml @@ -0,0 +1,17 @@ +--- +server_host: 0.0.0.0 +server_port: 8888 +n_server_workers: 1 +persist_data_path: data/ +models: + main_chat: + model: local_ollama_model + base_url: http://localhost:11434 + + conversation_safety_guardrail: + model: local_ollama_model + base_url: http://localhost:11435 + + input_relevance_guardrail: + model: local_ollama_model + base_url: http://localhost:11435 \ No newline at end of file diff --git a/services/llm-proxy/justfile b/services/llm-proxy/justfile index 6e9daa9..797223f 100644 --- a/services/llm-proxy/justfile +++ b/services/llm-proxy/justfile @@ -14,7 +14,7 @@ setup-environment: uv pip install -e .[dev] run-server *args: - uv run python main.py "$@" + uv run python main.py --config-name "main-dev" "$@" # Runs static checks using global pre-commit configuration. run-precommit: From 8a6fac06c30cbd1675127c370998ab8814cb3c00 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 11:21:06 +0000 Subject: [PATCH 087/108] Update type annotations of lists, dicts and tuples --- .../src/web_app/backend/context_retriever.py | 5 ++--- .../web-app/src/web_app/backend/llm_proxy.py | 6 ++---- services/web-app/src/web_app/backend/utils.py | 16 ++++++++-------- .../web-app/src/web_app/gui/main_controller.py | 9 +++------ 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index 888a457..80ef611 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -1,6 +1,5 @@ """Contains implementation of service that communicates with the context retriever module.""" import logging -from typing import List import requests from web_app.backend import utils @@ -18,11 +17,11 @@ def __init__(self, endpoint_cfg: utils.EndpointConnectionCfg): self._endpoint_cfg = endpoint_cfg _logger().info('Created service for context-retriever with cfg: %s', - endpoint_cfg) + endpoint_cfg) def collect_context_info(self, user_message: str, - chat_history: utils.ChatHistory) -> List[utils.ContextDocument]: + chat_history: utils.ChatHistory) -> list[utils.ContextDocument]: """Collects context information based on the user's message and chat history. Args: diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index 3f70768..2ea335b 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -1,9 +1,7 @@ """Contains service that communicates with the llm-proxy module.""" import json import logging -from typing import Dict from typing import Iterator -from typing import List import httpx from web_app.backend import utils @@ -21,12 +19,12 @@ def __init__(self, endpoint_cfg: utils.EndpointConnectionCfg): self._endpoint_cfg = endpoint_cfg _logger().info('Created service for llm-proxy with cfg: %s', - endpoint_cfg) + endpoint_cfg) def stream_chat_response(self, user_message: str, chat_history: utils.ChatHistory, - context_docs: List[utils.ContextDocument]) -> Iterator[Dict[str, str]]: + context_docs: list[utils.ContextDocument]) -> Iterator[dict[str, str]]: """Collects LLM response based on the context and streams it. Args: diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index 446ca0b..d0d4e39 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -1,9 +1,7 @@ """Contains utilities used by the backend services.""" import dataclasses -from typing import Any -from typing import Dict -from typing import List from typing import TypeAlias +from typing import Any import pydantic @@ -14,6 +12,7 @@ class EndpointConnectionCfg(pydantic.BaseModel): url: str connection_timeout: float + @dataclasses.dataclass class ChatMessage: """Represents a single chat message.""" @@ -26,7 +25,7 @@ class ChatMessage: class ChatHistory: """Contains history of messages in a chat session.""" - messages: List[ChatMessage] + messages: list[ChatMessage] @dataclasses.dataclass @@ -34,11 +33,12 @@ class ContextDocument: """Represents a single document retrieved from the doc store.""" content: str - metadata: Dict[str, Any] + metadata: dict[str, Any] + -UnstructuredChatHistory: TypeAlias = List[Dict[str, Any]] +UnstructuredChatHistory: TypeAlias = list[dict[str, str]] -UnstructuredContextDocs: TypeAlias = List[Dict[str, Any]] +UnstructuredContextDocs: TypeAlias = list[dict[str, Any]] def chat_history_to_payload(chat_history: ChatHistory) -> UnstructuredChatHistory: @@ -52,7 +52,7 @@ def chat_history_to_payload(chat_history: ChatHistory) -> UnstructuredChatHistor ] -def context_docs_to_payload(context_docs: List[ContextDocument]) -> UnstructuredContextDocs: +def context_docs_to_payload(context_docs: list[ContextDocument]) -> UnstructuredContextDocs: """Converts context docs into json representation.""" return [ diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index e508cb1..8a71569 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -1,11 +1,8 @@ """Contains GUI related utils.""" import logging from typing import Any -from typing import Dict from typing import Iterator -from typing import List -from typing import Optional -from typing import Tuple +import requests import gradio as gr from web_app.backend import context_retriever @@ -39,7 +36,7 @@ def __init__(self, self._context_retriever_service = context_retriever_service self._llm_proxy_service = llm_proxy_service - self._documents_retrieval_history: List[List[utils.ContextDocument]] = [] + self._documents_retrieval_history: list[list[utils.ContextDocument]] = [] def render_gui(self) -> None: """Renders the UI for application and assigns the necessary callbacks.""" @@ -142,7 +139,7 @@ def _stream_llm_response(self, def _create_retrieved_docs_representation(self) -> gr.Markdown: """Concatenates the documents retrieved till now and returns their Markdown repr.""" - retrieval_history_reprs: List[str] = [] + retrieval_history_reprs: list[str] = [] for docs in self._documents_retrieval_history: From 5dcf61fcbc6d4cfc0d1689d6c52219a3cc9fac21 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 11:23:06 +0000 Subject: [PATCH 088/108] Update dev configuration Updated mock backend Added mypy extension to devcontainer Fixed bugs in main_dev entrypoint --- .devcontainer/web-app/devcontainer.json | 3 +- services/web-app/cfg/main_dev.yaml | 12 ++- services/web-app/main_dev.py | 5 +- services/web-app/mock_backend.py | 123 +++++++++++++++++------- 4 files changed, 101 insertions(+), 42 deletions(-) diff --git a/.devcontainer/web-app/devcontainer.json b/.devcontainer/web-app/devcontainer.json index 10ce2f9..e2472a7 100644 --- a/.devcontainer/web-app/devcontainer.json +++ b/.devcontainer/web-app/devcontainer.json @@ -27,7 +27,8 @@ "ms-python.pylint", "ms-python.autopep8", "tamasfe.even-better-toml", - "VisualStudioExptTeam.vscodeintellicode" + "VisualStudioExptTeam.vscodeintellicode", + "matangover.mypy" ] } } diff --git a/services/web-app/cfg/main_dev.yaml b/services/web-app/cfg/main_dev.yaml index f3d235e..cbfafca 100644 --- a/services/web-app/cfg/main_dev.yaml +++ b/services/web-app/cfg/main_dev.yaml @@ -1,5 +1,11 @@ --- -context_retriever_url: http://localhost:8888 -llm_proxy_url: http://localhost:8888 +context_retriever_cfg: + url: http://localhost:8888 + connection_timeout: 90 + +llm_proxy_cfg: + url: http://localhost:8888 + connection_timeout: 90 +persist_data_path: data/ web_app_port: 8080 -web_app_host: localhost +web_app_host: 0.0.0.0 diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 4eb8110..8966915 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -8,6 +8,7 @@ from web_app.backend import llm_proxy from web_app.gui import main_controller from web_app.gui import utils as gui_utils +from web_app.backend import utils as backend_utils def _logger() -> logging.Logger: @@ -44,11 +45,11 @@ def _logger() -> logging.Logger: }) context_retriever_service = context_retriever.ContextRetrieverService( - cfg.context_retriever_url + endpoint_cfg=backend_utils.EndpointConnectionCfg(**cfg.context_retriever_cfg) ) llm_proxy_service = llm_proxy.LLMProxyService( - cfg.llm_proxy_url + endpoint_cfg=backend_utils.EndpointConnectionCfg(**cfg.llm_proxy_cfg) ) with gr.Blocks(fill_height=True, title='AGH Chat', css=gui_utils.CUSTOM_CSS) as web_application: diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index 8f57410..ddcc515 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -12,55 +12,31 @@ import omegaconf import pydantic import uvicorn -from fastapi import FastAPI +import fastapi from fastapi.responses import StreamingResponse -app = FastAPI() +# pylint: disable-all +# mypy: ignore-errors +app = fastapi.FastAPI() -@app.get('/ping') -async def read_ping() -> Dict[str, str]: - """Health check endpoint.""" - return {'message': 'Service is running'} - -class RequestCollectContextInfo(pydantic.BaseModel): - """Request from web-app to context-retriever to collect context documents.""" +class ConversationState(pydantic.BaseModel): + """State of the chat conversation including chat history and current user query.""" + chat_history: list[dict[str, Any]] user_message: str - chat_history: List[Dict[str, Any]] - - -class ResponseCollectContextInfo(pydantic.BaseModel): - """Response from context-retriever to web-app with collected context docs.""" - context_docs: List[Dict[str, Any]] - - -@app.post('/collect_context_info') -async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: - """Collects context information from database for a given query.""" - - logging.info('/collect_context_info - Message: %s', request.user_message) - - mock_docs = [ - {'title': 'doc1', 'content': 'This is the content of document 1.'}, - {'title': 'doc2', 'content': 'This is the content of document 2.'}, - {'title': 'doc3', 'content': 'This is the content of document 3.'}, - ] - - return ResponseCollectContextInfo(context_docs=random.sample(mock_docs, 2)) class RequestStreamChatResponse(pydantic.BaseModel): - """Request from web-app to llm-proxy to stream chat responses.""" - user_message: str - chat_history: List[Dict[str, Any]] - context_docs: List[Dict[str, Any]] + """Request to return the LLM response for a given query and retrieved context.""" + conversation_state: ConversationState + context_docs: list[dict[str, Any]] @app.post('/stream_chat_response') async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingResponse: - """Streams chat response for the user query based on the provided context.""" + """""" mock_response = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud @@ -72,9 +48,15 @@ async def stream_chat_response(request: RequestStreamChatResponse) -> StreamingR mock_words = mock_response.split() response = ' '.join(random.sample(mock_words, len(mock_words))) - response += f'Documents used: {[doc['title'] for doc in request.context_docs]}' + response += f'Documents used: {[doc["metadata"]["title"] for doc in request.context_docs]}' async def event_generator() -> AsyncIterator[bytes]: + + if 'fail' in request.conversation_state.user_message.lower(): + chunk = {'error': 'Simulated backend failure.'} + yield json.dumps(chunk).encode('utf-8') + return + for token in response.replace(' ', ' [split_token]') .split('[split_token]'): chunk = {'content': token} yield json.dumps(chunk).encode('utf-8') @@ -83,6 +65,75 @@ async def event_generator() -> AsyncIterator[bytes]: return StreamingResponse(event_generator(), media_type='application/json') +class ResponseInputCheck(pydantic.BaseModel): + + is_ok: bool + reason: str | None = None + + +@app.post('/check_input_safety') +async def check_input_safety(request: ConversationState) -> ResponseInputCheck: + + if 'badword' in request.user_message.lower(): + return ResponseInputCheck(is_ok=False, reason='Inappropriate language detected.') + + return ResponseInputCheck(is_ok=True) + + +@app.post('/check_input_relevance') +async def check_input_relevance(request: ConversationState) -> ResponseInputCheck: + + if 'unrelated' in request.user_message.lower(): + return ResponseInputCheck( + is_ok=False, reason='Input is not relevant.') + + return ResponseInputCheck(is_ok=True) + + +class RequestCollectContextInfo(pydantic.BaseModel): + user_message: str + chat_history: list[dict[str, Any]] + + +class ResponseCollectContextInfo(pydantic.BaseModel): + context_docs: list[dict[str, Any]] + + +@app.post('/collect_context_info') +async def collect_context_info(request: RequestCollectContextInfo) -> ResponseCollectContextInfo: + + await asyncio.sleep(3.0) + + logging.info('/collect_context_info - Message: %s', request.user_message) + + mock_docs = [ + {'content': 'This is document 1', 'metadata': { + 'title': 'Document 1', + 'author': 'Author A', + 'page': '1'}}, + {'content': 'This is document 2', 'metadata': { + 'title': 'Document 2', + 'author': 'Author B', + 'page': '2'}}, + {'content': 'This is document 3', 'metadata': { + 'title': 'Document 3', + 'author': 'Author C', + 'page': '3'}}, + ] + + return ResponseCollectContextInfo(context_docs=random.sample(mock_docs, 2)) + + +class ResponseUploadDocument(pydantic.BaseModel): + error: str | None = None + + +@app.post('/upload_pdf') +async def upload_pdf(file: fastapi.UploadFile) -> ResponseUploadDocument: + + return ResponseUploadDocument() + + @hydra.main(version_base=None, config_path='cfg', config_name='mock_backend') def main(cfg: omegaconf.DictConfig) -> None: """Sets up the mock backend service.""" From fdb2493967098b976fe3bacbbb7eed0cfcb6da1f Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 11:23:49 +0000 Subject: [PATCH 089/108] Fix creating payload for stream_chat_response call --- services/web-app/src/web_app/backend/llm_proxy.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index 2ea335b..5733d8c 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -44,8 +44,10 @@ def stream_chat_response(self, url = f"{self._endpoint_cfg.url}/stream_chat_response" payload = { - 'user_message': user_message, - 'chat_history': utils.chat_history_to_payload(chat_history), + 'conversation_state': { + 'user_message': user_message, + 'chat_history': utils.chat_history_to_payload(chat_history) + }, 'context_docs': utils.context_docs_to_payload(context_docs) } From b26d500227f2bec0f431c87f9b36d6dfde928509 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 11:25:43 +0000 Subject: [PATCH 090/108] Rework chat-user interaction logic Moved collecting & updating docs and streaming response to separate handlers Added handling errors returned by llm --- .../src/web_app/gui/main_controller.py | 131 ++++++++++-------- 1 file changed, 73 insertions(+), 58 deletions(-) diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 8a71569..646baea 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -64,77 +64,57 @@ def render_gui(self) -> None: with gr.Column(elem_id='chat_column', scale=3): - gr.ChatInterface( - self._chat_interface_callback, - chatbot=gr.Chatbot(elem_id='agh_chat', - type='messages', - height='70vh', - show_copy_button=True), - title='AGH Chat', - type='messages', - textbox=gr.Textbox( - placeholder='Type a message...', label='Your message'), - additional_outputs=[docs_list], + gr.Label('AGH Chat', elem_id='agh_chat_label', show_label=False) + + chatbot = gr.Chatbot(elem_id='agh_chat', + type='messages', + height='70vh', + show_copy_button=True, + label='AGH Chat') + msg = gr.Textbox(placeholder='Type a message...', show_label=False) + + msg.submit( # pylint: disable=no-member + self._move_user_msg_to_chat, [msg, chatbot], [msg, chatbot] + ).success( + self._retrieve_and_store_docs, chatbot, None + ).success( + self._stream_chat_response, chatbot, chatbot + ).success( + self._create_retrieved_docs_representation, None, docs_list ) - def _chat_interface_callback(self, - user_message: str, - raw_history: Optional[utils.UnstructuredChatHistory], - ) -> Iterator[Tuple[Dict[str, Any], gr.Markdown]]: - """Main callback for the chat interface. + def _stream_chat_response(self, + chat_history: utils.UnstructuredChatHistory, + ) -> Iterator[utils.UnstructuredChatHistory]: + """Streams the chat response based on the chat history with the latest user msg.""" - It first retrieves context docs from the context-retriever, updates the internal documents - storage and streams the llm-proxy response together with the markdown representation - of the retrieval history. - """ + chat_history, user_message = chat_history[:-1], chat_history[-1]['content'] - raw_history = raw_history or [] - - chat_history = utils.ChatHistory( + structured_history = utils.ChatHistory( [utils.ChatMessage(message['role'], message['content']) - for message in raw_history] + for message in chat_history] ) - try: - context_docs = self._context_retriever_service.collect_context_info( - user_message=user_message, - chat_history=chat_history - ) - - self._documents_retrieval_history.append(context_docs) - - except Exception as e: - _logger().error('Failed to collect context info from backend.') - raise gr.Error('Failed to collect context info from backend.', duration=5) from e + full_response = '' - context_docs_repr = self._create_retrieved_docs_representation() - - for chat_message in self._stream_llm_response(user_message, - chat_history, - context_docs): - yield chat_message, context_docs_repr + for chunk in self._llm_proxy_service.stream_chat_response( + user_message=user_message, + chat_history=structured_history, + context_docs=self._documents_retrieval_history[-1] + ): - def _stream_llm_response(self, - user_message: str, - chat_history: utils.ChatHistory, - context_docs: List[utils.ContextDocument]) -> Iterator[Dict[str, Any]]: - """Yields concatenated chunks retrieved from the llm.""" + if 'error' in chunk: + _logger().debug('Received error from llm-proxy: %s', chunk['error']) - chat_response = self._llm_proxy_service.stream_chat_response( - user_message=user_message, - chat_history=chat_history, - context_docs=context_docs - ) + yield chat_history + self._documents_retrieval_history.pop() - full_text_response = '' - for chunk in chat_response: + raise gr.Error(chunk['error'], duration=None) - full_text_response += chunk['content'] + full_response += chunk['content'] - yield { - 'role': 'assistant', - 'content': full_text_response - } + yield chat_history + [{'role': 'user', 'content': user_message}, + {'role': 'assistant', 'content': full_response}] def _create_retrieved_docs_representation(self) -> gr.Markdown: """Concatenates the documents retrieved till now and returns their Markdown repr.""" @@ -154,3 +134,38 @@ def _create_retrieved_docs_representation(self) -> gr.Markdown: for i, repr in enumerate(retrieval_history_reprs)) return gr.Markdown('\n---\n'.join(docs_list_repr)) + + def _move_user_msg_to_chat(self, + user_message: str, + chat_history: utils.UnstructuredChatHistory | None, + ) -> tuple[str, utils.UnstructuredChatHistory]: + """Migrates the submitted user message to the chat history and resets the msg input.""" + + chat_history = chat_history or [] + + return '', chat_history + [{'role': 'user', 'content': user_message}] + + def _retrieve_and_store_docs(self, + chat_history: utils.UnstructuredChatHistory, + ) -> None: + """Retrieves context documents and stores them internally.""" + + chat_history, user_message = chat_history[:-1], chat_history[-1]['content'] + + gr.Info('Collecting context documents...', duration=5) + + try: + context_docs = self._context_retriever_service.collect_context_info( + user_message=user_message, + chat_history=utils.ChatHistory( + [utils.ChatMessage(message['role'], message['content']) + for message in chat_history] + ) + ) + + except requests.HTTPError as e: + _logger().error('Failed to collect context info from backend: %s', e) + + raise gr.Error('Failed to collect context info from backend.', duration=None) + + self._documents_retrieval_history.append(context_docs) From 7ffa4ceb93d9984ecccd8b71110da9115d7cc276 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 13:33:16 +0000 Subject: [PATCH 091/108] Add user message validation to application --- .../web-app/src/web_app/backend/llm_proxy.py | 59 +++++++++++++++++++ services/web-app/src/web_app/backend/utils.py | 8 +++ .../src/web_app/gui/main_controller.py | 40 +++++++++++++ 3 files changed, 107 insertions(+) diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index 5733d8c..b43b49b 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -56,3 +56,62 @@ def stream_chat_response(self, timeout=self._endpoint_cfg.connection_timeout) as stream: for chunk in stream.iter_bytes(): yield json.loads(chunk.decode('utf-8')) + + def check_input_safety(self, + user_message: str, + chat_history: utils.ChatHistory, + ) -> utils.InputCheckResult: + """Sends the conversation state to the llm-proxy to check input safety. + + Raises: + httpx.HTTPStatusError: If the request to the llm-proxy fails. + """ + + _logger().debug(('Checking input safety with user_message: %s, chat_history: %s'), + user_message, chat_history) + + return self._sanitize_input( + user_message=user_message, + chat_history=chat_history, + url=f"{self._endpoint_cfg.url}/check_input_safety" + ) + + def check_input_relevance(self, + user_message: str, + chat_history: utils.ChatHistory, + ) -> utils.InputCheckResult: + """Sends the conversation state to the llm-proxy to check input relevance. + + Raises: + httpx.HTTPStatusError: If the request to the llm-proxy fails. + """ + + _logger().debug(('Checking input relevance with user_message: %s, chat_history: %s'), + user_message, chat_history) + + return self._sanitize_input( + user_message=user_message, + chat_history=chat_history, + url=f"{self._endpoint_cfg.url}/check_input_relevance" + ) + + def _sanitize_input(self, + user_message: str, + chat_history: utils.ChatHistory, + url: str, + ) -> utils.InputCheckResult: + """Sends the conversations state to a chosen llm-proxy guardrail endpoints.""" + + payload = { + 'user_message': user_message, + 'chat_history': utils.chat_history_to_payload(chat_history) + } + + response = httpx.post(url, + json=payload, + timeout=self._endpoint_cfg.connection_timeout) + + response.raise_for_status() + + resp_json = response.json() + return utils.InputCheckResult(is_ok=resp_json['is_ok'], reason=resp_json['reason']) diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index d0d4e39..5df03e8 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -36,6 +36,14 @@ class ContextDocument: metadata: dict[str, Any] +@dataclasses.dataclass +class InputCheckResult: + """Result of input safety, or relevance check.""" + + is_ok: bool + reason: str | None = None + + UnstructuredChatHistory: TypeAlias = list[dict[str, str]] UnstructuredContextDocs: TypeAlias = list[dict[str, Any]] diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 646baea..9e1c9e7 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -75,6 +75,8 @@ def render_gui(self) -> None: msg.submit( # pylint: disable=no-member self._move_user_msg_to_chat, [msg, chatbot], [msg, chatbot] + ).success( + self._validate_user_msg, chatbot, chatbot ).success( self._retrieve_and_store_docs, chatbot, None ).success( @@ -169,3 +171,41 @@ def _retrieve_and_store_docs(self, raise gr.Error('Failed to collect context info from backend.', duration=None) self._documents_retrieval_history.append(context_docs) + + def _validate_user_msg(self, + chat_history: utils.UnstructuredChatHistory, + ) -> Iterator[utils.UnstructuredChatHistory]: + """Validates the user message for safety and relevance.""" + + chat_history, user_message = chat_history[:-1], chat_history[-1]['content'] + + structured_history = utils.ChatHistory( + [utils.ChatMessage(message['role'], message['content']) + for message in chat_history] + ) + + gr.Info('Validating user message...', duration=5) + + try: + safety_check = self._llm_proxy_service.check_input_safety( + user_message, structured_history) + + if not safety_check.is_ok: + yield chat_history + raise gr.Error(f'Input Safety Check Failed: {safety_check.reason}', + duration=None) + + relevance_check = self._llm_proxy_service.check_input_relevance( + user_message, structured_history) + + if not relevance_check.is_ok: + yield chat_history + raise gr.Error(f'Input Relevance Check Failed: {relevance_check.reason}', + duration=None) + + except requests.HTTPError as e: + _logger().error('Failed to validate user message from backend: %s', e) + + raise gr.Error('Failed to validate user message from backend.', duration=None) + + yield chat_history + [{'role': 'user', 'content': user_message}] From 984d6273ff0a6e5067e47cf90794e90dbc4e923d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 14:47:17 +0000 Subject: [PATCH 092/108] Fix showing error messages for invalid user queries --- .../web-app/src/web_app/backend/llm_proxy.py | 16 +++++++++++----- .../web-app/src/web_app/gui/main_controller.py | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index b43b49b..15d9af4 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -2,6 +2,7 @@ import json import logging from typing import Iterator +import requests import httpx from web_app.backend import utils @@ -64,7 +65,7 @@ def check_input_safety(self, """Sends the conversation state to the llm-proxy to check input safety. Raises: - httpx.HTTPStatusError: If the request to the llm-proxy fails. + requests.HTTPError: If the request to the llm-proxy fails. """ _logger().debug(('Checking input safety with user_message: %s, chat_history: %s'), @@ -83,7 +84,7 @@ def check_input_relevance(self, """Sends the conversation state to the llm-proxy to check input relevance. Raises: - httpx.HTTPStatusError: If the request to the llm-proxy fails. + requests.HTTPError: If the request to the llm-proxy fails. """ _logger().debug(('Checking input relevance with user_message: %s, chat_history: %s'), @@ -107,9 +108,14 @@ def _sanitize_input(self, 'chat_history': utils.chat_history_to_payload(chat_history) } - response = httpx.post(url, - json=payload, - timeout=self._endpoint_cfg.connection_timeout) + try: + response = requests.post(url, + json=payload, + timeout=self._endpoint_cfg.connection_timeout) + + except requests.exceptions.ConnectionError as e: + _logger().error('Connection error while connecting to llm-proxy: %s', e) + raise requests.HTTPError('Connection error while connecting to llm-proxy.') from e response.raise_for_status() diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 9e1c9e7..a329eb0 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -204,8 +204,8 @@ def _validate_user_msg(self, duration=None) except requests.HTTPError as e: - _logger().error('Failed to validate user message from backend: %s', e) + _logger().error('Failed to validate user message: %s', e) - raise gr.Error('Failed to validate user message from backend.', duration=None) + raise gr.Error('Failure while validating user message.', duration=None) yield chat_history + [{'role': 'user', 'content': user_message}] From ea7ffb90647842af5f526d9d29252ae36da7fb2d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 16:56:44 +0000 Subject: [PATCH 093/108] Add support for uploading PDF files --- .devcontainer/web-app/Dockerfile | 3 +- services/web-app/pyproject.toml | 3 +- .../src/web_app/backend/context_retriever.py | 46 +++++++++++++++++++ .../src/web_app/gui/main_controller.py | 27 ++++++++++- services/web-app/uv.lock | 11 +++++ services/web-app/web-app.Dockerfile | 2 +- 6 files changed, 88 insertions(+), 4 deletions(-) diff --git a/.devcontainer/web-app/Dockerfile b/.devcontainer/web-app/Dockerfile index a66e5dd..1572246 100644 --- a/.devcontainer/web-app/Dockerfile +++ b/.devcontainer/web-app/Dockerfile @@ -10,7 +10,8 @@ RUN apt-get update && \ git \ openssh-client \ sudo \ - just + just \ + libmagic1 RUN groupadd -g 1000 appuser && useradd appuser -u 1000 -g 1000 -m -s /bin/bash RUN chown -R appuser:appuser /home/appuser/ diff --git a/services/web-app/pyproject.toml b/services/web-app/pyproject.toml index 8b5f97a..5f376f7 100644 --- a/services/web-app/pyproject.toml +++ b/services/web-app/pyproject.toml @@ -19,5 +19,6 @@ dev = [ "pylint>=4.0.4", "autopep8>=2.3.2", "mypy>=1.19.0", - "pre-commit>=4.5.0" + "pre-commit>=4.5.0", + "python-magic>=0.4.27" ] diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index 80ef611..fc0a0da 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -2,6 +2,9 @@ import logging import requests + +import magic + from web_app.backend import utils @@ -48,3 +51,46 @@ def collect_context_info(self, return [utils.ContextDocument(doc['content'], doc['metadata']) for doc in response_data['context_docs']] + + def upload_file(self, + uploaded_file_path: str) -> str | None: + """Sends a file to the context retriever service for processing. + + Raises: + requests.HTTPError: If the request to the backend fails. + + Returns: + None, if the upload was successful, or an error message string if there was an error. + """ + + _logger().debug('Uploading file %s to context retriever service.', uploaded_file_path) + + mime = magic.from_file(uploaded_file_path, mime=True) + + if mime == 'application/pdf': + url = f"{self._endpoint_cfg.url}/upload_pdf" + + else: + return 'Only PDF files are supported.' + + try: + with open(uploaded_file_path, 'rb') as file: + response = requests.post( + url, + files={'file': (uploaded_file_path, file, mime)}, + timeout=self._endpoint_cfg.connection_timeout + ) + + except requests.exceptions.ConnectionError as e: + _logger().error('Connection error while uploading PDF file to context retriever: %s', e) + raise requests.HTTPError( + 'Connection error while uploading PDF file to context retriever.') from e + + response.raise_for_status() + + response_data = response.json() + + if response_data['error'] is not None: + return str(response_data['error']) + + return None diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index a329eb0..720497b 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -1,10 +1,10 @@ """Contains GUI related utils.""" import logging -from typing import Any from typing import Iterator import requests import gradio as gr + from web_app.backend import context_retriever from web_app.backend import llm_proxy from web_app.backend import utils @@ -50,6 +50,12 @@ def render_gui(self) -> None: """ ) + file_upload = gr.File(label='Upload Files for Context') + + file_upload.upload( # pylint: disable=no-member + self._upload_file, file_upload, file_upload, + ) + gr.Markdown( """ ## Retrieved Documents @@ -209,3 +215,22 @@ def _validate_user_msg(self, raise gr.Error('Failure while validating user message.', duration=None) yield chat_history + [{'role': 'user', 'content': user_message}] + + def _upload_file(self, + uploaded_file_path: str) -> None: + """Uploads a file to the context retriever service.""" + + try: + upload_error = self._context_retriever_service.upload_file(uploaded_file_path) + + except requests.HTTPError as e: + _logger().error('Failed to upload file to context retriever: %s', e) + + raise gr.Error('Failed to upload a file.', duration=None) + + if upload_error is not None: + _logger().error('Failed to upload file to context retriever: %s', upload_error) + + raise gr.Error(f'Failed to upload file: {upload_error}', duration=None) + + gr.Success('File uploaded successfully!', duration=5) diff --git a/services/web-app/uv.lock b/services/web-app/uv.lock index fb6b205..1d4403c 100644 --- a/services/web-app/uv.lock +++ b/services/web-app/uv.lock @@ -1076,6 +1076,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "python-magic" +version = "0.4.27" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/db/0b3e28ac047452d079d375ec6798bf76a036a08182dbb39ed38116a49130/python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b", size = 14677, upload-time = "2022-06-07T20:16:59.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/73/9f872cb81fc5c3bb48f7227872c28975f998f3e7c2b1c16e95e6432bbb90/python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3", size = 13840, upload-time = "2022-06-07T20:16:57.763Z" }, +] + [[package]] name = "python-multipart" version = "0.0.20" @@ -1377,6 +1386,7 @@ dev = [ { name = "mypy" }, { name = "pre-commit" }, { name = "pylint" }, + { name = "python-magic" }, { name = "uvicorn" }, ] @@ -1389,6 +1399,7 @@ requires-dist = [ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, + { name = "python-magic", marker = "extra == 'dev'", specifier = ">=0.4.27" }, { name = "requests", specifier = "==2.32.3" }, { name = "uvicorn", marker = "extra == 'dev'", specifier = "==0.34.3" }, ] diff --git a/services/web-app/web-app.Dockerfile b/services/web-app/web-app.Dockerfile index ad9f1f0..9d5adcc 100644 --- a/services/web-app/web-app.Dockerfile +++ b/services/web-app/web-app.Dockerfile @@ -4,7 +4,7 @@ SHELL ["/bin/bash", "-c"] ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install -y --no-install-recommends wget + apt-get install -y --no-install-recommends wget libmagic1 RUN wget -qO- https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh From 036106ececabd229843d221ab620ecf526f4fe02 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:13:49 +0000 Subject: [PATCH 094/108] Improved error gradio messages content --- .../web-app/src/web_app/gui/main_controller.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 720497b..49df799 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -117,7 +117,9 @@ def _stream_chat_response(self, yield chat_history self._documents_retrieval_history.pop() - raise gr.Error(chunk['error'], duration=None) + raise gr.Error(chunk['error'], + title='Error while generating chat response', + duration=None) full_response += chunk['content'] @@ -198,7 +200,8 @@ def _validate_user_msg(self, if not safety_check.is_ok: yield chat_history - raise gr.Error(f'Input Safety Check Failed: {safety_check.reason}', + raise gr.Error(safety_check.reason, + title='Input Safety Check Failed', duration=None) relevance_check = self._llm_proxy_service.check_input_relevance( @@ -206,7 +209,8 @@ def _validate_user_msg(self, if not relevance_check.is_ok: yield chat_history - raise gr.Error(f'Input Relevance Check Failed: {relevance_check.reason}', + raise gr.Error(relevance_check.reason, + title='Input Relevance Check Failed', duration=None) except requests.HTTPError as e: @@ -231,6 +235,8 @@ def _upload_file(self, if upload_error is not None: _logger().error('Failed to upload file to context retriever: %s', upload_error) - raise gr.Error(f'Failed to upload file: {upload_error}', duration=None) + raise gr.Error(upload_error, + title='Failed to upload a file', + duration=None) gr.Success('File uploaded successfully!', duration=5) From 529d756c146a191d1ad680d792e311d90741457d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:14:27 +0000 Subject: [PATCH 095/108] Add small updates to dev configuration --- services/web-app/main_dev.py | 8 ++++++-- services/web-app/mock_backend.py | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 8966915..8604bfa 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -25,9 +25,13 @@ def _logger() -> logging.Logger: 'version': 1, 'loggers': { 'root': { - 'level': 'NOTSET', + 'level': 'WARNING', + 'handlers': ['console'] + }, + 'web_app': { + 'level': 'DEBUG', 'handlers': ['console'], - 'propagate': True + 'propagate': False } }, 'handlers': { diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index ddcc515..855b904 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -131,6 +131,9 @@ class ResponseUploadDocument(pydantic.BaseModel): @app.post('/upload_pdf') async def upload_pdf(file: fastapi.UploadFile) -> ResponseUploadDocument: + if not file.filename.lower().endswith('.pdf'): + return ResponseUploadDocument(error='Only PDF files are supported.') + return ResponseUploadDocument() From f4405a160c422bf2cb61785eacc38841d998d77e Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:16:06 +0000 Subject: [PATCH 096/108] Apply pre-commit checks --- services/web-app/main_dev.py | 2 +- services/web-app/mock_backend.py | 2 +- services/web-app/src/web_app/backend/context_retriever.py | 4 +--- services/web-app/src/web_app/backend/llm_proxy.py | 2 +- services/web-app/src/web_app/backend/utils.py | 4 ++-- services/web-app/src/web_app/gui/main_controller.py | 3 +-- services/web-app/web-app.Dockerfile | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/services/web-app/main_dev.py b/services/web-app/main_dev.py index 8604bfa..2fa0eac 100644 --- a/services/web-app/main_dev.py +++ b/services/web-app/main_dev.py @@ -6,9 +6,9 @@ import omegaconf from web_app.backend import context_retriever from web_app.backend import llm_proxy +from web_app.backend import utils as backend_utils from web_app.gui import main_controller from web_app.gui import utils as gui_utils -from web_app.backend import utils as backend_utils def _logger() -> logging.Logger: diff --git a/services/web-app/mock_backend.py b/services/web-app/mock_backend.py index 855b904..afb0059 100644 --- a/services/web-app/mock_backend.py +++ b/services/web-app/mock_backend.py @@ -8,11 +8,11 @@ from typing import Dict from typing import List +import fastapi import hydra import omegaconf import pydantic import uvicorn -import fastapi from fastapi.responses import StreamingResponse diff --git a/services/web-app/src/web_app/backend/context_retriever.py b/services/web-app/src/web_app/backend/context_retriever.py index fc0a0da..51de377 100644 --- a/services/web-app/src/web_app/backend/context_retriever.py +++ b/services/web-app/src/web_app/backend/context_retriever.py @@ -1,10 +1,8 @@ """Contains implementation of service that communicates with the context retriever module.""" import logging -import requests - import magic - +import requests from web_app.backend import utils diff --git a/services/web-app/src/web_app/backend/llm_proxy.py b/services/web-app/src/web_app/backend/llm_proxy.py index 15d9af4..287eda9 100644 --- a/services/web-app/src/web_app/backend/llm_proxy.py +++ b/services/web-app/src/web_app/backend/llm_proxy.py @@ -2,9 +2,9 @@ import json import logging from typing import Iterator -import requests import httpx +import requests from web_app.backend import utils diff --git a/services/web-app/src/web_app/backend/utils.py b/services/web-app/src/web_app/backend/utils.py index 5df03e8..cf05eeb 100644 --- a/services/web-app/src/web_app/backend/utils.py +++ b/services/web-app/src/web_app/backend/utils.py @@ -1,7 +1,7 @@ """Contains utilities used by the backend services.""" import dataclasses -from typing import TypeAlias from typing import Any +from typing import TypeAlias import pydantic @@ -41,7 +41,7 @@ class InputCheckResult: """Result of input safety, or relevance check.""" is_ok: bool - reason: str | None = None + reason: str UnstructuredChatHistory: TypeAlias = list[dict[str, str]] diff --git a/services/web-app/src/web_app/gui/main_controller.py b/services/web-app/src/web_app/gui/main_controller.py index 49df799..3657999 100644 --- a/services/web-app/src/web_app/gui/main_controller.py +++ b/services/web-app/src/web_app/gui/main_controller.py @@ -1,10 +1,9 @@ """Contains GUI related utils.""" import logging from typing import Iterator -import requests import gradio as gr - +import requests from web_app.backend import context_retriever from web_app.backend import llm_proxy from web_app.backend import utils diff --git a/services/web-app/web-app.Dockerfile b/services/web-app/web-app.Dockerfile index 9d5adcc..3293dcd 100644 --- a/services/web-app/web-app.Dockerfile +++ b/services/web-app/web-app.Dockerfile @@ -16,4 +16,4 @@ WORKDIR /app EXPOSE ${WEB_APP_PORT} RUN uv python install 3.12 && uv venv && uv pip install . -CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file +CMD [ "uv", "run", "python", "main.py" ] From d759eb5b993633466d7e7648eb6a2de9dcfb5ebe Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:39:27 +0000 Subject: [PATCH 097/108] Move python-magic from dev to standard web app deps --- services/web-app/pyproject.toml | 6 +++--- services/web-app/uv.lock | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/web-app/pyproject.toml b/services/web-app/pyproject.toml index 5f376f7..81d5845 100644 --- a/services/web-app/pyproject.toml +++ b/services/web-app/pyproject.toml @@ -9,7 +9,8 @@ requires-python=">=3.12" dependencies = [ "gradio==5.33.0", "hydra-core==1.3.2", - "requests==2.32.3" + "requests==2.32.3", + "python-magic>=0.4.27" ] [project.optional-dependencies] @@ -19,6 +20,5 @@ dev = [ "pylint>=4.0.4", "autopep8>=2.3.2", "mypy>=1.19.0", - "pre-commit>=4.5.0", - "python-magic>=0.4.27" + "pre-commit>=4.5.0" ] diff --git a/services/web-app/uv.lock b/services/web-app/uv.lock index 1d4403c..548335c 100644 --- a/services/web-app/uv.lock +++ b/services/web-app/uv.lock @@ -1376,6 +1376,7 @@ source = { editable = "." } dependencies = [ { name = "gradio" }, { name = "hydra-core" }, + { name = "python-magic" }, { name = "requests" }, ] @@ -1386,7 +1387,6 @@ dev = [ { name = "mypy" }, { name = "pre-commit" }, { name = "pylint" }, - { name = "python-magic" }, { name = "uvicorn" }, ] @@ -1399,7 +1399,7 @@ requires-dist = [ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.19.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.5.0" }, { name = "pylint", marker = "extra == 'dev'", specifier = ">=4.0.4" }, - { name = "python-magic", marker = "extra == 'dev'", specifier = ">=0.4.27" }, + { name = "python-magic", specifier = ">=0.4.27" }, { name = "requests", specifier = "==2.32.3" }, { name = "uvicorn", marker = "extra == 'dev'", specifier = "==0.34.3" }, ] From 3aa58f10ae0c02bef6c2643363a4ba2eef27cfc2 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:39:55 +0000 Subject: [PATCH 098/108] Change error message function for invalid guard-llm responses --- services/llm-proxy/src/llm_proxy/llm_actions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py index de94081..0fe2adf 100644 --- a/services/llm-proxy/src/llm_proxy/llm_actions.py +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -121,7 +121,9 @@ async def run(self, _logger().debug('Validation LLM raw response:\n%s', decision) if len(decision_lines) != 2: - return False, 'Validation LLM returned an invalid response format.' + _logger().error('Unexpected number of lines in validation response: %d', + len(decision_lines)) + return False, 'Internal system error during conversation validation.' if decision_lines[0].lower() == self._good_keyword.lower(): return True, None From 2a88ba5f56e3d8bf0294b6f5d7f2491ff318f366 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:40:06 +0000 Subject: [PATCH 099/108] Change default chunking params --- services/context-retriever/cfg/main.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/context-retriever/cfg/main.yaml b/services/context-retriever/cfg/main.yaml index 4b03dcb..968bf11 100644 --- a/services/context-retriever/cfg/main.yaml +++ b/services/context-retriever/cfg/main.yaml @@ -4,8 +4,8 @@ server_port: 8899 n_server_workers: 1 persist_data_path: data/ doc_processing: - chunk_size: 2000 - chunk_overlap: 400 + chunk_size: 1000 + chunk_overlap: 200 doc_retrieval: max_context_docs: 3 similarity_threshold: 0.6 From bc1e9c5013dc0b79ad31c92dccf783a2c2617315 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 9 Jan 2026 17:41:49 +0000 Subject: [PATCH 100/108] Apply pre-commit checks --- services/context-retriever/context-retriever.Dockerfile | 2 +- services/llm-proxy/cfg/main-dev.yaml | 2 +- services/llm-proxy/cfg/main.yaml | 2 +- services/llm-proxy/llm-proxy.Dockerfile | 2 +- services/llm-proxy/src/llm_proxy/llm_actions.py | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/context-retriever/context-retriever.Dockerfile b/services/context-retriever/context-retriever.Dockerfile index 0c79799..3e726b6 100644 --- a/services/context-retriever/context-retriever.Dockerfile +++ b/services/context-retriever/context-retriever.Dockerfile @@ -16,4 +16,4 @@ WORKDIR /app EXPOSE ${API_PORT} RUN uv python install 3.12 && uv venv && uv pip install . -CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file +CMD [ "uv", "run", "python", "main.py" ] diff --git a/services/llm-proxy/cfg/main-dev.yaml b/services/llm-proxy/cfg/main-dev.yaml index 47ae21c..0ec3e7e 100644 --- a/services/llm-proxy/cfg/main-dev.yaml +++ b/services/llm-proxy/cfg/main-dev.yaml @@ -14,4 +14,4 @@ models: input_relevance_guardrail: model: local_ollama_model - base_url: http://localhost:11435 \ No newline at end of file + base_url: http://localhost:11435 diff --git a/services/llm-proxy/cfg/main.yaml b/services/llm-proxy/cfg/main.yaml index 312a5d0..43df3b4 100644 --- a/services/llm-proxy/cfg/main.yaml +++ b/services/llm-proxy/cfg/main.yaml @@ -14,4 +14,4 @@ models: input_relevance_guardrail: model: local_ollama_model - base_url: http://guard-llm:11435 \ No newline at end of file + base_url: http://guard-llm:11435 diff --git a/services/llm-proxy/llm-proxy.Dockerfile b/services/llm-proxy/llm-proxy.Dockerfile index 0c79799..3e726b6 100644 --- a/services/llm-proxy/llm-proxy.Dockerfile +++ b/services/llm-proxy/llm-proxy.Dockerfile @@ -16,4 +16,4 @@ WORKDIR /app EXPOSE ${API_PORT} RUN uv python install 3.12 && uv venv && uv pip install . -CMD [ "uv", "run", "python", "main.py" ] \ No newline at end of file +CMD [ "uv", "run", "python", "main.py" ] diff --git a/services/llm-proxy/src/llm_proxy/llm_actions.py b/services/llm-proxy/src/llm_proxy/llm_actions.py index 0fe2adf..39b7cc3 100644 --- a/services/llm-proxy/src/llm_proxy/llm_actions.py +++ b/services/llm-proxy/src/llm_proxy/llm_actions.py @@ -1,7 +1,7 @@ """Contains modules performing LLM-related isolated actions.""" +import logging from typing import Any from typing import AsyncIterator -import logging from langchain_core.language_models.chat_models import BaseChatModel from langchain_core.messages import AIMessage @@ -122,7 +122,7 @@ async def run(self, if len(decision_lines) != 2: _logger().error('Unexpected number of lines in validation response: %d', - len(decision_lines)) + len(decision_lines)) return False, 'Internal system error during conversation validation.' if decision_lines[0].lower() == self._good_keyword.lower(): From e5e21ef6907e1146e8d56c1f2e92516356e4efb1 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 12:48:21 +0100 Subject: [PATCH 101/108] Move pre-commit action to a separate file --- .../run-precommit-for-service/action.yml | 37 ++++++++++++++++ .github/workflows/service-checks.yml | 44 ++++++++----------- 2 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 .github/actions/run-precommit-for-service/action.yml diff --git a/.github/actions/run-precommit-for-service/action.yml b/.github/actions/run-precommit-for-service/action.yml new file mode 100644 index 0000000..6bf82b4 --- /dev/null +++ b/.github/actions/run-precommit-for-service/action.yml @@ -0,0 +1,37 @@ +--- +name: Run Pre-commit for Service +description: Set up a Dev-Container for a specific service and run pre-commit checks within that environment. + +inputs: + devcontainer-cfg-path: + description: Directory containing .devcontainer configuration for the service. + required: true + + service-workdir: + description: Working directory inside the Dev-Container where the service code resides. + required: true + +runs: + using: composite + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Verify Docker engine + run: docker version + + - name: Ensure SSH agent mount path exists + run: | + if [ ! -e "${SSH_AUTH_SOCK}" ]; then + touch "${SSH_AUTH_SOCK}" + fi + + - name: Run pre-commit in devcontainer + uses: devcontainers/ci@v0.3 + with: + configFile: ${{ inputs.devcontainer-cfg-path }}/devcontainer.json + runCmd: | + bash -lc "cd ${{ inputs.service-workdir }} && \ + just setup-environment && \ + just run-precommit \ No newline at end of file diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 8e62a62..a081f2d 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -40,6 +40,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Determine impacted services id: filter uses: dorny/paths-filter@v3 @@ -72,41 +73,34 @@ jobs: runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.context-retriever == 'true' - env: - DEVCONTAINER_CONFIG: .devcontainer/context-retriever/devcontainer.json - SERVICE_WORKDIR: /home/appuser/workspace/services/context-retriever - steps: &precommit_steps - - name: Checkout repository - uses: actions/checkout@v4 - - name: Verify Docker engine - run: docker version - - name: Ensure SSH agent mount path exists - run: | - if [ ! -e "${SSH_AUTH_SOCK}" ]; then - touch "${SSH_AUTH_SOCK}" - fi - - name: Run pre-commit in devcontainer - uses: devcontainers/ci@v0.3 + steps: + - name: Run pre-commit for context-retriever + uses: ./.github/actions/run-precommit-for-service with: - configFile: ${{ env.DEVCONTAINER_CONFIG }} - runCmd: bash -lc "cd ${{ env.SERVICE_WORKDIR }} && ${{ env.PRECOMMIT_CMD }}" + devcontainer-cfg-path: .devcontainer/context-retriever + service-workdir: /home/appuser/workspace/services/context-retriever + precommit-web-app: name: Pre-commit (web-app) runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.web-app == 'true' - env: - DEVCONTAINER_CONFIG: .devcontainer/web-app/devcontainer.json - SERVICE_WORKDIR: /home/appuser/workspace/services/web-app - steps: *precommit_steps + steps: + - name: Run pre-commit for web-app + uses: ./.github/actions/run-precommit-for-service + with: + devcontainer-cfg-path: .devcontainer/web-app + service-workdir: /home/appuser/workspace/services/web-app precommit-llm-proxy: name: Pre-commit (llm-proxy) runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.llm-proxy == 'true' - env: - DEVCONTAINER_CONFIG: .devcontainer/llm-proxy/devcontainer.json - SERVICE_WORKDIR: /home/appuser/workspace/services/llm-proxy - steps: *precommit_steps + steps: + - name: Run pre-commit for llm-proxy + uses: ./.github/actions/run-precommit-for-service + with: + devcontainer-cfg-path: .devcontainer/llm-proxy + service-workdir: /home/appuser/workspace/services/llm-proxy From ca633538e420690f7089c632fc6c2458ac17fe88 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 12:49:11 +0100 Subject: [PATCH 102/108] Modify service-checks config Added new firing rules Added workflow cancelling rules Added specific version of 'runs-on' image --- .github/workflows/service-checks.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index a081f2d..96c5255 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -1,4 +1,5 @@ name: Service Checks +description: Run pre-commit static analysis on services having their own Dev-Container setup. on: pull_request: @@ -10,27 +11,24 @@ on: - services/web-app/** - services/llm-proxy/** - .devcontainer/** - push: - paths: - - .github/workflows/service-checks.yml - - .pre-commit-config.yaml - - pyproject.toml - - services/context-retriever/** - - services/web-app/** - - services/llm-proxy/** - - .devcontainer/** + branches: [main, develop] permissions: contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: - PRECOMMIT_CMD: just setup-environment && just run-precommit + # Dummy socket to simulate mounting SSH agent into Dev-Container SSH_AUTH_SOCK: /tmp/ssh-agent jobs: changes: name: Detect changed services - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: context-retriever: ${{ steps.filter.outputs.context-retriever }} web-app: ${{ steps.filter.outputs.web-app }} @@ -70,7 +68,7 @@ jobs: precommit-context-retriever: name: Pre-commit (context-retriever) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: changes if: needs.changes.outputs.context-retriever == 'true' steps: @@ -83,7 +81,7 @@ jobs: precommit-web-app: name: Pre-commit (web-app) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: changes if: needs.changes.outputs.web-app == 'true' steps: @@ -95,7 +93,7 @@ jobs: precommit-llm-proxy: name: Pre-commit (llm-proxy) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: changes if: needs.changes.outputs.llm-proxy == 'true' steps: From bf706b6a94665aff1276391cc2bd261f095c10cb Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 12:53:05 +0100 Subject: [PATCH 103/108] Fix problem with not checked-out repo for pre-commit action --- .github/actions/run-precommit-for-service/action.yml | 3 --- .github/workflows/service-checks.yml | 9 +++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/actions/run-precommit-for-service/action.yml b/.github/actions/run-precommit-for-service/action.yml index 6bf82b4..ceac562 100644 --- a/.github/actions/run-precommit-for-service/action.yml +++ b/.github/actions/run-precommit-for-service/action.yml @@ -15,9 +15,6 @@ runs: using: composite steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Verify Docker engine run: docker version diff --git a/.github/workflows/service-checks.yml b/.github/workflows/service-checks.yml index 96c5255..26d5562 100644 --- a/.github/workflows/service-checks.yml +++ b/.github/workflows/service-checks.yml @@ -72,6 +72,9 @@ jobs: needs: changes if: needs.changes.outputs.context-retriever == 'true' steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run pre-commit for context-retriever uses: ./.github/actions/run-precommit-for-service with: @@ -85,6 +88,9 @@ jobs: needs: changes if: needs.changes.outputs.web-app == 'true' steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run pre-commit for web-app uses: ./.github/actions/run-precommit-for-service with: @@ -97,6 +103,9 @@ jobs: needs: changes if: needs.changes.outputs.llm-proxy == 'true' steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run pre-commit for llm-proxy uses: ./.github/actions/run-precommit-for-service with: From 3bb66f7af47c250e28e16cf5a09661ade69f091d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 12:55:29 +0100 Subject: [PATCH 104/108] Add bash as the shell for creating ssh auth sock --- .github/actions/run-precommit-for-service/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/run-precommit-for-service/action.yml b/.github/actions/run-precommit-for-service/action.yml index ceac562..a79c1da 100644 --- a/.github/actions/run-precommit-for-service/action.yml +++ b/.github/actions/run-precommit-for-service/action.yml @@ -23,6 +23,7 @@ runs: if [ ! -e "${SSH_AUTH_SOCK}" ]; then touch "${SSH_AUTH_SOCK}" fi + shell: bash - name: Run pre-commit in devcontainer uses: devcontainers/ci@v0.3 From b16ea47c2ccac01131bb2885d096f67a30f3f560 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 12:56:50 +0100 Subject: [PATCH 105/108] Up --- .github/actions/run-precommit-for-service/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/run-precommit-for-service/action.yml b/.github/actions/run-precommit-for-service/action.yml index a79c1da..4780da4 100644 --- a/.github/actions/run-precommit-for-service/action.yml +++ b/.github/actions/run-precommit-for-service/action.yml @@ -17,6 +17,7 @@ runs: steps: - name: Verify Docker engine run: docker version + shell: bash - name: Ensure SSH agent mount path exists run: | From 63b86566eae52fcb710b57b1d85ddad624c83c8b Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sat, 10 Jan 2026 13:00:38 +0100 Subject: [PATCH 106/108] Up --- .github/actions/run-precommit-for-service/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/run-precommit-for-service/action.yml b/.github/actions/run-precommit-for-service/action.yml index 4780da4..d47e76c 100644 --- a/.github/actions/run-precommit-for-service/action.yml +++ b/.github/actions/run-precommit-for-service/action.yml @@ -31,6 +31,6 @@ runs: with: configFile: ${{ inputs.devcontainer-cfg-path }}/devcontainer.json runCmd: | - bash -lc "cd ${{ inputs.service-workdir }} && \ + cd ${{ inputs.service-workdir }} && \ just setup-environment && \ just run-precommit \ No newline at end of file From 68fe19908ed68a09dfa983edbc963bf6ac0db8ba Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 11 Jan 2026 11:39:58 +0100 Subject: [PATCH 107/108] Update README Added system overview and modules description Added setup info --- README.md | 82 +++++++++++++++++++++---------- doc/context-retriever.drawio.png | Bin 0 -> 98961 bytes doc/llm-proxy.drawio.png | Bin 0 -> 60516 bytes doc/system-overview.drawio.png | Bin 0 -> 125376 bytes doc/web-app-screen.png | Bin 0 -> 216585 bytes 5 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 doc/context-retriever.drawio.png create mode 100644 doc/llm-proxy.drawio.png create mode 100644 doc/system-overview.drawio.png create mode 100644 doc/web-app-screen.png diff --git a/README.md b/README.md index eece448..3400578 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,74 @@ -# rag-application +# rag-app -This project contains a web application enabling the user to chat with an LLM-based chatbot with access to additional context information, leveraging the RAG paradigm. +This project contains a web application enabling the user to chat with an LLM-based chatbot with access to additional context information, leveraging the RAG paradigm. The chat bot is designed to represent AGH University of Krakow and the entire infrastructure is developed to support self-hosted LLMs for text generation, embeddings or safety checks. The app is a minimal-setup, demonstration application that could be deployed as a tuned assistant chat bot to answer questions regarding the institution, based on internal source of truth. -## Development +## System overview -It is advisable to use the VSCode's Development Container mechanism for development. The default configuration allows to set up a Docker container with all dependencies and functionalities, such as Docker-in-Docker. +The system is a three-level hierarchy: -### Setup +- **Web application** - the only endpoint available to the user. +- **Backend** - isolated environments where the requests are validated and processed +- **Self-hosted endpoints** - LLM and Vector Store endpoints leveraging the internal infrastructure of the institution, e.g. data centers and computation clusters + +![system-overview](./doc/system-overview.drawio.png) + +### Web application + +The implementation of the application is demonstration-purpose. It facilitates two primary interactions: 1. Sending messages to the chat bot, 2. Adding documents to the knowledge base (in production setup, this functionality should require admin privileges). + +The communication with the chatbot follows this lifecycle: +1. The user asks a question. +2. The question is validated with respect to its safety +3. The question is validated with respect to its relevance to the specified list of topics (e.g. preventing the user from asking questions about politics) +4. For the given user message, a set of document chunks is collected from the knowledge store, based on their relevance to the question +5. The message is sent to the main LLM, which responds to the question, based on the conversation history and documents + +![web-app-screen](./doc/web-app-screen.png) -After opening the Devcontainer, it is recommended to use only the setup commands specified in the `justfile`: +### Backend -```bash -just setup-dev -``` +#### llm-proxy -### Running checks +It is responsible for administering the conversation with the chatbot. It is a layer of communication between the web app and the assistant that provides additional validation services. -In order to run unit tests, integration tests and other checks just use one of the pre-made commands, e.g.: +1. Safety check - using a specialized smaller LLM, it checks whether the user query contains harmful/illegal content, responding to which would compromise the institution. +2. Relevance check - it examines the query and checks if it follows one of the specified topics, e.g. the question is about the rules of admission to the university, rather than cooking a perfect pasta. +3. Chat response generation - based on the conversation context and provided documents, it composes a prompt and streams the response of the main LLM. -```bash -just run-pre-commit -``` +![llm-proxy](./doc/llm-proxy.drawio.png) -The commands are configured to be reused by GitHub Actions jobs. +#### context-retriever -## Usage -Prerequisities for using the project outside of the Development Container: -1. `just` - for running the setup scripts defined in the `justfile` -2. `docker-compose` - for running multi-container application +It is responsible for handling IO operations on the internal knowledge base. In particular, it does: -In order to set up the whole system, run: +1. Document uploading - it scopes the file validation, loading, chunking and storing the embedded chunks in a vector store +2. Information Retrieval - the user query is embedded and compared with the stored chunk embedding in order to retrieve the most relevant chunks. +3. Query Reformulation - before embedding the query, it must be reformulated using the helper LLM so that it reflects the context of the conversation, e.g. + - **User:** Hello, my name is Wiktor and I've just graduated from a secondary school in Berlin. **Assistant:** Hello, Wiktor. How can I help you? **User:** How can I apply for the university? + - **Reformulated query:** What are the admission rules for first-degree studies for non-polish students? -```bash -just up-services -``` +![context-retriever](./doc/context-retriever.drawio.png) + +### Self-hosted endpoints + +- **main-llm-responder** - the primary LLM responsible for the generation of responses to the user's messages +- **guard-llm** - specialized at detecting harmful behavior and questions diverging from the expected topics +- **helper-llm** - used during the document retrieval for e.g. query reformulation +- **embedding-endpoint** - embeds the documents to store them in a Vector DB +- **vector-store** - stores the embedded documents together with their metadata and handles distance-based query lookups + +## Development + +It is advisable to use the VSCode's Development Container mechanism for development. The default configuration allows to set up a Docker container with all dependencies and functionalities, such as Docker-in-Docker. + +### Setup -To stop it: +The most important elements of the project structure are: -```bash -just down-services -``` +- `services/` - contains implementations of endpoints being the highest-level modules of the entire system +- `docker-compose.yml` - contains configurations for setting up the endpoints, together with the description of the endpoint-endpoint communication +- `.devcontainer` - contains configuration of the Devcontainers, within which the services are supposed to be developed. It is recommended to use `docker compose` in the `base` devcontainer and develop each service in isolation using its specialized devcontainer ## Changelog diff --git a/doc/context-retriever.drawio.png b/doc/context-retriever.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4adec3ac6d10f789b77bfd72cc364bd3fdb619 GIT binary patch literal 98961 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

tal53;x8Iw)K=3JwwlC{S(i-6b6+jac1N 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 literal 0 HcmV?d00001 diff --git a/doc/llm-proxy.drawio.png b/doc/llm-proxy.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..c71cf35d188cd6781c674d51950b90b4c0c80a2c GIT binary patch literal 60516 zcmeEu1wfTq`nQy%AT6yZAR^sJr$~uNcU&4S-HmiAN=PXxAR!<~cdDdPiZs$)((s*2 zI85y9d^5ZM+1VYJVY%l$Z=I)q&+puz+p-ep(1_8_oH=t&@}}sWGiTuC&YXekML7#b zUJzFfoH?WHZ6~H;XW?XMVh%Y&#VT_27Zs}*6_XGZ3lr>zRm8wV*T_cK0(>wrpkfuJ zVqwu{m3HBfhthM(JJQSFHMcTib-oRT!3;}X3&_!&+qy;&dS=+@>8qVw)51x@M%T(% z25JB?2d5c09i7C*!hUoe1LvawP8QCi0VA7}n;%}2g$XvGVB&IoH)imxu=^X?n;1ZB zkIp@wXa|Lw+nHGXcu*f|X$jG{`_V*Q8yl$OkEa=WTkDf`JiZSVi}?Tlx!+gA24Z>qDu3j1$3l0|HMc)r$0KRl+Bu&r ztRd9WPT}|?GZm|_uDOYkC0HGO@Bk1SFyH{Ou`>aJ5IR0!2eksD`o<>a2GY9DPTBHJJGdc+hS%rmYL%Zn)-dr__UU?vmHI3?y+?keZMx$ z=6;I?fjP$t`0LOA3wp|Nyf&wlgB9kS%*`$6t!$u9;0-yxXXkw4WkCQq9{KKHVKVwnD|)D5zhgyzY^kT$ z_gH678xc$;heFRl4+d7vKzeH&^5Jn?s1r#}g#$F|OWbn}z@ zKn)FTAz=D%GvAZD92)U=zw+zP$13s%OrGoL$$m{6%uNmr>&V)^D*=%BFPPd-EcvH) zYhhwwaHvqnCVm$dIYdG3@>8Q{{bA(JaSVqI*+A`d?R51HBNa>w&2{x4=C`4?CUzz; zA0%pXG*{RPCZa^&~~tD5F10_Lv4>V=2XJ)3!eOYuJD)l z0#*R|Ei(LXiN?ng3=H0;{f^RNbopH{aAwf#t?loZ4*l?dpm7gT|$m@G0Rp+e zMDvdY2(l80gRUh=M*jz8c!DwfXUp)|Q~XGVKe4y}&LUZiLtI=$EC~-TxR|Si0r3f{O@}C5N`Rs{@|qGI(Gd3%su>>1vB%{v9$l9iureY^b-mGLdpC~ z;r!1nnU5dxbTnrXht>LOX!G9-a;(5*XM(t?mLk7$997al`asP^*=#$q%#v8;HKWjV)k?+&Lti9nS;A zHP{mYmcTJz5ymk1HQs*K2wcYN}ZWLhj zFBp5~CwBTP6q;W%g+HQ-rzu8&#L2}3``>R>(Ic1i`xAAxWAOi2MY+N1!$kcf4Luq< zt)M3aKjJ42^zSs`d)S8jkEaQ2 zCve_hD@{0w0lx-N{q2VTb#C}KWvoZ8=YK05_&Z(wMaK8PD_#9F^zbhc_BnnD(D_N& z|Jxz{wH+c0>tCTjItGVNQKx@^YFI^&cZ{7<#pCMWc;DeMXma!k?1!{*RyjtG4nL@# z{vZnL_rQwP!$YF542J#W)2T}QaLSS6fISJA1wI^7D_NL+1l=Fav4z^(9ByO-A5YSZ zqq6d@yvgXkWL_@ z(?U8D++SNrKW9dYz_uv>fW!h~YYW@F4K^tJ@@55?o=d~FZh@6PWojpz$G&eKI>9(k zHX485K6bb(_|!hIALDGlieVmaM?XFp7}2rQ`kATy4(S{>c-c9b7?_v=qRGm}#>K+P zew>6ImoQ*&Fay)6f5)c&=fFijr!y)Xi;T$tqHkgg+gA6}PU`=H^q3Ci#=*kGag0}- z2#@tYNO;GO_Ahml-{aN)btpSFk{@}=LooAq*x`RpC_91V{-rYd9=%{P`u^enAe5b; z%Rds*q2T`7LOOQAr_h?8hq8aXZR>x+AF_V`2dXw$;dbH>IbaU)`#})#jt>7R;f&+> z*-i=a&JVlo{)ZzPHv>2KKZt1TzdarKEk+JYr$7t=-+}YfuSqygHBR*A$7=E){w)a{ zKTmdlmKOcpwfMVhaa;hfoRArgmHjV5Zs7QNHSjYnKUJ>%xaj(u+;GVI`TybB{2_9~ zkxTk5E*a*Gzkij?_phz_3Ay1f0p6VyWBzQ1pGf>Oj}riKYr4q z`7f_^SlNFqQ~vGP&u>wVf0!x%Bzd4eE^1CHs{im*ne*p0n1UVb3y6SHNlVLs-+*~| zsAKShZss%%gPyPE9O!yC}*0F4k)6%2wjAdc^&(f^J{rUgkdsdJ4?o0geg|?@c z#K zZHWkB)UFUM1)Z6clqD!wG zU!L;(9^#dx6i>`91nl#0*j6;~Ga=x)uYy5gxaa2BftK*AlMxLaPc5W5-$%=MuTILv z7h^6+JkczB@HVOmJGJ`t0w?_XO+?X)*TFfp!jcfti##alG7*<^joJ-2cXk43bF-Sx z-6kV|!)5|AFwT;RUff2#oAHnU8Pgm~K_Z;&#yx7875&YnjgEAAayH8ZLiHjBi8NWo z+t0)e-L|KZYx=gvV;1GBJQy&DKB8HCiGDLPUbiq{Ci58yy^#n@xib}s$zd*l+G3$! zKDFh>BA)0_rHs|`sPpdbs>j{z$8elbEl!AG+wKKE*UB*Ku~Pl7Z^Nm>0uJ_f2>sBT z8mbPozP|KFieV1B-Su#GCY8-)9Cf!<|@;wLS%g?9imsdk{@7?Wvm7F3H z5JAseh%wtkU;p)8Jd^vjY=4C-vO?-wU1rXN_=gllCbJ$ZjnXyFiB=L{2F=DN=AU^~ z${hF?hN_JE1}feC-nc2^pyE=qPx2g!v*1m8HYbzwQ5Lj)5QAh?C*+qBxNYH;Uug`}vKV=s z` z_>2%Qpv&_g+fzVpsdyix-#ii0(oZ z5L3L)h=t`7p{0My8{?4+ds6DSNKU{&8i9s?C%&2s{fgv+{{Bxyo)d9KVLCe-LsG+4 zPRlqet@os2+I)qZ6I77Vo;Al%1YS>7PQOjz`YlT&Tg@W7ADJ=rgSr?a{_3shtmTV! z=n?(-q7joM@)F3u;Yoy)Q zOQ4+WdqWppbPY+40$uXK^E0anL2I&9Qqk`dv?_P8l(J&Oe30mL+7j+lhatPXE;LsS zPQ0N^f<+)k(20MB8JNxzIXsTsAZrY9PyjBMo$;i;9u=j($Rb|M@`Vd&GL~zDxg&Jq zc@FdN2JatsIweaBKM`3TRm?N(*61&_uX9p}W=!_p-D-Y}qu*#JHc&eMp={%>+j{qv z-Q_0Ts3ZnWL#9xQA+o_adluhrAw_V z`#ZV?riwVbm@nHBC6K=uE{}HKPL;MOFjs}|&NQkou}!<3qa`snP&T+072i6oYT9eb zbQZ(d5|Q8>5GVS<&JeTHss~LttLHwB;a2B}Q$f{q10gH#eWespR03t#+fstJ)nbby z4mQG7DOthO@~n7^>-*&9^auSEN$sKq-aF5o;25hC$fTl4*-dy0j6XE-UTWg1+uaI? zWH%!hPeySgeg$c+oS-dL&HqLT9lVn&J>O^XA!i5!*O8oN2Y{O17x2bl;EgJJ?&i zhkd_)_A5p_hsBE8S>jlf&1>GqxN?1ERE~`xJ9KiQc&|F;p zI!1BkoHin5@R<#X<#(05&bOWjdfQ+_lpI8>$xzef_+^1JZW1^{TnWW~o3LenUCr*w zowJ&GdInqpu||O z^1?_6<89oq654b0hNE1mq^N5GD0&))Jd;rq$V?OD&SH}FH9nl}ThI2&i$^4b1%``g zu=`vxXSBQ}5^@&4DV(gn@6GDv3J8BF;Q-JC&qI^`tsu|^87Q9tcmqJm{VbOBcF zNTM~#su03(X&U08PK?IuOvw?XTkOTs7beiIU4;b^?3*CW!0Wz$ zh{8+nt?jWzzCJt2Qib1JXrU_g>!Ug6OgzXKee_gF>_97c z5GJ@>*1X=V^#puTESG9`R5hgrD134 z#hj{rWRIc_&Y|6Km-Rv9Di$vy5dIK6p_VIOWn%f=)2RFxblyMoXz{5V37GB8(VhGB zD3;5buQ6g#w^BYKuFjucurZWdQ2tww`XUSJu4*)6?0AJf`#rsm|? zOg`d?yKyT374cKnZXM%wpG$1EUDI&io<@_p!q6B_MwiX6<(?I~dawWL6X5wnf%*Bk zr+AT`3UkAvN%@tDj_&PIWG)$W@JS%Qc$YsZSFu3}zguV-dn8n> zSug*2xu%E%jQw&nKCbJ8TpeFJvsC5k-;|5s@g3~iHX1+&%e!#Y*Q=9_thq?jHA>#; zyG92SWShTVZsx?Lku?kovz?&HKGpXa;C+ozt;jIeS4fr;EY&h)m-hr^Vij4;m zL8SCLAB$b=8!unqW1Y~h3-3O53eb9s$Q2~1aZx24mn`D^;YzC zMHG9A_U(ohJmO(BjtAPAs^(y2dtoI{U)gw+UxmoI1;)%E* zrIZBgOGOL`6zswow(0jjryVC=A{|4kAUo!+2OqPb^eQ0?=J`MdVuX|A&cU(JUt%$O zi7c2f$CP}w%6``WGwvI=EsU@2+8ocXQAdmh!iSS*)%dCtEj#Rdqfg*-#i5bi^=XOI zW*sjkO5DkA2?{~rEXN{Vdqw3>a8bARO2ng4?wC&(Vn5^?@y&hN7~UAxa-k)`QEj&I zj=@rG)D*GWdE&FbpSYR;8L%gvi2?cVTUh=(fty`o+Fyk7Tyho1<6w_T?aeh*%f}0( zQ}Lzf_!&Ci79L(#y?h33Ln4uPi_WySjX07(^kSJx7cP6;0bTE5$;Vz6@H zq6^IBGkU&ZfQLiebiYNf{tYQPIG){%abc5 z7x;JSTH@;XZX-x@Bn!@gWFhEA)nw3^*6Xk7l4DQBLindTM)bvHVg(M)zcy^uAB82m zqO@>1meQl|GSifOSI@$4EDXFs{D_!;Z{s~(NxAM#V&B8moeeICCL)R7evl9aWZ$yQ z2&<^24trgM{+Z0;Y;d1}CIT0YBZnP+_pI2(T||)d4y-Vcp%zlcj2HJ)=P2YlJv@wO z@*u|3zQ3O-L_zgLH{`H#azX{yW{kUePUN`U61`}OvYF%*O#I4J>}04~3M{*|Co>#6}{)B}XBC*8lwy%eM2HQ#j9{WmCzn$Go zG)nO$Z}*+urx(xaZebLUG%0K1z+va2+~id~zXtw-WpBFh#HA?rqCm09<^8hw`@=!O zZCB>EdZ)yy6H$&z$zg2paJ+htyChE@4$kos$dnjZM`ZVIYaf-L;I{@&q?1jMIMMg= zGfDj7wQag(Jp6~<{@-uV3w!&=FS`U`=N;W+xB~HN(r)$$?HRrE?x0G30;`fK&l|#T zyOOzk<}?iI$t~Yw-QU5hzo^EKpu4Z|(nn545MQjC1a+$N#g2oW`&lPGqUHL)!wT+) zQWqGo5uOm0fjA;>RCRyJGbV$ZvpP4lQ>ASZ1Uz{@@hS&_!uDK`*3EhUAsUJkEC8`^ zeZGhlA=#gs-_6Mtj}`|jQ>pcwEg3!@Of17-5s@UsOu!SuAriAqg(mUQASFmBUCEkv z`=;8SHdE_=E@XK;23bB&&o?b2=N9E~CnDQs6F7~}UxbEoI1cgFqg%o6qIOag(ylqp zW=qGiPU5mgK9j&oG3kWAz?F+M=w1{nxwB9fX55o?UajzY_{LzSm$v5~TyKuHSdCAf z)%bfP1^<8#&&qUa?`fgTVe{A-6B4sIA%MELrr3I5WO8Fl4rTQ*J6-5RYsj!KmMP+= zQqKc&e@qMC?R9O508D)A(RxO<15uQI*%BLCW{_KDx>0py#UbSzp5q)x#xM>C_3Z0D zMlg$7MnLXUFV5J(40>#*8BYpMx9Fbr=la6N+nt0dl!Xz-G*_GES%edCnKOO;}Q;GMc3*sLdVju{W3}Izbo;xjSl2Z+ ziDDN_-8B4L9&5#%4fa5HX^B$QasJJehbK3_| zGT~jZ-83(b3VdUnAR}h8P01_KAXD)x{pHRBD}wZ5TPy1c4J|jCK_2<3-r1@LlHgDT zvN`7!F6pb9JaNmFRzdUcAB6-GGF}Rai@f^5c7m?}K`baAgHIk$q|LTcyV$BNuw-{D znc3p?e6r_Y1glXv>lfn5XV&re1OqBuIb$J}!hWMq^cvWri)NDEjdQ`TG6(f|PrqvH zEw%T2NUMOZ(U_&qi3~6VNOy-6@O$y7qVZ1e9~2|DCGk@*6m~YYNo;V4$Rv`|zV|Py zd^shA9KKQ4BhsJI^hT;s#8e`Q2`Sn>v(44n=#^#}DO0Uk@2iWF55B@pw%vSig|?b^ zk~^l>X}{n0Wh9gCo$_UI=6o9C*&axAQF?TKtaI9wuBxpbS%Q6bx=AKLm7-&Ul2Rou zslJ}Pe^vgD)J;u&X56c_()AOUK#`#Hsc2E&H8h59!yz!5_S(*xNg%&Fe^Xl`XRcxE zXRj5Zt=+v1qI`ki>zZNh?TlwlyNvxLqd4@YI<|Tq=s`(&i!WEFQdUY{d|oxww$nR; zAR$kwPBw&y=l5));%dsG`UmPHkCJkt_NvHQ2LA2{J@^|Oi_B8Y8sVt)x#oC|?P>Aq zB{tzi0vlY`wzh@lTP@DRA~ina%XL`lt^8M088vxYSNa|nM8}P;;=Q=lUClYQW%LfWurQ6*WK0GN=pm zI#a2lTU`w!9@?6882GO)&E@B{oVBzRmV0#Vux`o~+Sy(=8}_#eE{$wS0(oYhUW0gF z0ai2v_h6ah;)OCKw1;&O0t>Ipm1$bGI-X|dS$wg{r)cTkborKL6x1k_`YuN6yMjMR^_$S?E`CFh`?RIED{N=Ue}>-FLFB%&>5~uf zWO?Q_YF#-?ceqohm6Y45tDyTu zgJ8MhoTh@|!7Gt;wPKb6J#>&8+%uk;@4j4Pdv3B zAUFP|qf+9p{t2#X z&j!BDbFyt;zmG=BKiOlm+W?6ZGwP{tJNC^O2G+hJMrhI#vmuYGQ!;31-bqh{d?!Yp zMG!yJt?Q3v*1s_5>1iOChl91jXB}}zaI_AE?|Qb{x<~-#qmE*0t^Q)`bMK*mr`cHWI{i8pv54DcS8*m<36m<--64|~RYH*@cjeyUhU4t?B%oLLzkmh8FP zn$WJvPOv9#U%RQxDs4SDJSn?J%o-hDyOO9qyyUH&XYUl4r9&YB+crHp1H~*#3yDEpCJK5jPfTLVtu9o4{>E)6r?vY@Y=mu!@bcNK z!8YT~{tfXoW67(8AD){UVUYKplPZ!EnaCpQsA@J=NLc9YT`_2w!%rSvZMdAPJC3PQ z=0fJ7G~{SG7_n@7R&VPS<8?W;TcPAk-CZV%X*UKv($FdgdGIOZW>AB3Sku~SJ`W8y zmKjeJi8Eyna+2Uyk?zJ?y|_uI`t&?kDucWF=z!Wli%c_P7}dWaKZCoZUHK8fD995npCca8$*BvEen_=q7?>Y$#R8=fIxN5$ zNvZH|CZ#=QSJ&TI_!7%LdqYalK3}xXx&xuUmfMzq#i1!&Gw59uXI$8{bear*Nu$TI zWcfs^>oesX+7_4Vh?W6TCMFavr7BmKw$kOBa~_ibtE+{=C98=uK7IuKuVl-xb-%C^?g@XaZ6#2JZB@ zTJ15d1u?vkJI^I!&?f0~WULB7subW)Zx-uPj$%Xj)|*u6K(!E(b~d`>3yP3A$gc+lu<$9{4vcQZ2Q zAX)skk=DmAWJnCu3*Y-Ljz67B33zE8ua@fZfn_W5s-!UK=0XjQsoz0l%r_GP;wT_dw#YiE0fjxoj1H~1+g zkJ6k`-a*$bTTcLBy;a|Q)3l(gs@)vQxgxN{Qo6lEW_sBh?cR7Lae8q|&H2EL9i_lg z+E@>yD-DJ9k*oFF(%wE^lWSR^TY);(dr;<`G|zu_ApIqoGn4J8vUn&Hqt%l$wn+l% zp1lc`y;GOJ-qNf=Oj}|i62fdNjFX1Lr?E5_mpMd)1Y^=W3C3Ea6RyAwNpDW>Qf2Kp zs8@?mnZLV5vWTNuqPbI4$WY31;iEh0t?~2_v3#Xi9^Na?4A?``H+3{~l^HY}h9((Q ze3s>TSXCER8a#>EeL6+6M245ODxHv)aU1jRP?W0#F!z;hFM8hGkly#&zu!bF^_*E? ziOY#x-rKASFT%SnXpE+n^sMZca%WpncG??PdHbOi^e)4D5;Pde zkZgpZy2^v>YN7*or!>t(t2fNX=E_-nx=E;OYJQnEk+t^ORBUPVjlKqBC0`|PzmZk# zl>63Abca6~gIRC$seC4}N`W;FbsI%+gsWV&;|)w=T;&`M)GqiHC>B;C7)L}v%7n&=q_fl)}-0QTiC*`9_IZAVG_)D$^ z#I6lvzS{R#9UMP=YYoj8&g9WhpdI_v=&IK=f zaqZr{Zln9G#iB*!66Yj~-2mZfjA2j-;LLhaWk+;p%#Sd+>9yZ%EXKlKN`+f=bMKX6 zF01MLuC>K^%R|k|c^(Z83J;_ri1MFfeM)Z=IMbi&x!On{by&Tj1Xd%!zgkf5f3Q5S zOpR*Qp_FZlRuEDIrO5>(+bwU=I?d zyxmH9;iG=Jv&~}r!JeN|B1!C8J0Vt6d3zPAlS@QA8ZNa*fwVCi5_gxm#0!u36D&Xl zm9R})^uu-b59upAJ$H1c&k!z)&U*4{x2uQsy-<7R9ER00nDxm!TGlrrYNZZz z%8K5NSY34YCrrLcC!ZpEuYl$<%no#7KuVxAkgC`cjml8-2HHWQXc~iR9E^4C4fIpf z?tEIEmvGb25XGZx76Fd~^qGg2`biAXu2O1D)yXJ{)^q8zq4(A{zNm^X-j}8h~9L0+h$42p{-4h8vRM<TgU&0!iA)MtfuuF|lmqJnJU9 zNp3m`x^+*th7Bzm5dwz$M#SqN(XI|{@AEcII}Ny+WTBm(R1uigGe=bNJu&$&bnsN; z#jH)e-*ec&Xi?{Db4rMnZ13EClkEM?;{bYNhV5mG!R1noFiz`__jEiR$#;m|Mi=)6 zTbcE4F)Bnf2jo|h=|^Ll^p+qJ_j5`6p>SRATZ^++OwNneNF4bZbWk(2{S1f8ysv;3 zUM&h0hDqhh=^VU#1m{_XpguOFynk-U&FQH#&*RLCvU2DBy5&4`kPp7C@;78t@5VRp z5H&OQGhwsFL~v}BXfs%_97s;MTeXCGz{zw}0)2$@BNtED$T80`Iy=uA_pR1O8={KT ziG71Sig}SF>$f$RuYjo>h9S*?yYSK^)cvKVcipx9 z)kSVk0(h+4N3bQ9xkLZvjjT_so#s_jyC2H5m>JHETEpDp11Fb+GR`Ev_1Kh|9hRh0 z-;6`>5~!LtifFg{?92Mjg1pt5Asu~B+vit9^3&Q`iKo4XNE$#r`Sx>i9ddYzXd%xf ze8r?AY%b#baD~VQyJH#Ll>`>5>$gde@vkWlopi zGtL`&pMBmuX|0Vj(|Omgc-^qph@xF|J%#=@hqAk!89QPdJ7imC2j7VMmXS zsl4Qf_(f+IR!>|7hvvQk>2EXV6^CL*y3ez7VK3ppC$V4*6xj{ga8VxYplSxw?5C=i zZC5Zk7z$kf%z}iU5mW6NM($pu(19Kl;o$(ifx#D0*z~@Fb=mDPUhM8WQiYb0$?An{ z0iCV_ewFnB^HrHwyvb#z*SEuF?k(3D#@g&sFO(=$HHN-;mg_c2$mKSyyhKtIS7N*B zfpI3e$mpbVZQD&CH4;>(~eqb4M^Xv#DE&6=LG?voD2^3YQY&h z(NfC=ChM}RV){fZFIbb^Jc2&u1RUfdHjGt$He|^bF|Oh#i`EWlOPa->+npy_YHr+| z|GX>n1SE1QJ#a2A!O`!GMl)k9#n)ZNTO+VwV6O#r=2k-H z*~;-5Tpa6ZhK5eR)tK{}lcHC{aj1hMqzGRXo4e1%Iu9!kr8#^RQg1f1KdAH+R1Ll~ z8T7(2bZMldt{rP*VNf6MI9U>3D0n1D!b;--scd~5=UTYu<Hf6XUGSS0Qpw<77f;!ckV^UnU2C(5eO$mHaFGQa~61$;3^ns$ycY&M3 zcX;_?C{bUX-ImwcN1@+1xFWZ%kz4VkcsPREf4n!%mtBWy#iSHqq2AhIo{gRq2?9d3 z(0h43>tqNL#Cr9<3kZtFo?C$d_Qp~v2LWggw<1jEQ74reHL@`&2~dG0ZO`JrKxrP zy97f2swx437M1W($SU$zm?r_2y*SNIvgrgg86 zQE$m)PAJBwqF0(jwJ@F$u=&N{?;lPd}RQzp*T<&%t>y;BCIYyu{ghA?j>R&jGMo`Mea-xtC zd)@;XkY0Z-(Wdd&9R>@fSDI&!^9lrh#oly#8PeBnTXz$hZwavsnrI^@VsZxgxgG3j}F(Dmj&yre5zi{`sF&J#@~ zA^x=`5$VwiJF^^0s^=Ec?5<)#c5kOW)p(#F7wYW`)rm>5bXBt0>gcD$wqsAXxWf$m2%c zn%-zVzti4&Z7jDfmT8ZA>TjHwykV`!!iylJ*F3A`aj{XbtfZLHe+R4%)17-hG}mVZti@Rw_n?8lLMaoHe^VZ}5?3_iUV5pAAQ_ zE%4=$wj^(kpYJlgi;CR#in+>8rp5q`kGEjD?=A0E;q1l>l~Q-&;&%zEZTkl3Yi8ZA z=4{*w7Bw)h-=*Y?UQCc>rN$s1YTb1yOt$wO@n7!VG1MQNu{O--8B-u|H-A43xIjWW z8w>VVZ$BZ`s}BqUeFXh?4`_=$_J{#TOAj@vr-tJ`_o`W=dP9p$bajSOHWAL1o1wAH z$wB}c$#Y)iY^hxu(FXX9EOio{GIIhCX!EQ_!a!<`uk5uKquv80Y1k z7j>}a)XjrW;sD~0bWmvFt|#Z6qR0iouWz1nR+5sd<3& z=Xah)mRDT9&|LHOg=K^0=og@K=SU=0?u07;`m4Iq-eL=P^JKGfUp)X0b;G7ZgE|eZ zV3K5Fw-3AtzgzZdM+w1JbE*>mesWfmh2PaAa>fi+fCs;&v|68mXp}i1y;Mk(sJ$l{ z+B;b^Ejod9-APiVY8z}DlacyowzRA+nkXQ*zi zX$bOyo>sBT`UCERokiAY6nBH<@qK`{IleG#)*`@4NqY1>+of|Fw(lih%w3)$p_F5Wgo^ zoez?Ln$IxH_L_;YUwfYI&cohR3~ z*N|Dn&@bHk2JeyrlHcqqJrk#seq8WDO(_9NU$ov><9kEe5n&^K`HJM7*fr2QQ`avw zALX?=xO=A=x2ZUDID_n4wtA6u#Cq83==<=Gu=ad1po{Lb-*=fpKup+40BRR@wMMjH0 zY3jXrD1Q^^Ou&~5Qh#WCs*;zXQe=6_a;P$>Ip(0oby1PYqLhW`jwfKiL{Inb?QCc$ zVsTXH)SzADMB^kFULoOhW*r0s7O7%$y)HGS7Q=dDx8~-0#Nc#RBXXz7;xyWTH)~CH z;nTA@X)LDolZ|0gEe|pzt*ouO!!w<&b;aL-+JIcJx&rXO&nOUzU1UMw+PLw7qv0b7 z6t7N#f}KMy-5S9mQ)w^Gk5cT~GpQI;tHDn)qjdtrT#Dj$=Sf4&UAk59Wo4Gi7Kv|Fn%y6M3)jgnHU;K<>YfG&y!l4~lt zyw~pDB+H%Vr-W7S_}>O z-FpE8HEMykE9*1y$m$id6D%O#&^>@zzp`O-*({RFn#Jt%`*!mS$$YL9jbZBNEEf!S z$07)cu=5Pw$s5_j$gVgP5#;w^&E3uCYJzZt_o-$0>oXKR)yT;`?dG^@AENaMOqL`k z&+g}r9wEjhUNV!?=)_k&02ya2&%km&34qp(N4WFIdT&VVF07ZNViUEUz`gUKblsO` zCU)A0e)=2{3k9p;9EW+5=e`*AWu+{xXs1NOq}ng#Td!4xA>thl2+09mvR13Yu4sc| zg3p%8K+Rdn+DrWMgp?tO2)fF_X98I+!4FCge|@LjYC{-P?&GgjF(c8}u?0yI`eF-q zG(6Ve%p!$Vf`J;~3iq3pd&H{8P_5oYHfz=(EwBb>!P!jH7jwilR>(Viao?H8oce70 zK$A6t5v2aUFoKKK$7iN*O(l-`GUfMyadEa~G+sH`iJ%i87-&zGBwYVY`mo?UWU4qN zcwx%{MD)qUvmcg;oOZ|3f#Zb3MiH)VFtOXMxD#J0x58Q-@f=&uXm>+M2qR^TwHoW` zAr<6ajNlJ5+B2}_La)NAcR>`yhg666T#EFn?-V)j0;oaYlCU4|T(A^q=v0o^o*nJ9 zfUS`z9pK#+J=v6STGo zp&M&=mA`X@CV@lT>VIff4Yq-}!#I3^i^B_+Gl|n^ChxmI*Z`M?Wy$_L+{VR|f&^mp zKE{(A5Wyx`1bB&HTQVXqW!EVnQQf)%NQG&2iZoe%ReKJGDk1)v{qtWqmlw(!A{n(q z&+m8~?7L^Fv2$t^Dyo1-;sh+Et%-88F3X$4-{#e$t#|^ZE4UK7-b`uv{z za)wAGmII~U%=)Ej9CSWfrL+p$WBYrqsdGKq%`)1=oNZ=(hVi|xG;4-y=&iR_1eCN? z!CsCcBK_O4fVU%Zu-|I6xumr=qc~*M5B34*#{>XsM~d~BTj;ew!RI(A(;g{1O3zcU zVywY}X7g}XH$_oSdgglrr=IwfPXJwmzGWFdgj1)khEe{RPy896PG(H?Sdga5dThSHCR|g?b}Qs#wemzkkT6Gt&h}-QNB5IFF`RpS`|# zn^?Ia7w}Mb*Lx4ZPMvFJZq3-NhSIREe1Bo|1dJy1Z9YIv;~O!F?Sz}p<}$9Te!R~5 zrR==<#l?tWu7)rY3eaX12XuhzdF)t__g#&EP>rw+`t3#0k=fW*3zR7a*ts$nvo>(c z&iTC|8z}OjA)6na?tcD)>Gh%k+slurek>J!lF2R1e0(-bSFaHo2Q$#09nIETd|WV3 zQYG?8xb^lkCn;FJ-D7)18P=|3Y`hi-Ac$j&)!Q9U7x|tJTwWZ z8EEqM99E6?c2-2^6nR70`k}lL8Ln_)pe$m+!at>DcKyQ>J>=bQ&8UbQj8-?e6{71N zepv0uy@QO`dIuNRznw*qhm*pq>Y&sMR9>Sw0_|h{pFKOKTEjt;-w%}(9sMksW3MA} z+&&-%od43Z*Z_d7G0^v1GTf(5SA2~R+Ig)ovX%L(?YECg;av*I{L36Eb|d<`H)VG{ zh{@vD*!PUpvRNyWHmYrPLZ{DofB%BOz4Yd=kLr=gip_|G4A=rAE z%E>i!IbT`G8GsebKjVpWP;I=6Id%zjF5kxF6woFz>tpV&wiDq_UNUME*5Mz6H21Iz zhgg?+>jliCK+C4)rcm$FNU>Y(|ggIw6jf@TAT8$PdEQP>GW0UV= z&V_KwH9AW<6=V*f>l=NmdqA&n`>6|Rd2c$_C{17pXq)KGzov&1QO$F@JeZ|=Z8(8M zXvnOekk7xMu67+alE>nfMu}VZ*8|&q%Ex!-Lub38nT}co zl!MxX`+{px+2C8SJ;B2RbJua6XCjN#>k-)LRZzODf~C$0?Ylhn}YdRKcp+R zdR5wxE>?A7xeH9+I~Oo9_Lag@uh9s-1~Ba64e3QHqiN_2b2jmk8OgoR(K&kQJsew_ z8um`Ca#?37u7Aj5?{e86hw9dh4IbFOMHo40wK+0aQPyMA zbas_s4xX5b;EMq4U?0sgCH>aNTTTllcd-=e_6ZoZYQ1W~W`}5%DiSO5;s`umC1^IQlo&kQqSy(S*}0Cb)b~j$mJ9B^60LvkE}eQw zI_y=pb<2-IjMV<-U{Vf0du2v_tpK(a|x-cn)-z2e=-G1&yF45Q~H$oVoxcQ}1 zE$wZnN7D8Bwzt~0zo@S|;Kw0>?OWWj6P}TOaOEASKFQ|3OdhD*jGl7_1#m42tI-~y z_31eWwLR_x2ul15c7_A%0qIx)ro+n*_oS)U(apT?WUaiRZgQ=^lUFyK;! z(O3?aQ)J~?!ub7pj*DkOdeDTUa3hP&6N89FKqcyuHJX|?Z*R`Q`@oM6sLT*sdrBf; z;6H`iR^>QhQ1Ss&d}_57L2AtSP=MCcdPy9vDC?13s@v6ExKj<1#?A)C8p@SwsF!gp zHL8NxrHY=oRIIe=O(a5asKcS7yj-&^`wjSt$n>~}+Hah&?8FLmhd z_*V?y(e~%^i=>kg>o1BXh-g3a)t z4P;iWjnjaVtHbdefa0*70f1w9FIA@OndgC{^j07jV8GR>aon(!2E}Ccb=sA$euP?$ zU~Asnt5fSPU|WgIF5r$5VG+lSO8bC)3T1Nf9B;pVEPHgRF7pZU+~)FS9bSMzJh}QT za3Wwm zR;~bI;9FbT2VTx?whVrIW{+f&X1DjF>V8AaRxRwtL41)2NReW4R`zl43Nw0W zLjc2?9Gx~<&hWF0LG-XnxHo0!qJzk5Jjt5#1+Avg81xTpVvrqw_oa7}?pC{vvZP#P z)KA=AUvz6r-1;&Xfo9@n$H!@^h!DadTU);+()wT;blA^+x_e~?WzM5`=-p>ZKAI2$ z89_i{&NcsRmyg{SN7#RZ@0u@id)*VEMIX7MFu>UA7if4b7F=$Entm-^X&&+rZ21{~ z-_5SqI5afmq@tP%_EHpEj|srovT_#4g_2Muu=%&;>>?-&N#gre2Git3Iwf45KTvDd zpF={^L|n zHZ=ehE!rmA$kt;YfhsS5^IcR`io<+Xsw{v{B5CAkugLC_-briI`DnL91%D|*aU&af zqs5fpWyl77xxlII)++5dd766}=E%C+XBcrYXayva1L{<)j!=z1QJJdwxAxQ>N+(82i@9G>Y=$|+vE$<~ITdlqIm3ZmNZ-;T2 z|FOY}R(pK6TJ0Buy@*Zzs~QPXzSOJ<0Y>_K=nPHPxGs%ZJxvUMh( z^V*gCG`S?PtWSAaFPf3Zz^>Yjw#2eV%Vis+Txf3um;Goc_hOIBRlp4-7~Smannh*! ze|)_MJeF%OkzJkH}hF13=*n@?@tt&PR=0Pe1+rdAP-mYPxv7D3Eg z_Vo3Eh>G5c^A7~99BMyfNqb)va+0m30|qx{DBGS=pGnlA##S`HRJP;kK841a1&ME( z$GYNQF-|uZ;#cXcQ^h<{ zdvd1mHIrUkKU!fz5WB+Rb}0Y&+tCYB)sH1ke0kykn#8XXWzyGl#7PdOCJ}+r{J^a2v#~#9h$QDxlUw{Jh zrD0`&_Vd`JYTAwWs_|lUKKX^l&qx<~olbEn=u}!XTp74KsR(k0to9Ygn1TJhgZD)4 z6W5sWj9&H)d~YYK)k{r1sU+3U*U!*t<72d?-}HcrN1;;pu9-sDsICULAyq?!cjMhT zKWe+P6bkAC@%%qBhi=`jo5e8x`YhM$_BxujyMJeFb2V+;deJ7&|)?-Qt~NO$`j52=P4Uu1S`S6rj;d1oQz1_}F>nqNl3A`VlP zzjU?+pJ`>g$ncH`p0L^Kt^;nGp>C2F^Q^LWdrOb)`7>d{fZCQ!r>}|Pp59_Ne8q_E zD$g~iPIt(WkrU5zKkglzrMhcqmq=o-YAI>=z3tpqr216#c%_7r>S9wt%Y_NI^2c)< zF0V8u))P9ECVSq!ZiS4c21(Zsw5T z4sSe#9(h;NrIjq0YQ5DN`l++sAXWOa+_6ESF`Bj|yOM#WTFun*xPWNeMi5q^n&%0h zI86R^=MTlk%SJf0cZAQhMltkD3~mh-`R<7-D$-)o3av)o@PZWeRQcO8R~W9dGb_q% zpB=Apco*#PJ&&i^^8AZ{J?wx8YDQp;_v=ESlq!T!eqt6Qa2<6m&v{<6?oGGfY@3$Q zrNvf>*}HQCg}?L+a+MzS`WHli^T40-C4)a)0joAPg+A+WQ>^plGl4Cqoe>oYQW(RH z3mIN?0kgRX{7w18HOnJfVu@ViHpMCta0v#2(G2(hatYet6%ldfBk(T2tBv40R{MaD zNo7bm0~bap5r5PU8*m&8DXvg8_WL>$#z@_dZGGQS_8;o_$gpchh{HL@Q@o?~|1@%f z8!2tU6S;oKW&Ad%fP^m;D$N!SAZ*Fuk5n>{J)!F96)RV9`)H3i6GJFooFOhP5d7N+ z1v;!Ev^s^7a>(BgDzKsgG@7(x&!jl+U_P++GpE!X_;@DoeCx})FVG0y2r(dy4$jDq z2=jNKSm=9B^nh7<;%?7uhir^iuAg%POKQ~adW%Wx!-2`?ft05yry->~nNKxP513TA zK(Rsl!8D^}nOb~%{zG?))z!VH?rI@%4>%OoT=pPPmhnJ?oDZGRAbWR}?rE1HV}_`? zDy~!t=0AzoHy4Mhc7>qY{p7VD+X!jW^fKxP4TL8?HZ@r`WuU6`t@LYT+%0XGbez~| zE6uz0=B$C59?^>SN+5_Ase0xMziwx?@|;7Uiz=NA53BFz?}d3$Cw+y8|>nHZ{cm$vTnz=N!2U4d=`&POsR z{B!qwTRF3<^Uv8xqwt(w(dNz=fU+N~DY>_Gb1aDgE-* zxbXD}DHehBcbDhmyVHKf>ehuojZ@+qd{Wy0_wln9?Zw?Mo9&2nLLo<#R8!I&%`jUR zK}~jW^-(_%*9DYh2Djeu9xtwR{d!mUO>^{m;w$l%V#i63;##x!ZX>UGLVI)XiQxl# zZuMQ<;p{CMg82ygm&2Ao9#R5MHSuiMTgCkusP6Z$0_5swo}}?)jRoyI18naDorw3k zhV>Y-W++&6vm1(0WaKcOO-%rOn3VlkdGIYUhb-?A;{{mv5f$`&Z#HH|eU8=OXSqkM zJMj#}ld$evxFRJfkr>EGKa{s2qdhCw62sFnUH3P7qvStWY!u1Da_*X)7CfsWG6{ZR2(z(5k%J>{0M5Bo?QNX zeqpRybhwN@ELnnBh`VnB);FTOsiqgk_4haPZf#40M(BN?>Da-3lAz-R(~H8}mlD3? zsisI`X5LAR=wUli z=BSSc9HmZ$RmUE4?@v047Xt_0S2Rw@;@d}uzWQ=l?1@X525hd1TvzFx2|WjLM+_yoXQgW3l|%<@u>;nrr(stlR0s&u=E6dPeNefe~6 zydt6Yh}6(@>>7RVJj3PBt2-tz3k7_*UfMtR_mR{imthSv6w903ANb<4KP>E}FkBJmpeYLmy+3s5^ z8rk38C`7$*BCwC-g-h5rC$lLsJm%ScGpPkJob6Bv2~?&D2doiMf1yA5_U zKF@Ej>z{6~DEMFYLd9~Z8F#^D?4$P!!eh_PN3UNnRvPG*S}(BTDc@2%eS+;VX22Ec zQVn|Ir~WEy8!NLfcDCEkWvitPhe1F_g=ga*emTwi@%;Qern+)FJ_@PaaOrycX!sGq zhW_W;6^D;NFH?9VW1uF^>Dw@M_SKZJundLpe`E|;dvr4uy77`FnEcY?k>;dm zL8i`6y%V>g69$=^CgTj5eWE%;S^O*_9`o)#rAXb71pAfV>~Ehdv7qc!u;cEGgjuUk zEc0+cRS{HvX)N_*q*&;l%ih8v;xS1AaQ23xU5<{h9Ibxq(>M9GlHKS8sM}z>*j%Qw zxyj*tHRj{sNyGT^7Y!fS57oC}X{>z9qcx`Y(c`+QDqe33MVhH$ul1J>*gF4AHDSQx zqNv@E;q(lGnMnQ+_#9MTQLpx@d&?O&3XR5qiNsML44KP}p%!Q0xjj~@iJpF%J;g*C zI#d+Pcbh}RZurFhUae`na^vJg-H8FAPeE$SV0t7+YIFIKn<0ojer}D#Lt;CHgbl8n?C8o2(>8fWZ(Wk_pJ>);2%=eU%8qprk5wrWupaQNu!F3o z1q)RN4fpq))9Lx?davUOlRWN1;rypCdLlynr_XN|vD-r#5izaIYO_G+Rih*{ms%1H z2IMYeqbnD^e}}UzHUmPZ<5~v^A|40gb!1%#?u)UruuOS);nFmzei2m6r)x}qq{ln1 zXcj`Et46^$;>0c)ry9$tZugPP&2M+syUa?9;d4d5LT6%O-8y)yB>3D69VpzpWl+<> zrOEb+;`!%Fb=+#Zldo6WpMGpm2jvMEnndTagQ(5!mn$LVY0t9UNkk?d=t|}IeSi-U z3_{pYVzmZh;!6&m&)$c-I;Q4c+GG-CF$fE0=E7@$y&rcAOyInps1mbnuF`pq@?fJ2E z^Ns@)7xhN+7T2*|myvR(7jW*z zWxg&r{aZ0C-p)SKUaDpk?8!1aM!bV*kor|z8PkfM?=;g39V*>U$fYRE^K?qEo2+l( zu!DN#bh^>9#eXOQpe9VQ)=yYff*Ct)J-jYPCXw{+aK&amMLzGvNt$bWyjezR@Z4_E zw_g}U!E~GB!8259FHhr*_q@KCW2+EGVa8F`t6dX-s@2T3$)rIZRP2La|7-Dk3PXkAq966`G%N#iv^ptI=CLsO4MBgh{oZ+!iUEH|LH`43 zdAUy%^_%oWRQz(H0mXvp9)SlScRdPS;NSP7!N_1x{P|<#B?StsbL?<`%g~-t-;h4p zKh4H^%LWn0joyr|-|5-I&?FG<1_6W}jLpoNs=uL+C?rue zDG>e91;A}mU^C?0gpBR?cB}sMzmW@DB(%xw(Gw(m`eWQDcOMDH1Re|h&3R7{Bb{sf z^s`kI;=6ZvPafisH6}}wb2a=EWr5p-_^n4CcmL_B{Lf7Xzy;`7pC2Zi!~D-vfEfdr ze<n?)j?I;g?*iD%8@rl@%=+ETTNKya8|3BE)(Fy^+^5JNEJl`Re&9}> zSXn8W;2>dJWsm3Z<#Qu7JXS_Hs)%!K=ChkVUy`RD?DN>n!TP&~X3a1t|#nAue z%dxtVAdY?=eTDzY*}r{t9qFrxvf-orHUcyL@h8XuCD26n^NzoL`av1y?T^71=E(T` z@g1at>~t{2*o zJNaK7)Q*IDm3674v@^2&La5F(4p(Rp(v-fW+QlZ1z*5}@*coqB=Cv+pv>pSjG{=c;e zu$Sjr!i{e%X>0wNJs1Kca(~5l6#9;)!DuRd(L`}aG{h3g5WiW*!Zv3>?|L;Rh z18+0V$QJtB2)5s%iRF!)zl}hZ^TUkYPGQ_s{S)s;`>Su;17egMUX5IeyfBA|DbEF$>FPuBnpCI2B(0Y2}{1o?H ziS~-WAB;h~MIMC@2psi=RGh!pvH^T>)JCR{@$ZO>AvSMwRN2e_?QH)$)ap>-NE#a0 zK(SBaBIv<~70UiYR+cpM$AqJ})b_>f)X)U~hRGh^4mG;_o*&sVj9el(L(efgpaujc zj!#d}iPOZOzL*`u>PiyBC2eJFt`l_RB^tZzzy9@jK38GMIe;1Kw({1_ z^Q~U;)z6a1pFz&0=AZvBYlCbcOWkkLRlXr56C=3dUbmIA)1i>=qTHt>wJxYO!P4vB z)05|i{_w_iIWaVyJIqGT3|FeZ$P-^esa_|yHgxLvUw#KjC`$DVHlo-5sd^~tM?_(A zdGM*=h)Z}1to105*-aW_mwKa1Q`{sEFK}nRp4K?VeG9i{cZBKKSJ)T4y3C;w$G4KK>;9SauO z*GDhe$&v(IKV=avc$G@{BDawL@1Q%t15hG6o+0(xs1{2XT>MzmzqS%^=w5VTM8587 z@L~747M{3;c;6%;w~RD}oD|!*cC6mGFD~MW)b2-Hn}WYH{0%%ULrN%a4=`{Ytp?Q!$e8J&bkrS)Z3grk@htCOE`udZiV@k#?m4x z@5Ueu9P#-VMk-gN@FGv^hkIF{)Gyc8!3~6#ap~}0K?htqyx$vt?w1vXm2yZ5#v!h@ zvUSkiG8bWNZ!7;G0T(ffo=uC`*GJ>(e*65Jikvu<2MPR@S@`;wJX#nE3unsHskYeK zu795TfH01Uu`T4uh&g;RSfP0v^yC3~>_|u3{4b-5Y0c-WG`I{;O{dipn35X(e^*!^ z*x6(EcL%hH5fqn)TU7&HRFr0NyeAqNRtfr}r|h+xtvo!lwv;`tFf{p*a^mn;VuFGR zm~nW@r|*lH|J~$vM3G6d&X4EtpE>fKQ2bWU=G>{Z$19ZT>V$k6=cHegqe3#-Rv*JG zmOd?hohl#~X8Skpbi9{rYv}lpDP#_lQ{(m_eoM-Sedqh9?_#PR{M_s|CEVFLJ^$!a z()rE=xQC&h;a9#PAI#;yRggjdEeq3r3E!qd`tQNt{u}35?clGSD11A10qid{(&ey3 z>__QBNlyrAgpi&f!gn^A*2vf9UK)AZ9fG%#Ut#}Q((HXa#dLGDvqbSq?JwqJ#yGsk zC$U9Q<)I!Wg2%-2&fu-!$ENdnNMS*v`1H$-6naM-YNH`vYO=TWO-b&0o(5uew7qlL z=@ZsN=NC5$SI4|p-Yrc{HASv{Evl_}zr98hQ#Cef)rE{`NUB~j@;G4Fi?XbGb25B( zzvtb0`!b;poFhO}_6FqK#8ZvorXL@$$UXpnhpEj^hAj_IUQ}fuV^@BlFjQi$w(uc~ z0CYPoW?CW41z;#b)@?ma@8UXTRB0H}a$GgD8Iq;{xU3whOcZ~*GH!E&dpNl0NE(sgS&ZnfQOj-p=} zuay;lqy7BaLxH^;SdRO_Cp#DM^fxs;@3mJ{FWxkXnp z;nSgFEK$W96z zn0%igyaOy!bQp~JahZc1Qy%K{!pVlvAnb3DaTnM($G6-5Hu7oESUR`IELAv)P7r(Z z>nAbSp_oWo{zTrb1e0*l-t5b!3RH@Wc4hXThdojQOVue_@7l%%mO#Jjlsjg;dS}te zz&=wD%X4Ejn6@Y@Jz$zNvDrC?=l&7)4!)+Ke)c~0r6D%*$No_Hbb(m@>wQ1w&C@_k zpRmqC-vqAe+=WxnhvM$b$rS7x7;u!33vgVWkY5^pO&m;2i!ZH1f)>~?dek3h=ofzC zyc^vkO8u;&>MaIvA+Y#Ta>DDO&I2c}c)uTuoEqp4dkvzp`x{zJ;*J3LDEc6>*Jy-# zgtM5^M&FBQEi@B+gNV7XWmi;D%@3k#Q2k6jxDdKO?GZt9*1EmNrWw`Cje^N$D`mUE ztm(7Azdin*6t$5P&2Wwghk#Ust;nJ?k%M3P0TZ2+hk(qF1@?zzBSQ3KWX7+@3v`8{ z&s+LT#*_3+&vA}9Etni<51`hs;i|Yu%*VsSt^-h^&V=x$Nv-3P8^*Bo7M%nhwTR9^ zvj?kC=M}a-vx%f4`FK!>r0W-dX4Vjvdp{}A!n_ydG27_@TaZ0aFMWIF4s-XS?^LBQ zuC%4sK!GmKaCTnC+lWOly==Bj^R=i_?0<2y<@;<$XNawrPxY|Y;GO4hY! zSJIDV(r<@FX*=37S+_7gWv?O!_$Dnpg5xOo~ zXU6m3=dSKXI62K89ufK&sFUt{&9qXKitOG$*{w!*$912DXH{B(!u-hxo9!L!0bR@-rlo0+?yz+_I* z9&M`M>@1#&_RM)`$?T>3xyA<1E4@5ijjcV9Vu-)C)gD8z)UiH;6I*aHLe3HQV~(1Q zlsftXntri2SB&won8R2UkmLk6o3b@eIax(`yYKYlj}j>I(eN?+E`|Jsv*W8k~l?|*z6 zt-W#3gC94r;5o(N5plxnE=<&5NSb7*r^z%6EArEKlz2mBVAIdt^}02;m9fvZ%$8mg z7-E;%R&nsPGuCu9-*m`svjA``nEe0J$hgwWG0a;g*N@r{I(;hozRwTW|j1 z0_c}-{TTmsK;U(WOG@0@OPh|)aw67Rx5UgCog(QfloZb`RpI*8;-d$=IvUrof2qq? zsjQQ8EdEy=0ZV*zZ`665V1l^ekR@P2UyO1tq7u9641-TN-4xkk)^n?Q zE53zu7v%n)>wV1C#v5N8sl=qkiVvKAQHo_cQ%R1@#(JVpZ9HBhyx=vpAef0MiI|>^ zGsOSet8&ij<0;-xL&{U)>iUU-7ac?N_4EY!Q#w4K^|Bsgwvfp0bu zU+A@oS0{$8K4uewQEjIdzWafG@LPv&U7QLByqYN;f(S0Zyc`{;YBpp&JSF!8JR$>7 z?3hhzcTx&b4Rx``XRp8XzX(!)^P%A)SzMu@qLH~*wNec8i49_v&%4glV>P#n9VJ%g zH!iGs(}&!$I$M~2^Ax#b{R7-y8Pk&5?kH^>Y9w}~#pO!eNm2Rfh3DssmG<3PQ=~n1 zadV2fXg)P7h@(9zW(j}%EkpX-Hts~3S6x~<88Or^_2i2#0S92llD{Q21YyRqikviY zfd9o`QcvYjy0+m|M+AAW`;&- zJ(E^He9=P)YZHPEObaY=yMy;_%Kt`0Tky)zbj$E}AY#trZbD(#AqA4@4~_C|^&0N_ zAB`fXpK3G3FM9Adtsf@m0U=dz++ghNX4&Uh)yH6Y3h~#$4_XWCNz9MOir3X}FF;g| zmdxt8a;IDC&i%(wGjiC`2FPIhWJWCF7%RHrx`@LVlVT)|BHUeF4gQwY+5ZVvdy=RJ*IhOiG^g!MWfZAL zawqG82(oThx>-~e$eOj1bMS=u--0=NH_}Rj6J~)=irlY*efhPEP9jE_V+FU~l7dep zen*0^(?EZ;Z3KC19b#I8Xskl`?119x@pt^Ms- zG5b+*DEp-xd1KemlW`GeDM|G!#;eq_8(;AjI0dKaM40{3duwm^y(Nm?w94Vext-nJ zfO>1#Yj)<690bhU(Z$_J?Y{t3Sau+#`c~Z+tMhv#=JL4UvRe(-rzddYR;F5FV#s86 zj)Ck$Ouu|(;YCr+g(8FM_x~_gU*%x$31Cj57q*~_p{Q1eTA2puGMp#JzVtm00>C+q zz;4EV2oBhS;Uh0Tgmv7GuMSKOWd6iU>4a*A#94EzPL2_3i9m_*%XPydlPb5u|FVA z+cNupTWYPyGtN&{e(zU}E)9U6cNA=B?v1{lESLQst{VD|&!eE{S#K8LA7?O=y0O9F zR4NfSgdG=6%|m0|muHMix6P#4hudYD%*;|laQv;qcryeqI7_95OZ*+0xNFkoJ(cbb zK3hYUO2@7j8Jy^d!h%iY@*T*$G+5OURmDsvgu!5wBSuRyK`}Zbkk+aK87_EiHuDY%1|-#S_tEj|6tgZ!oBV_a{mzF> zyetk!SvY{@c4rCm_&eJL-VSUCWtM`#1@*l88pKRVvzNRQR0B!bCUTH9QawrvSq?8~ zQ)ryGzwD14z86?N({x&J`P@_u=e(AS&zA>N5r(FiB4P2nGp$tWgH8?g(51zaZm9)c^(DZFBJ=WO4I#&c)pysdWS0{%$xZ3E>;QFIXo+w0 zNmT3EZgGtz`2fu}|Sog2(+FuFM>iRX)o;?`RUEDDUm*pNc z`s(nm!#jd}v*sgHU-0Ud2+*T1jlS=6S$=g!GZVLbRA~iGyc%8y5rolXeK1H{7!Y)_ z`dpHaQRvr`n+AeO?{~Gwsyx@D<|7x;-Xu}NtK2e{Nm4h-0~TQIMN4n==OZ+(f&`Y# z@tYYJ@Jb27u{qn%r{gPPR8TvfZQ_~Ebo*JQPOlG>492JB)JfxhmOrK)kUYbQtxl;C z0lQD#}<`VeDX8cBU zx8-cShWU;Kv$2s|;U;G;R`p{`U;Wv>lzKz|=zVu#Z{K=k(;a(=174zVsnuQ;209fu zHV~N>0Hx?bj1}Dw1pBRLkJr`;i{lKiSc1H+(xx z496K>D)C@zUYW@6*JI(yF0SXi;TXZi_t~|iYZJ-f{k>r$I>Nko6fOt3wn9^x5W%fO z>X;(z=tjQ&UMuUbV7N2?(WPE^R5EtdUwNm=D?B2G4?Ik4hSz7pOLJtDd9XqofL5O& zze2#BSsq1uMbI2L(v7d5$o4M~W};=FYbK|kA>*?}D9%e|eEf!HwZgR>p0DMKy*`_5>& zAV3GR5D7TNL?AvkR|?L4q7A3w^lKj;yI$zB_z}F7)7+0=$y(DxCP?lLqOn6v1+Dr2 zA;`Yb_bvb>JaXG16<-_Z+^EIpc!yip=(1!YJcO`!#z4T4I22AV%rX4NF7oWHH>_8g z4$7Dvf9^OT7z%)jWC#hpNjoex_rSoL8sVr)%sZxl@)KDE-HsxhoupZIN3##g@4>z1 z++tS)@KTY$u|a*|e%Gn>tN$-Iw(vaT<`RVHIiszQ*wwskOJOZ6cV9`pY*~BedcN6x zLy$K?($S&H5*=*b{#YIshF4a-99nL$WqM3Ui(xjDq8Z?XjswC=-B9j17_&X*-5nJ~ z|C^vNcBIdLeYX|&WY8zG^buF7>gb}RyShHh3>uSI* z4LiP%cL@g88 z3OF?Sz>b>)(9cEqqna+?b|(-ggAi|*JI|9sKt%BLnHAmh$>3A^* zW*{qqVY6Vpp0BMW2eKvuI06C(N7@wl9Nf4Qpa`@n(0@k>&cjNu%F4$Khf%O=)cW~q z2!MADBQ3vyh?+sA+i^xQdyz#5+3H~Xly?#ZTn0D+2e#;z@q54QesmI{uleq6otuWk z(YkT&bF3$yREnar7)48#jlZ_J$$Pt^Z=+Q2we=3LbSa9Rl{|i~U-|?$b;9Gc|j0L3KsVb^83+Z zko~|(&5yub#I|=o0f(9G8Gq8R)zpW&PFfJ_$wi>K!8Ke0d~T>f^(G+Z=5;&X4M?)- za~baU2LQd>D$rERkwDi9Ux@a85ziu0wKZ&W=_xP$!oJCQIHXHNkuG=MB69Y4R!hVf z6Fw2)n*>oiy{e6mD(QLY=E_EyQWBhz3GXv1W+e_$ zz24L=%=I7n2R1V&+&(4czJfqf)^y)!JOq+NMO2QJ(sV^t-y_y2@lxo#gci6>B%4Tp zI+G8=r|%}JmO~Tk51Y^vk=789>gQx0n-I!yPT+Nvncm1;{Y)R2Dx8u^|E6UXkauAH zDT68x@Jqtt>hjy)you&FV1nblenlOd5*M;~AI5jP!awy{mU2ucJO|BGjq5<5^xB36 zV8(;U~vOmQzZpHEHnn+m|TohCm zRO+Ur7wDwd?^JhOCx7ZE@y)BQ5?Py?VQuQQP~C?}K8zA!%tShF>mQf|>0>8Kc?u<- zv%x1~&cUNC7g6daTla{~QJw+J%%xMDzIH`${|Lne>mEd~$jX#IZt|5^OAMjubY}@;@U04$#VE^& zvAlCO13l;k*Uatk*#x-{4ep^0##>5Gp8w42k7X?wk6t&Dy_zD4=hdMTlC+vKb}Ci4 ze5yq%A`6h*Bm&X)YU7pEX{DW+&c|sa&|E{=!x$DlwDs~z{lVggY+#l&Wg%!E4K_*I zfK?d9uVE?%8&MjM9TPZxe{7_;n8JE`DOvng2gO|$az84^cHnPcyNL={cKvL$tdFxd8v9dRQ{-MGZ=SLfk?`B(oK>7keko zt~9E*p}A@T`>WILLsN4@+Ov9QqDcgNDp%{)OzG_(TKe)$t|bSk#B4}8P0KW~1~cQ) ztOpX8u^`j7Xu{UhG4XJ4ulff)ETXlN_ITf2Kolm zz=mxA8+Jm{#R#F&>LF5)pX@2TB^ImnNO?_}qV@Qf(Y&r_yk6aY2fLP~SjmjdL(Rh7 zQb7=x`J2vMW7+Ez)Y5h`q}`@}#R6v@3VJ^s#K0a$GB6*{p_XV?rL9WF1fjC|ma{}} zIa&C=8DrNo#W^P&scofqQ!OCW&ZWe05SmZr8JG=mc`yz8rqFl`b@}bP=`9^r>7jAAwc9r$kSKT!!qB7dB-F(4rFEUSYN{(4Mf-+s|APg z`@D$gT137%|LW8d*jq zHUOp!?p>;MwS%(b(Zm}9DbA*AXjO+Nf7L~RbX5WA9^hU&OtjZ1V#XQlb%L&I^HZ$K zVK4X278}^`&dXH0t*0V91?y3gdWQ~6CY42RRqzzUOXN&9z8g)rHyn4TQeXE3cC@#n zo&pRj)l1X$IhQ<4z58?^1i@EEe*Cw*|>S`pYOFV;sPKw zrq({zC`WSP2Z{c%iK?_-V%J_t7W?3*H+py|QR2qRfmUgPL!T^_@&gVBs*F-&x{lmq z{7TmU#v-B#HO#O5;l08zMm$ z@$p%!5;=t?x4$;w<&SG3l$6YU(Y^&uuPCNuQH+&&!kfmn(#0emM6UXaDm7 zpJ;!A7?9H(%q;!}+`nl-B)Dl&eIj{yn(Lzra!Qb-t_K!?I~fzm{WAAkU_j=nKeXZv z1X)_%IN};9H6Ut1!bTLl$}Fh%CHrs;5dB#t@H<|2IqH+xy0tvQpI80+!?MH$A4c3N&6sl+L=FOr-8B@4uJJl1LXSizpwwNQGdA3g>$i}H39ZctD%6i_O54%;S>&JmO%XDyzzjEq6HI6iZzzln z+gb^i84)PbJ;;^((CelitoG!nyA&|OhkTsa@4;ZT#nrxo4C*MtWHPD-R=`x9*vI|3 z$v=$p_?4@|9%YR*C44UvLacL0n0@#|b{e_Csg2)ku7Nt#&fr~2kvs=$pUnk0ur0|_98A3q7%R;bq@tJnTSOJp}%PT>jXno9Kbe7}7|I|QY0I4*L3 zdRs;r)7?!52(s>Af3I^85=^pX*8N1Y?N5YLpYzxL{FqH3Q(#!jOnpXMU>DMU^*~p^ z8Kh^lU+PPw4|b)TN6^0WSdJRwOlK19#^A=n2OI?84HVwed~JQb@3|HMY@rGO;T=KM zt#ts<_?+udvoeeCeTWZE^6pD|Z}9@m$Bk%cj%G~q^4M{hX?>JayHWm%tgNlzP7Z9 z2u#qg_UeCptHg|O%x}+5zruwOcJ?Mn#>>Za0_t!A(5X@OZLFFReG1aVqJh>xl;#|G zuT+P^lF#tsW)T=%)>61-Y(_?xkSM-?diGWn=Qjv*RGWcEc`uaQJK_cm+xuh*Duj;= zInD^SCvL*2fUPE>J90?L^ruuGvIa~RH)2)e$h{(gV zKm;nHm4%<`IU-peM;0sB)S*o1$uq zEyFb=Q@sNU3-GEj&Q?!jZu{r7sSrLX(;cbvaL2*i?SNAnxq$Zy0H1((@nAA(n>AJ_N%jZxrY#34EAVeAJ3v z7ahGw#76!I;V^oaEMYH1XhQ6Ow`XI>r6o!9`LY}{TAd#F_N2=~1B5N82$`p@{WR-m2H8t*O%I z0YaKT&5OsJ=I47Q2-3v33La$aQz9V`=K(OmsGZZ}tTW_fY;059iqU4;kCH`RM-g1HnUwBf4 z)Yam_Flne3;O@p^Z}iP56+ez%N!*tXDTz=_k2VHrc;zMYIP@Z46%PPLHPAbF z%ya$(!bFTZH2SLO2YN$nTxVVkK$Jimf!jH%34s7Xv!HNIr|iz7p_Lh4jI_pRL!;V) zYL-|;Dz}$Ij#^R(EE++9QQo-_mN~|Jfb#sF5_1*D%S)iD$svPz;|6tTMq4*NTom#9 z=}|hWT&M7;L2Yq~U+f=emI0okDia0jUC8q7tO z)e{Ab11S`NMR?~)6g|CyXi#LLoX2|rI@U>FfcWD?jxd5LeZF*Zmw(JvC$qmaKetZ7 zuH>&?;gltgN1E1SdIF#Ct0s&7JREs>PBL?5SJTD(@Q@Tw0l*G}kB>k)A`8xg3oViO|d4_b|A3UfBk;r)deD+ zRpp6fwg?sXl!7uYujlm0E)2}f)FMS>ZgkuFM%j$EI&gBVd0`P&*H75~y&1r?%3}yW zj^e?3vhIm}mEy^JHu;#xn;;lO*yjI~Df2>B0Ebk$weAef$4It_4v&*hG!bWXMSs~f zD!t-}MQT!Pb?(&q4}sgX{k?8uvMmh8jg*c$bAk8<%JRJ)_SF5z!Cv@S@LSMJF-AEW zGGmQDT!8NNsc`fX9-xjE_1B92px%2Fc%hG6g9ikve)y*lrQ#+5f;v7DO0gDZ9ReOX zmqYy?&b3t}IqN`)lCr+79AE|7*+(h}m05EnGK6g(ZxR?KI5zei!gXoqYZD^7`Ww5E z0;atpJYt%3NcY9igY`5Ya!jg@o~wWyyodD&{30+<-=;o zc?e`m+Uk4Z?)b7t?8=!?BFS-xJC;8;{D0sMKOokSRU(?!X8*?~$Jy1B#q(CH6Loh! zy*!bx{TwVP^Nm{{p3J$ECgY1NN7KhUU|mMGvX7q%bb}yknxTbqrwG*n6eV#o%dZ&lMnEde^NuCF&hBLv|PoSw?N;OVC^ zsBwSu+X!u?+qZf!jU|5iHqmi6GXx(I2{iE{PTx0m+{3KiNj62>^I9{q}#*iQ2~N=45}0?s&4a2cSd{xCY@aU@Gf2 zB6$a6^xxeLcmrCiU=U&@3Dv#UtnzSz^M#3Kj9l-_t8%(uk^pT+_r@1`xD#Sg*}HXqLun$30ROe22@O*h!hC?wqLsX0Q20LoAy6 z+5}*(dYBN1iY#7Q4b8XFBOseC=b!ps!MQi$ooWC006Qt1Mkv9I{Mnf<3Q5KmM5n6vwx)+#?yh zr66cbG$>VG(lA?x$=ToE$4N^Rk2|Jz>OM{!Rf_9w7iLQT>5MqNW%}TBrLZ{DPkTu^ z(Jql1g0n3maLsOlz?bYS@n*+A*d5A;sgIuQJ-xbl!%@QxKr#f5NG2TIbKMbTEj-V7 z)#_L41c8?&kL!k0a;>+}pUa&Z2B%X`Qh7!+JUDS)^(^FaPTcL*tiMlKH!B)ze4;$t zq8cH3C&t*DgYfydKbAJS@Ksl@H8V!Z&=Aq^-g(N9622r>?a;N}Gj{v6e8z0PVcpP1 zj|j-BC7r&!QKm#>!NY$RD`2~ci8y48VY{tEQvV1uj;0`(azJTE9*RP++7BmN`w(6r~~P;bLM`W zfma*v-gP*3o-k{Ps)=f^)U1tCgBSm7qoDIWN-+!^T~D_7@!3VdgMl>8p3C{s{|r#F z=;~2_)ji5i!AX0_#&Zu_AIbv8i#c^CqVK^ead2!p+fKE@#u7wCXN*uj*PwbYIR2as z&7mr5@rmwh>nGvshxnRvj4l^7EyN-gux>*J1KvF2k1>~&dDe_8Q{93Q$JwSgZ~G@$ z)2#I&7KB1VjQuI*<$a>QKU{bXYnaM9_H_}OGnLaT1ADuT?iJ|$*B4ZH zJie-Ydi1udpn3MeAtOY6#0cq~f5Qqpvnb($=E&k&^01w{f5?t_~%z+-iM_y0e9HaEfg^=gpLWL zEfj-{HI1>-ekc1$&m@}M3ZB-P454n;`8~4`3V;mBS$oEcHVJjII5|gfd_`{;HaOov zRp<^VcV{>?aMJ6<`6Kx3!zDRLC*S9X{xd@L-_rB^o1JBKSoXZD!wHPm4hIetnuJ05 zRZl8s(vGKas2XEFvsA!~8+ZS=yzC(b0puMx@XA`rD{8C0XsbIc4TAf`$YANBWU)L` z>${g;F;J?`oNHL#JxZsCq4HYbD+ntSa@#k>G_(?zC#mUfMKX`$hrqBaFTdJotS?% z8v;rXe>CMW!oyIH73F!2|99mCYbL67-7Gfy--@NNOLC^)t+7EtHn;KL8X@?K!vdAJ zbGNcK#j(E}7KbT_V*%=F5yoORs_)cf+zts*DC}Aw*sOSI3Naucnf9e}z;rt0=sNU#Sd_H+< zVnz2?Rp#5tWH#zU>WLHUo9EqsJlfr%k8pFX|Mmo&h3eH5>mal}tO;lQwd83(r#z#b z=MNCX6o3?#={`s+aHcd*v?ahnCIEyu6J4K-fglz_G<*;+c^8nj0G;!^17z3$+RW0p2M*?m+4374kCUGqgtes9>QuY55A%{z`Y9x$|$;?sF5E)8?yoa&g zJqJ068B&rLLD`I8DnvDMr!S8Jehmbr90OTD4sdi`gviSYw16!h4=Ji$VQ-WNea(k- zc^t6U??j1tt?0yL0HYRv-klGam{7>NbVZF{Q8zz|7GQ~phX@&svpq1!b!?$9L+1;u znH0xC&n4Udb_`;Wgp2~b6qIQVX%(eY=WGXi9#4NCf>Ep!xI1$R$@j+b-NtUh?*LsB z1?*&CI8QJ+KOYLf2@5HgfW$?dJzC7gfzr7ymEjJ5#iJH>rV#4%(?0K zu)78-gi|J%5j{X;Y(-Sn>S%rRWkMZ$0R9@f&vmeag^Hc)FrjMfGve*>ic0%K%;pdeA_BX`2f2K#Ekr5VLJQ~;qTXE1RIphKOxM2@D2V;cGPRiu&vZanmP$Nn{_ zjWT(}bsR?X%-{-?y(IbGc*!tN$s&E{z2z>@z6s{CUfrz$i@(4x3AnPlJbJ2*1gftX z^GnP7C7BbHV~h?}0T|bWE+HSw^p>-ZzB$~;DhBmqt?L`73g8%2sbJzbqDnT5+9c$N ziC_*|ih9(p))QNFUjsA(9?<-CP!o_;95gV`%xqsiH@5&<(oeP(fDAnBY6NWBoEZ$ z4}+r$B)PSco7vL#Ao@~1PbqZI81gjOb`>6ObqD^SS1+f#ojby3g%v4?_zTjrA0d9rEBx#cTT!Sqjv{#9fjV_nNu4}dwPK($~(uWE!> zJsRQ<61fj_o9bYz0yi z$ts2GlWogyll=3ftXF#1Ehos^9a2+cNC4$Mca5C_%l)Ll@R!!(JdLj|*z#ObK(tv{ zVr;DNEp4lsYi6-}gZX>6n$X7tSJm*lb<=+B-I(a$&aBYo)H=*|%56|CFjjYZ`+Wt> zBNj^9QHITmU(+`6f5s&6!GUXUfce_b55qDbBUr#Q@a|@S7V5nXUclGUa9yzCzLelz zU%!iAI!osr;;LO!a1|6m94`8xYJc*6SX1HyOQT|#mydSE?u<=sD}bx;RDgB)Cd*uC z{B#@;W_gk5mA3R#>^wE@7EsIX9&j!~bI#|R>*MXeaI3alUea}2b-}N9ZVhtF1zaZ| ze%NqWu&7|W<4Sv_2d*r?DlbMXO4R_a4mkX7Ll--5m{8NQk8^;7-wMFBix0jEnrsNU zU^34*7PzopAqiM=ThF#p4zjuVrfU_Xkq&Od{05H)xx@Bzg7(6?7&Fe#iUaOYeF@z( zjdROx$RkY)Eid4?4IO4oS-@KWfKy(Ot;CaXZY93!JwIxL8*royc&S{hd*JaX-Oh$} z=CkJmhY^u>C4YxtlGnr?d@4PO1$k;C*ZKmPhe@C7Wk;69HxmW{d?+poQzEIqji z-V$sF2U{a@uz|J^SDbpS`^xIYJ6&KCXTIWES?v4JA)9^`R&lPd1+IvE0h;!k|KI7i zS_)`&IB?VN{Qn#r4kDnQvG6ufS_=DmE9}B)b`3jfyMv; literal 0 HcmV?d00001 diff --git a/doc/system-overview.drawio.png b/doc/system-overview.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f92a91d24506fa066a49046275b898b3fa9dfe GIT binary patch literal 125376 zcmeEP2RPO3-$x`PBt&*Z_Fk1ycG+79ajeW^Z&F4S5?Q4ZnHd=w8If6OP*zb^8Cluu zy$|Q7Q;&bo^ImVyQ~uBE>gqb@{_XGld_VX1{+$pNCE4A$`*G3G(00qqNvWZsVM?N* zVd(DK2}X`rFC9cfOKWtJ)^W0NGqbdYp&jIt-1u~mPx>JDv4gzah<|*Nrk2L$aAO#!q3gWF<=gduD*U!UT(yIx}^v5ay-c6 z%$+SwVUEbNZ5-)jXJ_qXY5(n@iJh%2%*5%N9gX2|JJ)Y_GqbZsJ~Q&F_TaI;IS4VJ zZencx$5CxdQzwg!eT4;(w};qU4rXa?0bQAg8@a{C7}^;*;AmlNYUjFf{QA%z2d1e0h$8Jgk4zoo*%KzzfA{(l5F}8L_3i7zI z$yu1K>BhLDlRG3}AQpSXE;e?i&WN$&#@3eRwqU>-W(Mx$xTC$XiKVT%!umHUAcC)Z zn1FkQ!NGtF4DMtJbao7RsFR&N7U1&IosK{c1~_`&gjZ5kI%k z#*W5F`!(M@H{$TWqGPZR(nNlI|65oR{~y(-4zo7nu&{GQ>`?~m%_he89YIt8Jq@JrOm!z26$J;6*tm_vG@9o)&n&fLz{*joDQ=wEUb zM>}Wux_g21^Y936T*b*4ZVrRuA!P7~>jB3@?1$Lv$0oU@OTl5*#!i+lsAu8j-b$W- z<=kJdpn|aDuO7?8C&DR$`nT~+kpDsohpxNvtjKfxHP3`Dz3!izA>+q4%_sSP@MfM3 zk@Iq+xamKpejpQsShkJ&MSi4y{_ov*Tc{uMOO#~1p%fH*fU>YX+|C66E>ks_gR>Ub9BWP$)oh!-PgaX?|;{xB2 z9emLD?WJ&}^Zm=>u^?30BE6MY1Q~CB>v$~ikDw(8NPZKK1-2Vn+GM674R1^L6hOM? z-4@mK&tq+#bYQBLCF+i8-HtjEclP$V+dz_gO4G$ zeY>C~9&U)AfHVxb>$ZYRg8v9U-df|^3?K72;p0TY!rwb0 z|04)la4Uo?xXloTo5W%(Y#{-dod{K#~JDq2277rHC#42Q8jQlcn4E=q5%DcsIp18O5gGz@Lk z%L|&^ttIWO?LY@G=qu!tl#~{b0j#DCtD4LSKg*!qcNjelehD1HYboh|78L-y@$5%YegBSBgh z`nHV=30l6DH;U6ipa9k9pfN}-|7f7&;ok;Ah9VVGtPqR$Tgz1l$zJ`)cz=0v=Hvd6 z`ED-mKoK-AH#a9Y${+G6QSF&W0Li8N5`+E=9S~-AwodBEQfX9qk;rK8vi57guM z`&b9^CQ+So9oAV}+i-yPaX0sayn@z1=EqGfUBE|k#7BE~u)+j1h#%wQxuKsSstqjf{hWRZwyhWMW&c3*!eDftu34T?OXo1h+d2gK(m)oh@RG8LHlqLt7!t zKPEuPHGYB-{F#;^&Hs`R@V}^Gw}z3R9Qlhlazn^JanT*pQBmcKB;8P*=%0p>NQolz zFB0THy8X>zBvO2+F8_T|VQsnYSR3A^jjSaQ!FdZ;`_7ZU_gfoFQ`7a8pva}48i>`L zQef@z_lrUKzK*CNm*66X)|Zj0H%mfLtEcbfGa++eH?6koEkdX!nm*J+x*Bl=eVs z8_R_p|4Jm^1PkA;@!f{89MT_BF@L5%USu%%B?{b%A&>zk4>PtgG_f#tG6ZnS9ykH) zuc+|9B^e_XD1`LsKULs&G{8UVfqZ{-L4cx6EMO*Q4J~c$ot+FFjm=Tk2h_4iibmM(~@K)`LmT#RkO(&~Sq4k5ag(9^u2A2&L8O!s9*PLGDCP=D^!Jf6#3%iZ z*7}#Eyv1^q-%rX=kM@tG{M!+h$Yg}HW`1a{5yhOpCoFl9C<)cPd7!BMOQHyL@gE8P zUr1R(^AbOStwK8Kca$YBBzP2S*_yJ1cKkKwu?65-=PbcYJ$TiV69*i;w#gC(hzN+5 zMByYixXbNMTtf2y89dvcDI20JevPh?)Y^|i!H;La|1x#S3z^l=^RNHsE&-DI{@?%U z?MDzw_>n#Q3(3o$84n=nfNa+Iv+#iQnqLwf_@FB5>x&7uD}DKQXb`EIKhxkZQ#;+8Vt7(-4`_0TE_q_oF)UyE%wo!$AKHD%>6n=2jC*GS2qacE+ZL_NHe4 zM#XIp>T(m@|0tdQuV^pGn|}g^`pU{?@(_=}Ux2B`E^znozd zQD5B+oct+G%vH3pbUlNlc1Nf0_|2s)U85wCoNy#mnTzEDu?&l?FD0=;= zIeh=R-G6kNUF46YB4}U)+yu<#49wINypx^-dJXy(tRW~zjBSiTVFG>FmhFz4F7XqT z|7Y6%rL3U{l-E&OU{_LUx5BNC@7d z=3Z#**T_-mkMZjdM*qvJMqy|LJ2Ei{Kr%xSE$BqqxN%h3@(3dz@0SQy7_zA!AcgF5d_ZG|Nc*1Cc<0I zXnto8|H69lXU2p7TrX~k3Vvn1DE!A2I@`5g{5v%G$9i!~4gS)4Q5boX-;^FumkIbS zGe?lB0UZq5PQVA~w=iWKoMDKc|NPGJQA(8GqV42w(CHTSV9bn!r3C#q~W1JW-M zF7%@JAKB=CC&42vC?oS92_DGeex9d6E`;J~Th0XiVsqF67_JjM7BFjj7@PyV25Ad= z2kHXY-t7RJuJ99-{%2bLrSy)_U+8B0N%W2oWKTaqrvFdx{9W`8a@yfXIpAMN@BGYo z@So|OEt3G!YkmnL5dLFl*mk9N{tgWyRr6;7{@2nwTNNHM<}h0r+}P>&f9uNMptda- zoGl&i*A|S>ue|*z5Tj5ue_k;DL>LQ|HOL8J6#IveEoxB%js21c#v`;974}`>{p$-x zXtp0ISsv)^(@2?+z~blap>gfb;cE9MWB_2;$X zPeiatK|*L11>8WO_BW~(x0-4H&gg%6ttj~2gKA|!59+5Xx!$IvTUf5d0}3u{Hl z;(kKNLUFAv`K(`C911}B6eUKj7l$_B7YGowA$T<*;%)4vTfUm`zhhQ$(+B(diGNd-DDW3pgMVR__%q|dHmVY#WlJbfV7pd{e}@LQLzM{q zsv?RC5k0Bfp-TK4RJJ{;#LeHaML}Tyrz-I$VpnA5g~}FWFxy0|DA4v-RgLS5rr>sV z;1{x_4|0E-Cy@)PWZ}m47K(PJFz~yMDEq8$HMKN0ha1}jxS@}}#quJl@4}ww2|R9(L)4u@!bX#bxyyF+gO|1#-l>DO1Z-}zLG1ltB zP*P%bb+yrLbnzX__&Vd}enXdsI7iJTR@dr`_w z>@Q{L=ed5`jjy%-XaV#NeorLV$0VdM*ps3CjK<$Rw0L<32R_hr!MY>=mUJjtdxf{> zo!yEFg1g_AxoXdlvFo6jo0~h0yjHYH;52(0e}RDdaIBek>*8(c(Ay8!LiRGN_11s;*O$K02@F}Klm7N;(A*2AoSZK@CR?XDn(72~h0T0v6 z)Jk6-YDqGw@nnTx2-K{Ty$0YFZjWFFsvrfB?yHX*JpKOW*^~f!;AOG3AQjk!&X!$p=1s zICuJ?M|x3n3`Z!3UQzF-S9d?Q=P?k_iiK%qpQ1lXJ3)x`;aC+t&E-Z(wW=GK!djd5 zDB({|X7A)AHS#*UjnHx71*bM`13fOup_}(iuh5Rbqk}Pz_PgvaX}jaQwyO3xwqjwB zlJpRTusz-JYZR<2vt4$>!o+fo*N+I1aq6dCWZX49aLw?{+~>E$8N@h5`jtM^z{qL~ z&%ViZpEk=ftfWcun!*8Ad7jp19v#?Ypnk}egD1)4{G`vZc+QSi2k&8M9TS5e386`= zop@iPS@tpz)4*s@S*kAzEhx63jdN*sEZ|np%L;wPzE7XhZJDp=h4wcQSe~AZ)PpnH z(|cdN8Hg#v*#2p3>{2wF_MIHr$} zkG-Q~fd1HR%l(}NmL}aTP6zWR8#VXy?z=c@^06566pgqKKF%Y#3jOS<;Wjp1O%~_j zR#ppoO5#yqD;G=S&EA$eTXf_f1d>k0P$Zs@tT-Y1ig5s*d8I!jq_VOyD^N~#5+`qm z&>^Bw#KV(tcHP>DI>^ZMK|$i44EYh4tkTX8;D*(sZqI&xONmWLqfzW&-JW}F#qACM z?oTgMYND8xTeDf;JLlST6*VM^+&@9w9^s*+q%@U!g=+k1g3tr+B|(Mh6cyX2CBADF zrH`d-)pbjq(&O7T7n$p$4+kJgJ4-zbn!x4SkiD6`myGq8)Z6$KZJ176m5Ua2n~>0r|IBO>U8Er$ zb-}W7w-(c5D^1(I7oW&#_MgLWpqo&wju8GxOLzcs^K(#H^9ON*9^J?x=O zu=<;Vsspf1fCJY>HYM(ZYX&RCvKF6f(5E(UxuH40oAlVV$NTQ<8oh>WR$zf7r>PrT zqS^Mr`x|ZzzKF2F@sL~M)lGk*3Zf=?qn7`r7O^FK_~Y|W91dukH<)I0+&2$;VspUJ zLQWdTr-6fwIPs7{DZk6-?(}1mbjXP#lNv!mg~sSR zC9UWC;TEV_J69UL#KvUsNnEVBuNd&x9VH&em<~jv1z^(kH{s}BV}8<_u8s{~3OlNK zFqIvol7J-NRb5eenR8rIQu{weDX6e2UyN)t0Dtt;PI5OHq%V?0upQ_Zq{6w;kZhLX z3&Ogla%p6V;uS{ub7vl3JT}FsbHIO(r5=;m?ziKF6iH7!c|q(54l3X{M*b=MmUo=R z%#%32b)P)Q2Wuj6)`=r2w0xBsF)1e@J$Q7FvL^Y33r8;uf^Z)pZ(TDTa-1*gxIg(m zBW}hz`3^b=4y`{VQ5Oa=f5hFy2GdmDpg@H$Ea4dfRN73O(Rb6WI}7ARailTu)R>e{ z#EE(qWgVvpVe`jJ%Z|V+8I!qpj=MkJwmF)fHzd7)YdX5&&TTbird`o=m-OY|4-MVD z!OEa5BNulxT6z$V<#f4lzYBHTwB$XENEe_P7EO)CnKy=QHo~&uG}6~N4eUR6i$v3U z?0Gk@u*9+yYwJ4ldN({eP{EH?`9-AriT)F$>CD>MauV`4_B+l`7?WO&^pfAP6JJI7 z@t(8phr^AZT@50nJpfGK3f^(@8mGKwwCPK&nj%bFQ(mo-6U+x_3mNv21WN)1e;`T- zx{VTD{8D!1(jsIrs_R!x4CcjPo;49QDVkL6X-^X?ONy?B_WC{pWcVck%GMt3#K72<8Af{h5 zZiD_oIAv(GOVZoaDr|80)G_Ps5D3tPk{JylK`X#-mGe<&!%}rx6@e0=h|-BTI3er^!fAu;&}ovsZUZCpVei#nSRSc+y zA`YMjo6qdJ@>GRR5VIZmuwTz!TMob?k6ja)xRRfz`qyz}fHYxlS8Us6DM7XNvY-aN$aIwe39T0R&Z-YCfC!Jb~# zbv0JGV1n3r-LWxp^HKd{$&5UaS4cpdnn{@rdqal+;s@c`D?=x;HUM|6CtgEEyK&ca ztQc96oA)p(2euwL+(E^j(fns_n;sC=&bt$TfJuzdN4H z0S)B96keUFmwDBGFZG4Qs{=y8 zcf)zf42MrkQ-TQJr*&QKy9Jh;|29<{viu z6YlLjoyQ4kfULdKXy0!pibHE=A-V>xU7I2p4(SYe+1`g}Zw^WLyAcDgywU5fgL2c& z#D^j}Nrmh%r83p0?{d`N{M^?nCY|^;`C(<}i;HBu@76{J7a~P3cf3s~oslxj*0_45 z^-@Rj{lf4)!5^nh=f$pzIH2FV5byoO_<W`CKnT@S-f$=egvMx-d0>Dnhe_na^; z|8V^?i4LnQoYCnc=X-m54;@UWJWFj{Ly~(2eZjW9Yc9B&h;6khe`NFVs;*$2Nwzz9 zzpeWHL*_^PE6riiAKzG#92TMpzL?~3)8_5FiPL$zv#q=Xa2G^#T{_JA#Q1!5&dWp} zu6gLjhCezS@+RkWCT~qNz3=tX;8M;po~$?F7FrLnhoi^PdN`Ieucxu&FA=VoVOT|5 zg?6TNRhzHa7UcA3&%i#E->QSSfG@>sd|gjEqV~1sExOWN;$rnp8Kyd7kGq@INvh`J z_2-R!dPg73$qg7T4DIwNroC0yam!eId9YA=V2!^G?`=GxOg-1mn?5C6FH)7b^dEl7 zVJ&l*Nu7!)N_jeyS(ND|>HGAO5I6TO_`u1TGuh8eUAUILKjY&2+V+%ZUgnCqvU=3# zG-(`V5Nq$FGnkK-Xc`x27H2RU7Ghdfuf7oP>*6%gtej@d4EEETYb|A0C?1&Rm^nL= z2oMW-@Xj*e(a_EB%hi`&QWYZKG)w0S14#EyDT;S+fD%q>yZgry|styXb0Tou@n8n!4u z_NuUhu3$c2%%^K*uTLzW6qfpOPEX*i%E7uas~0;-(K_HxIA&{y1*Patoa3}DY?7>N z^_AM^)n-a}?%cWF2)cgZ*6NbnL;e#LvS(v#A3b)|rW^9?ezI2cLF8=jP2b`J!^_S4 za=6p#-S8>q3Kz@Gn?8h&c{Snpv9Hn{Z)#62J4n5_lJtI&)RzS}@(R<*a~Ip1(#l)D^fq&>m05{qgtjWB zt7JJH6BZV}**mnLqCjZR_&WTWSis(V)0SYrguyP)X(l3@Qn$2~ep%DTd}$S_@k**< z5Ia43&F+>`GrC{A(?0wVubwcenmLJ4rJArYU{yBk&e|gDenD4l|LbS3t!Um%IX1oj z%5I7%Om!vdrIR)%y&e1B4tbI|Q);W%6Y0$@Mr(TG+-@MH8!Hu3?TXI0b}WOR#o12@{uA2sM{8X(z_Y17O3AfiE^moq4f}9_wP*T}Ags7;Uev>L zm;&E@r0U>?xzl-IWGR9indpZ}iGTg2Z`3iL-sU3x1)?-;3e%Mi-xi)bLxd4sn7n6G zaxG@9NcAIlUooPS*35RT^rStt>+}iw5O+4+bQfdVITgH`yn}ie2js6X#Q=X!>ezUU;dguI<~9jk}{_Jax??o1o>`E7d|d$E;K3 zs$&eH{FdsC2`5;-(3XeO9Id|IHTMPW`H~mQRS&{(@fb}~2{pFGM^5G7%kinJjbFNp zxjJND-+9O!z9u<)p0jQ>q~2Ndri1#Eumz+3Q*u#baq|^`1H=f=WxWn^mr%{&! zS9E{I6^k*d4EQwHNT$mjQC&jKu!2voZXV-vZBzb~Ne^qdN`ONweA7moFsoAp`~J1? z8p0a0_YDHqJ?0@v46^)_fGVwg3SmIhtlcV%OW->$U-z z&S75uEPkP$NqjcBt1#5pK&!aUB0jKd)iu{~TCCh-;c(N_hVaKn4c2FZSgo{?(>)aUS zTt)^wQ~4c+$fdo-O@tP4RkM$$uVp0SHIwZc_hc+Kwb6MfNl3mkJ;ZfDi@in;-rtxp z_#x7!hXXr;TlKhZn|RW-$npF75nTn0a-hs}*S>Iz?7jDmJMmtGjE$}eMRA8fO$MMv z5qH;JKTX`+SIGR_O!BeQi|E<))un(Va|3UlPE_XMJ@0;qEi;>RZk3@d14nVduvq-T z3!P5Yd-!n!0%SWX_9x%K;m*iP;Q$}0% zu9j-P)+o!>hc0*qONCks;yH0>IZ3`kV%KGu3KilOS8PNw)Y7E;1fA`A@*%n?=XgLZQK&iMR{H9x4*NiF~P#OM>i%A`a=5U=kSW60#(%WHQGWWC!dOD$ZzB zOHoSAdd8Y&KXIjaG~)^;g+j6BV43vY(;VDBvqpu^hpVsySLO_KGN(*mxVo9oFz(j9 zR?yc9Z|G0Sw~c>7Ez4B;4=tDX|>FoSzLxFYXE>13`NVuYB z(XVx3H}<|qXPcdzrGrVDqUoE9pPnz6Yw`7bk>xGgc-g)@{kq!m#j>>zb`i{-UnpMV zh(Dvun2qXkCbNspux*QU*7vw73_lM^%i2TH7(>{9|UPpp>TH}EDK@MI{CZ#0*vFjVs$xZI&r;B#^D z-F462%yafr4--r6@9a_QBpjbM&H7^dc*2`igI)ZNcVo=#?J3b~r3&xYg|WIry#AO&?xvr8Dw8A7ZeQh5t$K|)%0qtU>`+ACx9r}bi5D1CZZLO# z+va$~%&zo|H<{-%3Y&eM%B=k`CJzyPzD0qLb1e{S6Q}|dpUVkYnV}#N$*jy*FFx9+ z7vC73%#JHmtDB<|xi9(Z_%ntNgM(z3v~=6(CK{P>xZCeD3(}mrV_P{q_f|XbK!skk zMD6u~xsTa|0rYm%5AJLh4Ty`d>l-EY+~S@N&@b^4P`Cj&{tMyf--bG%3zEaoeZt?V z@sLlw_CJY&x!K5K#cf1(I@8{jQK{{q1{gnWru{S`T*F6$FPnU9iQBuc_f(p$l%}qX zzXeXM6KsKf+LPo}hINY?n6Ald<*V^Qsl9c|t2mPa5{-CmTZqHW0x*_oI(p>`&(Q<% zVKIjopxmt+TdwQSo>s0NRnf`Yn%Q;}LzB~Xc#m`!vwAL>wRzrj`Q-9({xKQ?24^g6 z4d`E*U09~kDYL$x!5kVV&VD@k#P#>5%Sm^-%+!u(=NzQWIbHEcd?@EONcXL?-HpvE zcNLDba?KqC*xSDheNNNIEp(!jBmUM-GiCjAOtuE9Vs;Dwj$;8Nu2nz&JeQV6+#@5t zeEtm#0rQ4S3$&eGZH}Z(*|@7#w;g=4Oef+vuq$e4c-X2LpH@`RCwyM?WkJOBXnP+h zQ6j=um2oH`HUlU=*a4ky_s;Ippc~nNXF6|3>Xe1D z6}VnnxqM4M`pR(7yx{m-oywQknchQ>Jl8PFeO7ix$vjh^dBSnP>dmq7gk+NgZCYiY z6}fe2Ym5W}AG>|&#qkmv*H%;_7o$vJBTrY|@0m-w4IVtN$(0E>ZJ?ZXjy@ir zc`&GxIrzL<+vi0;%mw!(7aP*=lzeyCUVgL6|6t%p9jsI3+Ux`BZv2udm^NvGYg+iU zIp-(zbM;n7zC7Y_I6zfaf%EvpJ`MEHm!x9#Gi_yLP!%i6v4vgyCY$@{@KjAEKJ>L7{2ad{~^{N_Ve()In7n{qcD=XUEeE&cri3uYE%D4{nn_QRXR?n6?^EFCEvP?12UHmVV*@z3vIwGP z*Bxi20Os+*=7<%;qrT~bEpkab+17#b#Oylvo%mjl>D{!=jJ@B@r*OT2x8ITn%+&$- zmTc7rz*{S4IIWm!{j(Up`<(=Dg>atVX^B;ej?+8;=3YtZ;8g#-VKK#JkiqH)hL#*Y z3~D*HjULE37w0a;uNaVeK~e1ur^*3x(~m8z2=O-7OIJ|Flg%DUwlto;b8pmSETo#~ zta!kvI0A#O6I_6%^19=9_9@)zbU52uw+hF~VP9(22hqp#`{mnQK0dy1e;t{~-8jHv z`cfSytiki6#~zzz#uWJ3uvE(jW4_o&gvM(!ujRZioIOUdp51d|WS=1}pk|IS-!*;7M|s4+guB+Gh1ydI)Diw@ zWpeAT!NVLuuYUN+)c%0eV-=E5uh?*VFCX_3%2R%To%W{Su+o|X!P5+9ZRJarUD-TJ zpSq@6ui3leYEJwSKAmao7SJiN*uh#>N$ApQt%C(Gue)c^y4MJluQEgLI3x>aefY{< z2CQP{3LhD=sW5U~jA8dX4C~Bf?(KgPrP;HJFM5gq$Co)qMPgs?oSdxN+=sc3)aS2P zfS7%k`9@8u1Uqi73j){atRf0NGJ%@~3+%xx-ICXD; zg6{SAi98(3&$4QpsPE@ltdMBr=09!7PWB6?lZ?YO7xZG*vP9op#b5(hNrUUC5`U= zexphiE}~;$P~OBDC8I(gv-Id#tBFQv=slG;qv2NqPy=%`l^}rL#W6!f1v&!Sx{Ixf z$`iq?(zG0|M1G9Q`czaE}ppzhvtJ!i~*ztC()4xa}7t%(6*hEr@87(DfG2Jr1G`Zye9|+L`sZZhwgK%tMfI7CM5uOnU!t_`1@BKXAC#Rj=Z_5E12#3 z*hqmsPbgEB0VV=^Bm~b-=Y#2{fvZ!AuuxwD5sYs)7Gbpm>o8IW6IxDby; zF_r_5%W<_}z^p6uqj0KCwthji6JOJaWaSONqm8U*#`2%4z6&B{AyUWK z<6W^JdXWXzWfxRU)Foa|waI@EV#dn)yAgft%n<+UMw*gx{RdpaFM`K%C^1s9dO)2qI^OO&+bzEVe&5(E`zxNaXFY>EYQJW`w!aq5~1R6P5}M&_g! zybO(=-AS>!d!L!>=IIWCk3H`E6=}=SO08g<*OllGyr(%kUyoe^6m}+~N#w;_^`gC*JQ?CEhcDIL7z=Wk%xRv_Xq0GmwhRZr zHt%fLu@1$9EUsMda3Ax%dDKhOH#w+yvx(5oOMA7%|J|5unvau3J7J}}jp|HEt{5m4 z=0)?rC}#(xxJIlXyoso1qlIaX9-7{oU9B%jjWcw0bbOWYfsFv`wpSWr{u}h10h;Jh zyuexe*->4EBr(yZrTZXW7*S#X5{J$bOc59O;DVrBk05cHdfvQ`phNGk_n73pkXvWR ziSb3^c#D=KkIf6YthWM$h5JiBBox&|9+g&m(8d~M^R6t6j`Gc@)Z04EOI=evadw@T zs*GB0AlPGG^JYI;!lbk*fb3sX91{<_E=Dvm`%HHATnSw@35$NAMF6g!wMZ%EeP8O( z8c$_8m-CI)$7+0)lZ-#5S}x|9)i_Szm%FVJ*Z6$Is;>>nePm9?Yvv$RJQy(JbFF^d z(?@1)kAa4tXcpB7Vj^_o2`!Th$kys zn0)$Zd{3q9Q-skmsDs>+^*_h8gl}U&5537A18rp}QdbGBFmqq+e z(OrS8ni*9+Jw5HMgyPG7poQv|+vJCjorP?m#VMuf-sy+9pvy{FMC6ugvdjaoh5RNV zgRuPqxS*|z^*MZcP_Z>zPrLBo7`3>MzNV=2Fp0jt{_{+2E{&Yi)Uf85$1xmsYnuFk zw*)P7vUz77tCYFeBpz`kSO(Fe_J#yjv0BDtqI>>rjgs5Kj#IZgW7sG=ohJPP0(N*6 zkIKefd>p}M=%V?$T+%yH+z|(Gmoi{3zP-XBr%BxX3%l3?Bl^Xwhi(?Z92Pz}AN5{N z!WC<9$yB;DvDkK2S5sT-D!X2-P9@-)+Y4Oo;=cYoEt-L?nUOxLma2pfNaH=x;-6<& z)2+btQ4NcMRdKi-BduWz#9)>hsp_BbeB-=(C=g(WtU^;#3Ix%oHTc7IM zOjV>c=rlU0kDGj^?d5PRvCeRJ8SH#tl*CId(O{?L2?~Kaij%ULy;lm%pUSVU(Y|RU zE}s`=-Qg3?{yxg0f{-|&pZ2ule9m=?4Z%)D`jzG&`s1{ z=_{_3DC`d!yH4ymRcM8Ub56h12?q<0thTtvCv$3dC}>JFt_j?&lW!Wbh~8H2?%0~4 ziHGd)dVWWKFDYXrtu`@{WqU4tkzLPayNZRK;7Zz0*-sVhB1RMO_;Sc+Wk!4S?b57l z3@hl_K@^@ij16@wGmA&=8xsPiTZ8rLz5V^eyGn=$-ml2Y-QbPW zP-ju>)EE}czko@B?@UF-k6BS>@Hm3GI+EGLp2_q0K4%4y*>n@%_lpC?=*F)cC}(-f z$KN`T!_O+-V;oRDdeR0HYiIfa3fU8)M#+K-WC%am>D9A)CSD_G=;o)iQ+GtPINn+0 zgGLHPzn)~Z-nj<2cp*Vdm%wZoc)p8hBOovGFi*TO^gZ_K-RYu4&><## zeya%3d8KEt63Hk}e3f07So@xS^~}f{ht*~GFQXlMK@Vr(-Mh?MIj6G^r&#W1l;Cxn zFmm(sWYEnw%~%D!m2H|dYV!BcT~nd;lQy9U+A8#+!1HUczd!jo7ASv z!>H||v9srys}pT!8$85Sy^8Df`k(CJRy$qzY9qnS54)U$_*1X8~tr-g3tZdD`lQNH_aA2goJq@%$tF@pUY@Ic{%lV;xd@yb1ObXtaSEmdc zq%w$uxw|hW<0hBL^~cI7TCm!{8gJ}z$Lr@;(qVNB`!d3R;wcBQ>V2Vm@6MZ?k?n7q zb2)l?(ao^ZC%H3QEt&l?jqs%r?d7)FD%-x^`##F&`$pcuclB%0i45Mo0MG0V*NrjO!c7!G5d0&)?O z7z{6y@F{qEK}TAC#!Db$``#+_Le5aok(vw|m&tiegRL_%6%(&t*Q9)TnZD5C#qsE% z;)n&gJG6mQo^!|FjoUR0fd(KVK8%uSb6Er-$y^Jj8U+&h0(VO^Men~~UUyTwY+U8O zDWw8!B~g#!sL7~AHi*D^4mt6CHL(k}()av6isxr~JUTh{a%^JslcVXA#M5tinYEQb zp^E2jbrJv)ZotaR869)6=}sm1jMc5Je8EyLC%p6n;~}}h`Iwg<50*H~U>pV@Lru9l z?qRn&mSnuvSfCP3Plm`zF#i~q`vOCH>b6BAMw)u+!~82ET7bO47yWWm2AH+N3JmkG z4-Z<$-qPL$-pEB) zR1=+yG3i+cxmAN$MYeA*g3j#&?tqIJ$*FA3=7~>D*V7iXdlv?}osZumX-p8}@>v=a z8sKpr)^N@Yvj#IX-6f8aOs5SBtw?9bx`IYK?k7w5V@ymNz+!=#VpI53 zz_s$WQe)M;QxtCFdVbmUF(1My6Ex7ORhWvKx_2E719Ktd`Ogat&n|Nh+1M8t6xTgi z9HtYb)eWQB(e?g0%+9p&hH4v!W<{EnD}XFIV@I?VTUoJQrXG!xUOcEA|A{YauTP?o z#>L}|ulf=nl#m9psouHrY4*T)qp-6lCGNg865?*%a^s9rY1l$h+mmI zHj{_s63#4+rP*eP?R(8qg#aus7W?ZQV4zWrJTYja1ZyUZ@C!<{9G;C1qu|SsSAadz z_%sQk^d->7n}MSV+MU898D!6V?k;K1Gr^AGGQ6yN->mw@i#>Q`>{SmO`b_urwb8;u zpOm{#Pk{F5_-i^TZprwTJX9w~$nAEcX(NW1<>x4`n%PIPqi2#FI9J!Zn9?ggq} z?|>>61m{BTiPF7#726tv?%ReqzPrOI-NV4oNayG0)9#iO z*mRLi1?zWk$zG;nHM~a>DX)dMk27nw#Bqoq-|T6|>yg&<05FnMAn z-BqNhSiu@?DjsLA`TAg-ZLKxua5c*7aGoO)c27i^9a0MZ#ZrAEMWcRMFFOyLE0T(MmHMyV#gvqm)-8~`No*8@5{Y;deuxXQ>wsn}JTZ~c{Q!znV5~Rz%}Ir_ zgN9$a!tT?1biv$9Tf&FX^+L~D)z4(3ARIwZ35TEU_54ccvTORSAge{4>!9@1a&2li zhDy&5hJK>RN>QaM9x*>Kc)z{^InDAx&9DAzohf(#6qlD0

Zn#Gp`?^~+x8CpYR$ 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�?98fZ!eCgo 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�D`8ZGiQ)S=!L23sI3YVE#)F`MLK}u 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 z zd}L#Sf2lX$bBFg6`#t&^E{a9bqWu}ZybmuF z!Vf}yPhpI&kuKMe=&R}JSQ4fds%QrZ(>C5y!swDmV|DB`K!#j=QGQ&7O#`{g#GDFB z*T&es^S=`pI+S3biSA)B9cJ!nops6+8ldpp+MPZ~0b$|npD3pXTddTvbx6I+O|4TJ zt-*o$Cqoee@#q0Wcb-0d)I0m5mN#yAcjV~+EM-DH^lWnV2`4LEQnBH#>vvLvEnVlS z?tNQA@Vau2aSf~#I!=U_MgHbu_L=16XtB~K)LOu_U#6(<(GY$KBvs3YyI0D+O#ob3hLV@s4Gds;$Xolt{EFHes)>Ia(&6MEV0E_Qy>-Fip9Lx3CV zR3Dsp?xlspi&i;wVi(>{CPUcSN4u?~xGB{S=}_Blx_WV^IF;lyIPK^H+8-jp2&(C*2XaMP?!hG5EkVGNXxff;C9>yp;b0Esj@$=}$ zogt%^q$vBQb(CS4#f8%V)>aA-Luklt=#IJ#B?7D8g4h^{Q04Z%4^HHp;3c=g*ox`7 z7j!MnO_UO_n2(M7RvdPUzbt}(Fi+sY$j#!TtmMBu_#0(4$tSk4>QdI5J-t)?z6E-x zN|OS=r^yTA6JYheST57yfnvWXVtlzz+WJeo*ew$+n}hXvZJlaKZ`=*~;HYu`g?kW` zwLvzzci4j%g(WAShVU!D%-~-e1^|1K0O|L8h49=u1daasSD(Kw%kvKhvLpv@rG}!- z`NUyc9I1dmCWlnQbLe6jNFPY*Q`S#`C`{Q{A_ZJj%^fBRo-yecl0Uk6Aqlf;f_Y&jQ z=fB^Ec_{_@&ZOQ2e_go`3erqdT<0us-=AOKWbCzB{8|v~?%vb|#nDE%r5V%pa!CCA z3=Ik}&+C=BY;K3Vf%2A@kanQdO>JxD{%c1aS~)BrB^GKHzRx<>^HI^$+q$ky@C4J% zpSAHM_b}*951v@0zX7HT`>#G(BeH8%+;ip7K(BKD{$+lvuYO$m`+RkIJWa+vG%hFU zd=Q=|S;%ky&u8%WAD!pnEv=qoy|=q=DcK!HYXFi4Hki-ZUrdmMHt@P_fJ_Z=>04{N zTclJi8#ALH&)`uO-AZSkLfw$?X%M5yLGj(cNlSNOLsM+N0o@BKP)nX88AuYV1=3|G znK;4cVzZhHX1Xqbic?H7TR^KxF14`I_cjH86bSEM32_?nz(8u24BnNU zM~Rx57k>dCIOSNbA0kQEfrXMy<$9g9&-Bfd(Z|=*mx@fi@<6hbl&g{FSr+etqOKjI zO&LgdAv>jo&`k3G_3eb<{qv`Vwgr4J>S`NoV)Md3y`*ZKLWW5RF3BAs6cSVR|0jX% ze{X3nyW*!)C$Prfd2QYcN0={HT2@58_6Z>i_c@p=Gx#uoja(GA7XqU}wCCP$!HZ(f z@Aw1Zzl>l`Q01aFKQ0{~JFefZ`57bG#dTbABK z3buj02Q|=btQgDdTfOI)QPK-&en%?jJ6^}8pxA`@5~&?#!j4`nF<6&_Ap}zfoW7&> zg?fJ|jQ;;Wh4H-pYUB=-660e1!qeQ6p{(ZP_@#Eimw3z^O>!OY|>5#yfB}F#mOA_qcvD)dfgVQ z@VR7Z;3{F`fTlh!W|~%YBLgTv7__n9-dUX6O(OlAdRLV*17yGsnKHo^T6B1quFWU^ zG-EJF8)YiS_c0l5!QSmhgY9dg08|sks8{J`~It8vw77;;^u8+1K z<962jq&5A~N({7jvD*I1V^Bl+|ME&ZebpY?7Vr@Eu_pG~Q+=MpZQEDefhJW10if|h z^3_EME9-{Lqk5A%8os2&9OFQQV~JxBfrZJajRNk2d;|+W=-6(=#|iNi`8WnrasKX9 z=>cN&96-HS6WwfW>Gx5m&74&Gu_!T3qd}FaLG@%NmQO*;Z-C@q-B={j%Q#VV8eoOK z#b=ZDR29JGjoGT-wahmAOA`4?*!t_r?g{Q&ea#;enEW~Uory;AqM%LcNG5PttAf@- zwrURzx4Fi3COQ)3v1^=rud1QvG;(Jk1S%LZN0R>ywX$pn+sB4@QmAJnr?%rBORJ#i z=c{>|>g>b38fR*oCb#ul5!yYr;s7tU5W>?i@2@mx`D6o!f{B@D)*-drT@I zWedU+f~xTpJm9O13=)1+TsjlH_kt3^g$-7ObmLF=@N{p3J(l*9mNg^=rb|?VN9Ds- zEza`#zw}1YP+#~1THdt3R#Js!zfC$gMnp=E8=x&eT_9a2)a)zFiiy5(epVZD z7OgGDn|^~T$mqRR@dr5#)B*4L!h0rGKrI6a6EwkV<|7(tmjY-(gu9>=(#^#Mi){Z$ zgEG6{9#@ zb~DGKGYJspV(+mu`c$G2kA}-7$$T$e9Oa?!FRWo;nzR4`ooQQ45|-dLpARR7kpMz` zp8OoC;SQW%Nwl7dgY(|)Vos8Uix0f(MhmRYAO+^9Z}QSJ zpY8Xg`}K(tUHpO3dvy{g3yGMoe>BQ#?Tjx<1`7&hr+~r2G%D7fC2w-qOjf0LB|pXU zYcfHCpsilV!_z7Yg3E zGFmIqaojdH{sa=!_6Ga)3A1V9?-3yuM%&DHmq%DK9Syv43$vVjH4rrA=eTtIIQZIt zuE3lW1M$n~lX#A{@*e^OXNV3!l0?LMME5Z54uL3~Ajp^)2=Uzvai(m{FQr%10JDci z9b1m!f5Ls*tD&5ugoJI}biEBW8pZB*7%p(?abLmR*6*kjy94L(X@#l>>{q3;;bRD& z7)GKBSH$(=mfdzY?JT~RoIJ2Ohv6Qklkt(Gr(l*#?RgIZmxPdmg#W=lOcaP z+@d9;tLY>z-ICmQj+WnV>NS&=10LKP6oT|_E+sfL*=WXa<{?)u3WjI z!&`ARQG6#QI;7-$D6a-YQ%|_bU1i0o7h9-vwSRlrNt^p{FE&y(nyeK#Kq)Om1q~~2 zXfzH!W{{)+-aG|=4KV7Rh8VXH!! z&r6yxa8n_IFnUYdLul4_c5g;|$D-L|+mv8`*`%y% zIxO}0#^q;l!lKqOfjFMksn#fYdF(fRQmVF;v#izQ3Zv!%HN0+3&MA>xNsyT9>&uEc zcZ#!{y%4HYst+d8gnI%+K$vWKqF58EFCVfxB zWkpDbQ0O|*R{@6-AVK25P7rOz{2I@pqKVy{O$tJ~_3ls~$**u&fNYzR*}k0kt+sJ? z_PmK-Kfr9k&LA!((d`g;o6np6+cnH)Sa^3d^0Dykuf4r|ZPc|Ygx|VjQVSrrwa{vz zGoIQE6l5psoB430^TxgK`^+Dq$L+wKqZu#m#uB&}UO6zTpHUFaV=UADjaKAwOcJSe zf*@aR&*>fEsFQ>YyuKAx%~<-pwA)Qj60RA}93_*rWCb9sxh+(3-)A3^!Ry*xl z;STS~8UpT`g4|?{c{{>PzQ{|z0BU&UoAAT4+_}T1=V}XQ&FWtiSAM))!M}h%-QeXB zNd#8s#?RCqyy?K?T?3i^M!FaG;Wh;XVHjvE+jbc^AT1L1b@w{U&pl;CJpz{hH6OZq zx^47*Tp|Y=0nKy?os-D4Nu@M}JS;j@Y857pwLyLIYmj$69iEd`Zsl;>#w%q%7fyrF zFCgFkLmbrQxbm*mm#`1|h>A-ocYjQ;N{}Gx#8sulWCVqXML`ZwGFzmx_UwrMOLBL6 z8#6FzUsu)ac&eBrR-V~#kyol!9X(yxwkO25%^j^&&0Z~F zNeeZ_dYj1Ng!6b`+P}z2F#n#esO^zsbs>h=G$853+(QNX(BskrKCiAB-r^ejj%?GA zohV89di|^qn`-sqV=)Fj=^06{eTDugX~*+iIt?Gl>v~QMI6nfN66YQ#+A#1lrWop8 z=){kqwxcfJBs41sFm4EK9Jvzj65*C$R}4=7^GLKUgy{MCu3B-Kx_bjkL7%SQv@D|i z$+jwLDUEa#Y}?D4tV?EL#Bqw;_U;=CiIubC4CuF>ndmFHNjXFXj6y<9_G93aeEA?( zXMWB0Jp?ld2M?*FiEWA5cn!~}C}CqJE608`21;upa8CE$llZ-w@5`Y{o^@B{xSXvE zR*L<=m}=aGP!$naEEf80z0K62_dT&Q%;r{myw@p$Uq43fUiN0(;I?+Yco=dsh!19o zgu!>DD1nr{hfhAb4M}Np-(b|pGIkJ<*Zdon8L>_b7l8uikMA4c1MH!{umMtyx*S}H z2npe=%a0t6%P+EQ4_`P?>jDEFEEi@3C`{+prFVtMYuEgI4Lr3{tIZLwHQ`}P9=XJu+|G2NshOO8QY)BG(&ODgQ$vAfvb1E0G_`3|RXZ;H2d(8=s zlgPQxnQ5pZ`+?BAp3!11B%Y3;g(pc!3U6K^>_kBxl#khXCiJbg{sb(+L3o+o9JD%* zfls*>yUy?uD25JHJ2U?alOV9qPHQUS=HAu>Q~_XYUwLef`ZL4r`A-k~PKTuiQXT0= zC-Z+kc>)-Reg|t#)1crz-jM!o5i0U+cDWlkVwf+z1z#oUw zU@6YmB*rZ~rJn^BMg8U+gj&e@-M;tPf_fcB8bf%U^?KanrbL2^(!V|aOpShz`Y%>%v zZiFPxujiihlJr415*)8N^i+8jvVPjmfNfE^R-}o);PEU)R3gZsiq~`CD26<18*lcj zvFz#V+uVuXCSnkj7Rde}JDcXxqo>{+goP)h-k&eB{vHiDpQ%;8Eyr0RV{L2=O4pW#-Arpr4RTVcAGjp2~0oaJaRK)!i+J(r+IXc>)1I zZHqg-cJ#2X;U&DGk=;%af!8-4vBhu=&GhSg6*M*CL*Mv#CXw1YmoF2GiHWWK8idF< zmHynJVg=~0c!aqDC+K&o8S5YXZ*U27Xm_YYQ%sc^u>wB)RoHfh|G$y%8-svFx2@9l z1O7~67ew{v_Ab8%Y)qE&ZV}O8C^mN}9x`9T1#%Vr1;3ZH;Ql>x($79WM8WN>_y;Af zNq-Y;`1fOw;)mOO#}cp(K;3?F)sA<_`@wyQYURkcdX&E|OS3Wfc|U%ocO*67G6U^w z)yA+}@ta75oNS!8<}3rl%+mu9i1K=&lm?>6icG zcHn33N_it<5JLV)Q#vB}{WmV>9y#tkt`#%K_&;w5LD$=7RNKwQ(zz7H^Vxig)kt&F&C}1I!00BiQp;sYP6|f?LG*OCzA^}26 z=tZzlga8VmgA}O=odBVHJ8_=h@BN<9>w3RGX090%bKmzl=RRlewbxoZxaJt?dvsNZ zf25#8!D(nCegJqF;cT2`VGv+d=iGEW53Ux_1=!OPsAx?wuaj4sff{tqu#MHI%;#n! zCq$4LK-JO(MyX`^ip$AXJ)hy}GCDOP1Em^X;x$_X)X%#|?1P*kLK@Zcs0HiLo@10?m0YsE#@STl0G*0bAnu)+`zH6s-OQ)701m)r zpo{{#rjr-ax2_VpzDgaXuCj--0<1eDfCyCw zenkU5!r3 z8daR(zQd>hxZZr@rK!5`nn-$ z2%U)iPmovrg~xd-%4SERkIQU|sK1DpV5q!@AxD>-tq~>V^uwEymi6 zZtk{vv<#rqgVuCbmmfjr2toQP03v)Ix-E zM-)#2!JLpXw}FQqAHgYHfNsV2ioQAfWI?78l=~R&F%K7zrd0Ezef9u%Iuh-#+)uUF zui;Av5YQB_Y6!4^tQUCP-<)VWLL~vSs0N_)A=vM>=J!!vKo^*Z5D~v~00Ky?F3(4l zVpU!7z%Nf;n=k-Bnny~@BX6iyz$?3&i|_W2BLSUUTqBrsuB;R4;2}c<^3O8@2vwSi zhD|3iBl)7&n{;D>F&tK-JOPeSCe5?pu zrrfFiVNhtQq4lo!$pIjZQ$cZOoG9B15%6g^TK!3ivvB0lO6V zT%d=9NvQDZr8Ir)1!c|}XwJ|*X}1|NKDY5nlB#aaLtdOooiobdr%CDZ)yz-x&_f~_ z;7^x@38P7`XBnL9YH~UAqs1p#GxEQP_?vKS9+3rLJWM0R@5;9$JxAhZq0}M{;Q`nb zIq=sK9ed5le%!Di?^9!aYo5$ECTTbb19U&s5zH@%G@%v_JLHF^m(D}d^zw-#_lVj! z>wDeCL*vn!MRHtZ9G-JblQa?NaW2lN*|`6Qd_yCafj7QSR~hx2rW z7Hrc)f7tT4_W3Z@;u~0tj^(AsTZC6GgMf0pvXEi>5<|Oj57Bl{A;O;0#<^g$0UeQYG54UTCV3TVI_hZjl-Rx~^U zpwBzU9GYIIOmxx;si#pI8dXg_h?6lES<{+U!mDiNogyb=+(oY{;=u{aVQmwikNO&| z9AEkYH!N0J&f2El0NVg=_#jW6$aDFgm^ZFUrm&>O)OF%=w~L*vMmb79m^w62zBa*5 z%xp+lucOGWz&f!mo(Vb%rM!$Xvys;GiP>6w2zsV&Zycwwqi2s-h~E*5SAvtEWk?1O z9R~-9o`+lCD?mcN=Tr5sm?$>|veZ(58(G3DnK~p<*mG;P%wIMY|9xWFga)I}Gwf{6J zY_jy;dJ~Cj`~6theZO{{fna;oN>Bkb9y>^4iXsz{$Nr}k2yOG&8yf2^%-RvstO5aTne(T|oa)H-g2-IN*i(7EK5jy4^X)};oYXe^^8JW=`Gni-F4fwmJcZM2E zmVQkcoY+*MxMQ7GZ5`^IsIAY~E6T>d`I~AIdph#GE=$HHe0N_fp$&nhB19TnF$IeI zD_@K@CcWaQcv_H#R-7mVaft|3du!QjBOn*1{3$>oz4e2&Pj8Z7&N2llr!=^|#Ul5V zr()G6-3F?kiM=b6HLx)>{g|P}y}*_clISSp_dsngAB2q`Bfd0l|F7Wb*Z+#Pb8SP6 zUklk3ApJ4#LMvGMV)@TrWHZM#16%DKGSDxDPJin}E{2}RgrlCt!7f!M2qBeJK`9`G zNA>!vQcLsouYp`d57lE9x=r0E(Kf@6oPjz3m`_A|F1mFSbSsm#rh7qalswJ(mcyuH zHl?k+JS5vu|K7xwFPBXFtXT+z;I*OXsviw_V?r8|H@`*MYij|q1h{8mtn8bLJZjcp zK(Py>-?V6InXfY*(lOS)INaczP#~*0x54mNFAV@GhRnubcEmATspZM{{yg8_4NUjKT$Cr@8bq z*AkGIHwM_Rz8Ho4sr%H%;|tZS=DqWy*h#f<`|7X{4o_&~eyD5m?q!s5B~LS z(ZaxU8{i4>{j#lHr5@73RwAiB`RtQ-Rqgk@@$B3I89~I1Y`|s<7ruMMG)1F@!+_^* z%T6myoGi7RmF3#{VgjPoi0`fBUa4K{h&I*Dv&wsN4u6$@{!)?VzBG|bA`H!ZccNuK)a@k8OG!!fg%g|? zMw(0?^2<`wbd*B~$vt_ayE7&-UT3`acco-OJxn+S0R={+gDwiAOi^HEuW+SnTMMXbi%R zbRDY$&0{*jo+3jnnim>hX z!(jt^9&>y9?;|nMZFtzgYDFZ#X5?rJw=(p(99+NySFV_$2cmuG7JQ=|K%dV&QCH}u z+A3_^PA?`t^SxNrH+g)5E~&0(wP&(};5aUvQDv%+XHPQ9vGkxk(_pVaoB<>WEuMzo7sJhXP^$E#Xo-Q5lX$Ww; zd%%5HOwmrZ=b2bYao8I8J-WaKn8@OknBD1pUk4#%U1}6#JF5Z>Oft@*-?$nYcUtIf zfx%EP`rA(HnnVEbtoDL2oaf{#12Zop=*~y&KpEhWm%v|kpgZDJ8@7IdlPJsHM(=wY z=iq|1rW4(X9wU$=k#>mirdUxF_2t8jJQa2*9{ zD^ash_)k;LNTh8ABoHSSK>uWGEpH<1weKBuxQNW227&V9%Luzb7pRNpz0M^jpL4#8 zya&f>KcTUu{K_|~J#RIirO_0$$k@oUlfMQCVj3J39u9BL^2jCHA7bP^)Hr$}M`e|1 z%MA$LO+Hxy`}FwYs%9tm(`ZVkXF*nu*X%8qPWyFd-ZCQp)Y>X%Wrh-F6jkgYozIV_ zU=+RQ4)V;`2HCOL^Jj-;K@T1mTDNCin!e*Bg4Wtp)z-ZmDv*J8EKU$vca>UwjiD@T zBd&%^BevZ7+s^01&n9Xv;85fl@~k@9mf*AV4%&2`J{L8k!UEEjl8YHsv@ z2J*@wm~Q9sPZC{sGa`WFR--Lj|9tbVqeV^~@nm_#i7!B68a2jepu-AI_jp;o;TV6@ z#V@DsyQiY8!hG_LZHw*5-}sMf2jmUT{I8ODWIDvNO^1h4xJ0*UvBvk!XMdUT?!57( zDWgD&mFvu2HN@AP-=2Pu8Sf}VupDM_szj$e-WIqnyUl1w`XraA(<KpLFD?^L$p6N58hEyIfvfY^JO7(YF@8q$G@QK$?%SAe`~8+5pr!}G zI;(ll-d~@eIS(uS!o?D%^sAYyWC zxP}=WycSnO2uaJBJ^p>}&GiwIa~P`y+!tAeS zB=1v0_+0XN`KKo^;b#ufcur%%M#g@j*3S>&(TZ#J&i}^WekD+9&G0#(YRkBn2bf^W zeO{PrLyN(GrsQ9LOYP+*CaN~dI?&I2Y8iK>leI>c{gP8t#( z`9@^Kqd$$2Gc0FVc?Y;3Jz@e|`;_61lI7ni{o%}Gd=9H3IX}&7FJlw~Pi}`v*ol;3 zPT_Cz#E)srSx%QZDD!I)+~AHPs9iIbe^^FtunJ%qHQ4?<&qV0@ufZehcom*xjPP%s zdYdG3*0OWL3b>e)z!+qmW!JAee~;8LCkZBD1s4PF7YtH?4Ez8&C^qi5KM$8=ECWCu zFLB?GU@q+Nrw|s*#A4$A`u(f31J8Wqe$&#&%r~d62xbv&;P7h|{^l7zo@371S?-Vs z<|BtEFfI`18vpknE&!jyo70aXJZ64F)C|UKAm~-x@1Gc2M8li19}(Jm=f@}JAlAS# zIl0uJtQ-290fifUz{vU$C#TbqXPNWL40NVzN%hR<|8L+FR>46g`m1G=G{syMEO0+Y zY`>qc0JX|rZ^0t&`SxFHjtkb@h9f+iS%3ey+qjt9<5$!M=I6|dX+3zr|ED!Q4PO`f zgg6Q4(@`*l@ft}A8H`46sRKplO&V3V@{$?!<46JJ`jzbKnoG3ax}58uBzDO=l+fgO zC7wrv(Z+d*ZU(2n%+^8JprHeXPp&D}O|QL6{Y&w$jt#qmS4E&**J9{#+qn{)z{qu`%k@dJ`G*6R&?&^_=ht0@KY|4Z;h3M9{(=H>Q??6q4Lqbjc7B(NPt0=} z(-U2Px2Aic5?o){^{iwTgGYI8G8n6E{~WugitVU%qbN|YV^(HKs;8nZ9rc(vxdi_y zri=%>n&!9lk7nRJuL0KcO(<<2z43W-q1$M9F|m8RUY=hYd^s$E-_=8JzrFv`i+x}b zf4blZ7>^-~+(!3;Y4`Nn3IJzgDD;FU)Xu`n*Ou!FK~iGEXtx=A(mC9u%%{C{tqI5y zV5=_nqg)Z|`)Ahe3=UF?%9kwro-TR)f!Z59*349^6bW0CD&bwBmh2{yzIPo_n~? zprZY+Ls!lK_9PCVnUiad(+_p8`4)0zY_LgU3B2Rsk?=z0yl@ca`~3>r@gBjFrDFm( zyoL^%M(zHn-siWvTzBK?kaN-xs7&pqmVn~t9Nf>%g^6f!Fhda7CeyecPpQ;lSSd?` z=bC2{s;6Y>wGhIwW6mMj;>J6j-Ny$d56YG_UTc1P3AbnXmQ8yOf#WXvESH6}iIBWQ zI=2RPe$2g|WeVk3dPsF;>MnOBr3aF|2%toos4Vu~<)USx@ zDDZ28%lS>P4-@bxlW;60TyrQK;^RRoTL1kLZTmg-5L8`P*9T$`f%Z2V9u+I==n70I z=~xwCULvpYXBSjA|t@{+ta531%bz~)RDrsMeiQRw4V8*Y6`UT zbJa99s3Zgq9)fa%((tQyXMY<*#OY{3g_~q77$X;LV$1y z#%`&!p?JjM6OhoyfzEX#EmXu`3D1FxE#*yqra!4dxAQd!T={xz9cyhwrxz$9b@w(#SVEWC9p0@2XM2Ov(d9ZYqT&pUT~HTN141~>Y~D8U z!`#MfatWQfe`%&}y=csFeN!L5+3nN5<3;8t8n>fh9G6dghCtZXX*G|2`5K$Ku6XXd zqLUKiv1G;8%g;Y37mC$4SBAxX9fa{(*e22Hb4EL_p#7wxpH!}HT$M7|+A>bq~J+j@a_L8kHy z?4Bux+1EQ<=nD4bK9_-jAh-uXB$6N}XhLA4gRAj1^1b))+w!rWJP>vn>Aikf0$CoG zVNkn;#q2))wC_jV$BvVQUoxtUT#S(P!u{Sq)flH4r7YKN5(pWioO{%wP0x1xhYKLz z*-nwASBpI@@F>miT@x`VwWVjD^%$&+*43zJ7qC=GIsH?lC;H<)gp6590d0lh_fPNJ z(Nm71_e1@yAaUjsf9Gv~YB6V)l}HzlU{BMDx?|mI*<=Ak=M(6_@<#eyT(L);g~g*T zLVcAy0xC0Mn9`ND8(w0Ejl`*-zcUfMt_T@h)0HH3@eC;{h1DLDZ~p_5u?VqlwgNEE zae+f;(jCZ8(%=>Os#B6YTMUJt^POfQ-w?NnM1QkEGkU%Jx~r=V<(2PNZqEd-pSz$R z3{mhY#o3O&xl{P#LN2&=S_hO|zPr$oc|jpZIpAB0_T)vdV8US$>mv&$#7$PD?VYeR zy`ix13`&|$^jPfn6i*%jhZm!~kuj13xFfs=_MXzZj~LG#$JW}B(H@VX>Gh_MT(B

%a%<+?#%=(~&H38f3fxi#z{!_8hW62_H_Zv-Vmnq4$ZG>u?P3Hi?;b|KjwMV<8 z818k(HboUd)@2z9%CZmZ5sM!St z0PI^p5LfTlH+~-97(mhF>uOEYuPa@fC->fWM%WFQY=Oq3nfNC z;P3V229~!|xB|x1efFmyv*4HSnL{8EZHJ(Yt0{n>$F+Tuw=+C2J1pBsY;`QcvTq8o zpX>vSeO$@R_m*P1xA*eg`%_v5k`-dy0rtIvP)N0@HX)bpKgE)@emi9IE-BA0=VGL? z=WJ-;IwMhFT zyuUikH4I(-G(bPKca^^NJF=y7AF%itVFUx>O~%sVd$3C!6$=`;*U)(UamS7#^kX*j z;)V#_C^!9LU<0{O3V_)DIwRD;I!no*YB?zUguU@@Ed#H)rY@NPLg_1CHgjwl^nJED zY(}Dt3&IkfMrGMae$X#=$HC5_cc7m~6kuKjR+ z!W1+o?sl)W&PFToL!oKdD~H;f5T8zgqp7=zR`(&k zJIj-Mus|6?mDEogsdU9`^zHw6J|oO5 z6U#wr?pw;CnL+V_aKo(3Cl-RSemV9EkGqAg=x7M1ZS|DDc9XsWkKvH6(q%Q8bXjUf zs;V1(K3>VIQc+l!+nOGz@3B7prRBmXl#~dW#HcR)v}?_JD;`TfLMGiq-xe>;Flr!l zU&wdddI$Uj&J2fxf5^z%7tC?XgpqEm4pwsvuRUD~4U~v2LTz|THrfT#b84SH^s8fGqTu{hzYzjpzV`;qbw02s=uk zv=101m9ETvBMF4pyG7ywUOZcwU~%?7b5~Q7f^754j(yQgX3}q_zF!a0+f6K4OAu{o zOI}7{#78Jao>Xk6=`0XB2b^pRj{gD^HfqBcE$TVn{OOnW?i58JBlUPIq;~&<8Evy) z@?U%LHyjDc*w_AEm&kpVzekfGlv1GJ)}eTfMeVS$*_&tR;2LJWjOcW%{=hp>D zw!`O{7sv!ma`DCD$z6X4ZJAIFfHgOhoOd$Or;iY@y<8j)`-SBEYbgXK!{-+fFXs#t zbeU_12^M8nR%`wn!(d)A@FXu2Df!0!`4jVw!b2f*Y>w5A|AjsL>%PJ>nNUo#X}8iY z=A@;=BY%-Nzz=Hc->!@PGfZejhmVh6lkt^v-mpl{JL>#`)BgQ;n4dGgp+9?uIf~AJ z*a;m-H~9njwC%n=3j?7uG}SZtH3_4PN$4&ds`>phi;e=W`{gRa2cpKB)(nyJkj4&z z0QJ0;rsm8((2+jhf5|KiyfrTayGLZsNb8Bfp?A6oAXNCgUjTSzC+hBR7aLlosh-oj z(eOg#Yqtd$Iw(CtIcL-U-?4)%bF=**G}NV<8i< zYbdiN-hOJrYive5NCfVS!#o+ZG_>* z0BE!;2{N+h5JOpq`5+-{Jp^6Yo&hW5(BLuCr~F+I59MHKGVk@0!dI5Z@epZ$a>|DW zb@+W&4JJJarrOs1h37up(XEbiltD(+{h)%s9m~=sAlv1vv`Lzl2i6 zH6IFEcI1sxdEs88tP<=+p#l{S^8aCP9x-FugA7CgfEUe$t_OUdo>=HnEn_oZU%F30 zwE6pq9lPIZx#9LSSfvdzysQ#X3r0WbWt+I;4geV`9I}kU+#8bVc_ade^hbt2sk(q4 z*(z(51;ABh>4w=7pPvq@iX17^`%AYZigc8<@8I6qqrV?c*t^a_v=b?w#^MC0f!qp3 z6uh{%?n2OQw+f#4zUtnX_@PGxTbcMp7`yU9{XF-D6ZYN)m6etIfQpq2UxiAzm)G*> ziy2VNexm32Fa8LzTwQkmp>9S>bb#6}l#z9T&Lq_1Y-~LPtq5z|vJI+cV}$q+5cz1s zk-Q_~+Z*3dN5h@%$2948jwmJhua^O$X5@$vs;V;~e`8=h5a>PiV0Qv@pg|xo%!d-x zgJzo3jlOZQOild|8@jtyr67|uSQxwR^RX4%lR3G*vXEQ7`TD?z|H;pDD$MUSlNQqo z-NcVT5&U7j<40S|5-=V~2NI+h#JF(3%$9J#vSiMZ%c5vnmOV)v&e91tH&i6KEh+yx zM*h9KsU3!wu;sx8#KdVJb?&y;RodUm+6PULZ4$c-80;*gBDdJb0&*SQW1j^bpF;)9 zMzX~iDxvH~C5xAM)XW|nj$S+cptJ%s-i!SKL~-FEvjor$?ozs)X!$kfbXCNpX@EU% zC6I*i9G@x4S5h{GA04_h)1WA5dd@zw7FlBz7*4R40f_+jsMK><8}|2(bh(pFy;o1m zBm?v9@z>bdB9NGo^m(8!#d*|9&uGUfph;au?U3~tW-u(Hq`b88aXQel<}FQOACI8Q zJCf=Z$yidM!u!i_if}9AU4?NRdT35xzTVS7NdTi<8Q|{i7(-z@`xmLdg*?>8|l~0Uv1A5w1wPL7j}x`U#Y;$5R)<{x*z*CqA;s zJz;u_b4T8x9RGDcFA9My=Ii)Y=T%2gEQko)shnGc8e5CITSg18;5PfT$hk8iWb69t zStVo862DGD*~@$WlsB&sHDyBwpf~*i|{VHRbLl_Ju1G?~>a?Bs~opdSB zmy`Ef*)Vxh1S|Cvg^st%M^AJYYuOvuf-P{@3VU%#P$HN-MMIh}_R>!hyn5UM%ipoP zB@%4M!Em$RWp2drN=C=kqfULI?L_-x!RRMgkV9T~fPT`o`VT_E8@#>_1MGmYmIRlK zR#2~q0pRN5IzQrM zz@l=jNI!Zyf#d)DU3^+n0*h{~D@o2RK^#K#*08mQsDyaZ6U>qcAWWX7ZFbVBY#9+F zC8`WGEw9ABXRo5L&(!I80kMT)X!B+Xw3Zowm_t^ixEGAhAcPLdss5f+4Cmne*ATy} zf3iZ9+^QGIme9oY0POl8SYJ*qc@>#{^eBJ;ncaCo`&-xCpi_2FW8JZGU`2tsX9PTj z?R`{TPzf@Hj5Cm3nyPwgV%Q4XCRyMlrd8@nq8dv(cx!gKUAP-mddt-9@MqnJf zJ70_u`^`d^n>T@e4A?;vmo{d8Okbuk&-Iw)Z9R=|3LShNMZrnhri}urtZjZ)fkpo8 zPC=V^=a#T_VD2*aLTqm7>ZuTOQomxVIg1nUh>si6zp~e67!$5NeIZkjbK}#)n=+yz zpzce)6o(Y{K8Qn}poY32?0}A-8es~OZ2K`I)D~f-)CT!cInNR3^%T{nwbwVU0|VG} z`YaKtk-yVnU7uSYoK2~lp%dnKhmWjTiQ(NY69MaZS2FQJJ%D!~P%IO@E^U?V&=*(x z5no2vI0Ll=@?v>zeUx-u1350!rR%dCaD?rzmVN22%D4Bt20#ieD}+D*o2#d%%6&hT zojh#Qe1;~@#vO3C9&e=#8W8m!Z_N1(^4zE%^;nc+Z5wUhV*CsnPb_;$V}Zoz)1-5aun_c!j81qH zI9A;Aa1Nx0<3$O5tW(unxKSB145_%lZ4YPkM=pYldVNUum)ZDUAbjRe} zB_e&6hWzKb58jy9-lKTOZ%f;$`(t#mqMpE>EWX6fVJm3KGhervvs8Arm#vMK`;}(A zmY^A*)tl>a1A`t?8+b}3tuK#{l^YyUhHP^m!(REK?y%AyBesJO$4g#O-^ggn`@^^u z%$7AYB3{juuluG*U%OghQv$5Z`Qc8vEFnGzW5B$mW4y=S+sdd3AGOR1PK_k+PP8n1 z@LO!;TJ=lPGAN2WuK=o|Sj8gVZX1O0gQ!Swzu zeT%`IS^2g12jmV4;#e@#m@NSS(2GF@_8DNK8+@a{e{iDIKWme@pd-X0rl=v2fC5el z+ShjMpxaoPe{cc=^1UxbB%J29Ci~cDxHyBvF!R*Py9B?eXtNj6BK{>Ugqa29*MbOo zPZg^b?vxB98nkdgo3aSYA9u2Uk~f_5Uj)XFhb-z#>rbDmV0RfqB~PktOo~D(@d&YX zm{4ijQP~KsBZ}n8p>uLZyaTo4D4;+N=^HBIX)C}$>xwb+9_2N7FsT3$-d>QUxSb|U zp33dj5=S_65})8M5azG9ED$p%l&K2oltSOu=Tb%&Ix!;ds$~KNOzvipY@&%aVuD_1 zVV`_srtsF}D~OXmpq>fYy#lY7qqUPyN4z<`tBmhEpyRV-%VMGlJMu|y%qQhZR#uh? zntVl9S%l^Wo}vFl0N}a@>Lg_1Jw60<^8BD*+meAom#r?uC0_m82w`_RUVo)Mz7(k+ z3sPWmZTtG)P@ksCuH<{-&AAVNK3P4FwGYQz@k7!ILJcqARO$zOFjljwfANX3eWI7O zBmd5Kd9}?8Qe`AQ*k~5A;!c#l!3rBRMP-y1@_khFbns+x0)V|ZYu1*13jHHhsts&T zU+0gtN~GDZUtd=a$Y6J~Bw6xzW?7U5*DFJjwY`Wuc8t0f7>dK*J<;;8H#k!quRlz* znSBilx3Rd0Wc!Beoo>7x<@r_)dzRhRtuhN^IK1^X@4Gmz^^rGQZ+?Dkw4G`ZI06z5 zaY)jZhwk}zPpZ-{oOat3rR>UZ90Un1#TCf_wu}}%{V-&<9ri3eKVTsP z0qnpG*0wa;s>;ecW#!OXCKY|_?@3m)qSTpJhb`{Vv8nFcZB-_`%UGsb9)2g4%v!nr zc#j|wcqI^_U;E;*)F#`WmWG?H>9Iu%k|EfhbsWNhVn1LfqF$EL~1r&}Kd3aQ*lKCp1;o&SNzf%%`xFIQ9-ZJT(`r0*a(tZ%6DNz)cgK zN%7qRd}LSBE$O(sLHj?%ejIPwIOKoB%#*{b}iM!5NEK&pNkj4C=P}e zMcZh2tu67Zb5wvZ!HuPaqM!^lM|-)KrrrB(Fw>ss1wrSa>wSS$UW}TadazGg_2#{Vf#nj_3RZ%t(vJz zQ~o4_bi>o+RxT*}MIzVzDXmtJ4b9bY>Uz;&(dMnHYV19hg*D7_Tv!l>eAf1!|IYLv zXUOB{wK*tVUAnPHjldskdx~-ZrEdR1A?#&7*_(R7^!^_1`@*EqHdu#(S?oBXu5(o| ziQV)-lb64t;=;)7&iEhj`WGUP`0r?FEQ`qj?s3NQs%ClDWdquzLw^tMLyzMJl}A#D zh1HAMvH?Ih`CM$^mFoX}V40Q|5Q?$L{L^wZDTY{I;H)@;c%cIN_!yw$J_l*@d0fLG zt0)uzhXnX@q|jwYn|D1p5B%Co0P7wX%8&-VU*AGS9->{HqqmB+?+!b6(X^o=3bRw$ zxqr~Dd`(X8Dkck{`+7bY%y#xPSMzi<3 z-*bziM+J+%j0rl#e2@sB(BSZEtw_!e?)qX<*RE%Ol}-5({(Kf+W2*|$gJL{0j@LRq z^5S*U{K0&KoFEy7I!NV%`mIB__#VA@{a8Cms-l}n5wn8kK>fCx-@ zr-HcGt#M-_mK6b~x2H8q_vJV>r+u;49fOMLSnlI3yAYjiP!<|xozoJo88wzbEn=h} zN+XD3jVr+*=9mJx8no2mbFnZf_glRSq-8v;E1QvaWb-@Scaza*lN5aHlJLS>ZnkNe z&-q???)f^_C3k9c0ZseYE~!$6Ud}2<1z6h$W}NEw0ZrFy=|X=OjZOM2La~9btkCx3#`NoLwX4}Vb%JmUX}VzMD{_jzr`q9*urI?k8?wXb3m;)69;D5{2B2dF2KKI z{y;;}#UL9YipZX57z&RKU^f);oePAPKs3!eA8jE^ty!{`qm6 zE5%OWEdEW#ZQxu9YioFc|GLU@P$Uj5+IK&;;?2{a%}&MdX?2^96kq69eFSVg(jML4 zkOvv{l=IBm2{86XW#<-s)Nwn6j#~$ytRVby*T|MYVI=Ka9)tSp3F${67Q)-BotJt? zC9Lcnd)-E8?;@@gtH!zq%-EXj&I5VQhPoX0_v-p0rN`nDHpt0tv z?^l`dGYxwYI(v84-1vPZM=c!2qIFapq0@{}G82Jt%PzBi5|D}}UnND`II3&Uv?T-% z1ScJ?FS|Xvk|=o2I(S$Qx=^QCmLu>7?yWx9S!uXSot(g5imqYD31U#)qaHpHKBabk{qL29i<@=BjG_5~C^XfpG z*@*}-6EFFPhzKd%tzEx=N(3vTUIiom1ApaLSt?8viWxgU9zV?WhX`FXl~F199bm2SMCJvT9`%E*^i4al5{4%zkhSw zX66pGzj=BEZ?>u@TmG}R^Ci!&qlOovWw7<+hc)bw7Rv&AG8#PNJ`T=paBa9G-@T6^ zV*?RqHT(lAVdssv>^5%zK(+M`LnRtE1!%QS2Zo>g|A@NH z_f+TP8%Ft5`&fC$z;u(s3&7R+dtmzW;K!^iFOZf>wG%MWipnyqeGpmHL`p`_3m3C( zIr98+mR0d=gQ6vv;xgDbOJD=~#f?{$VcfFv=P4Ys3*{6k_LK zE=eU493Ma4J_OuEZP;@C>v<~}R8`o$IW`A?z-m9RIK!2(Do+l#!pTrwzP=_nV8!L$ z-|2{tdM2jDh^fMfI=jbh&>3UgyKk_U${+516XV_=f#^+oPUwVP z>R(ce_g*S3g+K!aV`#i~!`@5r47FfD6_h{n8SxkQz`hg}dkoz?WnT*Eypg1#!3Ch@ znsyEXS{u<*O0Nb^QddV!oIHNBu#(={_$Je2-`&6Fiz#^1e z=FDbA;>(idF-d_O>N9Au z@u?IVw!FQP_C2Dx#EYBeDfoyWDRV6~(Py?ke|h4-5YRE_I4VBGTP)3_9CZM_s8<40 z_I~L^b?W6egh&_ZUB|5x!3x?K?|uQ9ZkU1>obu;j};#kuFfmC7`$z04P@j1OWE zTyYYz=YiZYSEBJ_Bz@*22-aMHN&vjy*GP-jFktCjk$R3De)R+hrx>0Dd}@vLt8oIg zOAS*+t6X!n9mvJPK8j>;w02K&*)O54t%2L|yy1Jy&^bM^;su7becUQ66rXH1{@63r z5ggXqOS~d73l+PS_v^eo$j!gjE09eFy`ru|={(YuQ`Op9@gho7zA2!Xh&!q5zxJ|d zOE?g7FZKAiW`is@hISeFyl*gXKoy-&dQz;LV0HzEl(uj3ZD#-JVXwlS-wF=z>DrY8)fU>UYfKn`2LB#5JDyn4nV2B7TP&ZLt1kmih{3wW@-+|v~A`_^|9syrx0t^ zrH*gG8C-x!a0nPzS6-iSURoT;kg4t{n11ENTag4A*uaOos0B;esc&e~$z693SJJWiQZM><)(C)%34S8H<2 zPshX!K!-HzFq7}E1g-5?roSATB-~}Mm>*YtbJ}`0;kFt1x`5ZnbMAzlWooZVe_1K7S0P3`p$KzS}`-dSIr#PF9uVb@6N+I(Js-$b_3 zX|}#VHu`vn#Cx=W^?vBR>1zLoQpXk#0{lny@49iQd@A+PX6>kw(K425!V{rnCuG~rclyO?3U*YSgnX&YF?hUW1>hm*xz}`64rSl9ZBN)S%+R_b$t`Lxj zGQ9$xfGzWT4DKymT`iGjaE+{N}vQJ(6XHY>4#$wS%VT=);$mBn|4Vc8lq(rzQ!wGmGsiS-Tv-UTpA0tbB0=s0?n_0jOc~96HoFmix~65x;si(gaYXunnQbHislWPhXV5+%sGcSV4|jZE?E`_kwfK@bj|SFu zq~x38OQ@MZmO7`+g*;?x$o9RwTLD_?dXPXIPDunp?=rIH)Xmzz_}^kfM>bS2Q&E=5 z7BB1Jw40PEz>U9SKd+ZsSmf-67BO!A%cRqZN9YZ&{1Fq1>p)!mPBZ4r7|Yn@P-M>& zEunvf+{C@THE@^{sp+6U09k`eOC!=^cROA3`!Q@Lzb&Pi^;F-rsYe?a?l*}2fqVWG z2kwEej2CE2CSVt8e_81>;r+Z2WOtLz{+Tgu0A!lWczOGMYSmgrh+NjUVxhcSPu=@R;c0Ge>V1JsC1w6n*xnqXb?R51O z7@6|~E85`NOJ*A?LBv8H zjgZ||n!)Z|?q_gULlL@q?O{mGgT{bM#_kIhnQ4v+Xesl(wq>2$-FF%^;cy(b)OPxI z2v-ZdLx|wAWzK}^Anf$};N^J`{4QmPjDA{hWRasHspr_*BoEl4 zoB{^1r}Vl4*YR7uUfgiCHjuuGLG-kdrjqUM_U)2<;X~{7s`w8-2SK=!sb7#Gi=8yi z68dMpL~JQL5Lz*t{K5hlQF5c@;lF+#ov6VyvSd}>+Z2$IGdUD(Wz%P%PV--tXH8+( zSYIOfCz}-J6!AM5*po`Wlzvtn%-LoOYF(K#Gh6rh$_m(R?E}o;wpzYNaM4(Mc;n9f zXSf2C$+;c`=sMuW5*_40l(&Nxye0X$X+{`lOk|-)Tl_n5?I<@ODXXLaA>A|uN5~>p zf#Zk#HJ)xz3c|=3ZksFPKAG=Vgh_=~ND2)>bT8#@qD!}q26NK`vSaGaGz&}83WGw)-SgL!c zeZI~7%x3!stC6@D@k;F-Sdlqm08v)Zu*IX{Wnszq8U&dw#182$;fjTz5KuN?$;D9J z%%WX{i}-J0ebVk(|7jls&#qtZ9Von9Km(%%Vk;HiENAQ<6y22`9&!K?Id$D#LPk-RyuRh`a77DL&@;H@At&*D3(DRyr4)TX%D&TuAY{T`E~bPCUC4Q5VN< z4~<0`)&`?J?@|cj4w!CyZWOq`HnCSM2ym0rmFFb!CCQPcou+CwfuLM)tbA-kRC~!L-4@R=QoWF zIU6^5U+4^a+Uy&TEtG2{+AA9HVt8BO=xCH{)~1E68A{eFj+GVg5NcQ1`4PG?hjqvm zrJ4Q9KjW^B$^~l!EMEf8=em&>L2n3TZ&?Tmto}TK5sE;xb=l!9ad-U2r8^auEDDF? zi%o-8D}yXLjur(kzii^`r=$SARR%$n)jzYamLsu}njWNwA*&)}jPqi?r`HHqth{-3 znDOdJ4p79LA=h=A_9wStacn-Xchv5KCVuEfK) zq2w*_vEBoa^?D3F#5gt2dtM;p;_ji0w}efdpzbO%pNH8NaFU)evjU)-5pz4%T_^1W z&*9D>e6%duCD1UCbxE$kc!vxEL~gldZ{PLgX9eT<<@8M6o$j|b_|#tLY6Uc|Y+}61 z+a!1W-DKs={^L-6qsAifeyDh_xAEKolq_UE--PnaIUTY~MYwWYTG;akmNYQ1Gt8n`BbAhN6 z&Aw~gu`VUsUe>f{SM z`Tfiart(o5z^%~lY?48g4TLHJuw*K}(DbI<20KaaA^@O0{(0M1aWF|yO~EC&E?9iaf62eh6Fr=X7?JOFM*Ru#-ZDvK~K zfs*h_%U*2UR25NTz3enN~_QCw$fjo0p z`iJc%!)D$~{FHwB*ZSL$3wY7>c;(N35Xsg6egXhcVY++#PR6hF2>=Lz-yZhuPbtGV zgc3p_z>kelb@-*vsBqs2o`eqHyZ$J`&t}p~AM-|!LDt8*nRI4nHR|8=Q+R(aQ5jkE}$@}#Qf|3##{Eu{JH?) z`Yz@zsFg6d*n-OPe?pmFOECrJL!TG-&QzW@7W zC%VL#APa;Kgitk)cYOmP^WGfmrt7;v?OVZ1w5alqJz-x2PTZ&e2laN}BVHq--7fGw z&SJ=v8xqKNz$MuSS@qLdtR{_v5n*O!u|rq%3!or-d)%?dB;K#+mYZzVINU|xNw}rZ zW5zOn@=f^o0ygq1Z_h`Z*k_$-^7I^-2OfXvYYfhVQjp`Hu6C6$$lM3AECy;O1N-SS zh^{!4-kFsa<$w?561Y2&rI`vjH)_}U1e|lV)q^^I6AYs3KagBv$f^FL2rwFC5_FS- zw@uL?()#%|HbpIPCC6nb?Qitcos2te1FSmK{&MCYOiH;vGDIXVpqK){XnAn??qtW_ zwac3V{wF4ucZ+H)5pXs6+#W{nsOMCJBy}$v=;&R-S#h)W`LiUAH)xg#uU2RaSsQ!I zYC!J)g7nVRsO0cx7-pOBK@pUI`ev`?-}d|5{wX7IokhtbnoYk%+b`h(8no z5sL|9;C3lDL0uj$p)aA}zgBYGy73(J!OOJwjjO5Js=5zwkVrW6YI;f&3bh>pXM@g1 zqnWVP0`x};s)obT75@sF!_%Rd-f5NC2 z@^yJE8X%x6*(LmJ$n5z9mD0_?V}50&DyZz8=QG#zXVCCB ziShqQio)>0F!UPOiy#`!;t>vQS%E&wqgFHZ@@Q?q)a3fo-&2w>1sltv5R1?|HTq^< z6edy85E>Op#Xsx-LS8lCnCTy8oOq0NtHJ!ON_xK_nqaHzB^dzkoC?3_Qy}<(gQQsN z3$Nzn2d5gm1@`(0QoHn6ra%;6vrYNZTit|1jFP}smD_0iRkEp7U&R{WPv`k{;=yH< zP(w8Tp3CV3om!4dk$xE4qy8>2|KP(D@ug6-<0ZqIl;<+47OMGOF~H!JVwjxgv$j>z zprCv(!Dr?H=vX@`I1E{ZVJ`r_k>5ZMWmC{|2AXmuTTqWONSxgTpeweBRrSwYz80;z zR^Tn7I7aqA%Qk$reJBV!cEw#y*}{FLlFN>cw1dv6|2W!tt7FGNXFxuc{Eks>sZc}yXq z$&j%Kndf;jiT&nlE@8{w7y#IdN_Wsef6{~BV z*Lj`Sc^=1p?8m-`p%n`(TCBglJg*62tRGu5biYI&1Ckun=+jm@{lR&zuoen6J+0$I z#Q^gPb$-(IU5&<{DC5Igc&)ld3)0YNr)uOBM`S&yVF6aVodSe(A&}lXR1GkooZarX ze$Ta^10@Wb^Z_m|@x?nRXw#FuUMc5Cmy_K^c#JeObEFsm1kYO39(~C)xoCZH3yLZd zO96??2FyLM!AMf(!q0CA7Z7E*62$@YFYQ)`_0lxaBuu)ANvwNGPobSjY45#NdA9C= zGgl#eB8O0kKmOaUf&b{x`5gohL+LH0eqpaiigGGD$gYL~PWsS!=yEf793ic8QKGIZ zuOT|iumyfr+QNLkwMw~4{hgdI3(tIFbH1eR0-?G`*NrW)>Duo236mE9aNJC>EPO1) z2ZQvEZ0mM_w^@yJ{i*U=c-vyVG?o{-7E@?Ib3bVf@2)+jRe1)BH_y>_yfYOe+Ud?9|f{`dm^jOuUcI_=pC%Acn_@ZvztBXlw z*ywCmdo9PYM3rnEC!$zKWH*RHb^~&bUp+$G%$kl8>;?kq(m zjz1idi>FD;K+{&8kUbT5IH?dfSh_YV$JH@ENn`>t#V`<5DWQ9{YlZ*psE%P%@7+|7 z)M-;9*BoMW0s(KAITd7lxJq~xq?!)eZw4--PEpP=3 zL(tvv^qgCda%YS-FiLI`a3Z6oM8$?JS5sGxBTT7}ymODqsf&napwn6-&J?Vvudxz} zl=W6;>#}Ujdk)bFZyrnJ1Fu-Uuj~n_(F;gDxV`7EG}7$#hAvn2p{(P%o7SNE3p^mO z8?kC@dxx>!m4foG?Z|vk^JbNmI}{|)(90vp1pV)n+niE~pxsp0X0s!Vu4#HN-{lf# zlsZShH$^!}J|l{GS4nV-&6#@7Wk`BKXGL~((X?olgj=&fY7xJwarxU*I#p%2YU68v zxB!;Ug=$OC^9uWH)bzUGmPp_I3EJ5*62gR5!5N%eS&8q|VPOOYxQ01_9&5&pEuv0b zGC}8xYQ1$Pk7%>2L;Cmm3v_2GJvcpz@g>fhdz|O$KVVOM1yzx`X(CwC+NOTdazKOW z>rxx3Uw!HGxu*u$poa}fGp3G$tCBLIh!1BILeU0Bz=^BNpqV>;zud>LZrH3Fg$9fC zE}epy6k;vtq(+)P8hY42ouBTUdy3)c1obypM^kt0p0~=WuV?GHOVP1F>bs(@p8lON zFEm%HBtZz}9_`DkmBJ$Y=6x zcCDjK0)PZ`Acx{O6z`i^3j|44h=it(A~hsXgRn3*0S@yt#qO=R^SgT+Po>1s(BlV^?9o ziE%3Sp*|mnn6o_qFY`L9o-36iXHdxA4Tz4RbN{EbTAR<0&cSx=4VBMR_fRH;btdW>PsqBQvN@T8&+x7BZ|8CfozQKqdzEo3>T_8i0K59V*RC9(7ULY`^$zJ#= zUlYjmmLmPiMi`XZ>wpdR!#v(+a(O5E72+02Q{xcP;kKs_HDg+mtl9m^jALFPAN+s60jntm|2o%%1Q7d03@M> zn>Om%%-6>qrPL}?p!xz`jZqr`@-K_Md%nwpx7EiMT%UsFCv*^i&hQ1#eJCm7syoM(8u?%Zw%H+hojnbYWu@QkR zbA#cRuNv2#7HYrc<0nee2)3~yDm` zYDfRt{%Iv#*h=v4EXrJ@-x^TDAxKBq?{;lPnArXW~KrlT?w0I;=f?Ezu1|XxSWjS~5 zMw&)`f6L+kMiurZXjL{CjQ2h96rUI~S4`5IU?pcUf<_>;nRs~HsLmVi-C?3+nBiu; z{Wwu+YB|q@e^yY>&eo9(LF$2&Up7pSF1u_;kOTJUBK z&R;cBVa{ewVq#(z9v+?#X2*5+Mk@AO8gReX=Lh=m)Ozn=&>DM zVj37mbWI0w?~@Q*oP;aHmK&hSR(B-U3oI>wp;VXvGXhPz0`_izis*qifYn55>rkw_ ze;rsA4;A8-3+xJP93@Y9uEv&A-p>u8F_A8xd_@BEU&xbN@!AEPhGa#)LW3O5@6AU@^ zDJay$1H^O{%K5Aj+`izikP{B%P?;+K09mL@;BvsA#C8hPp%^X53I1>=!C4~4ITea< zIuhfEhXMpTV2N-7(5$GlT1EU(iV&;gj-+c9v%|p<07k^B5gr@Ypf!@IQF!i!)7nWO zjlwC)Vca1qj+d>m3fc$IE^lNZ17ki7)Tv-FQyayLhFK0&)`4B%(06H}TBxOI z9&345+_xd@y0VXur9`Pt>hSpysg0TP2TfVW)u~rps7n;)d|6K#T|k>(6>7nprf)-_ z(cJvJsCE&eTkyZyVT@>cP)nfE7q+r6A={p&Sb5rvXl5!;-P@3@^V5I<7@0dV)IrHz z4`_0972%Q^m zB+7Q>V2rH|ZzZa^THAj{%_`nsF-nrOXEW7B;Zf^IZc$ z@L6CxusGD;yc5Br_aw3%yif!$gLdE=%EY*DT%o+)UcpaEQ>~Vh!g<_O8tSLnuWgbc zOKh~pCCH}NL3j$-O==pQUB#0ivmRVv-~oGu3e?hbZc%%t$!CXq^4nF?H?%H)^VRG% zCS)->fUe|pj?nbOcYXL4wPnmH4KeU_Ozbn^ObtCg$nI-u-uDuO@C2X%J2fnw*Oq*e zA}v+=grgLKM|=hUPrsPNN7 zffKe=`TTAXQwKcJWpGR_N*4= zr`2mYMtKEI{O?d5X%m>d0OgB(bMuAw%gG98XH_YKC$8?*1C*sd{3b;BX=?yM_C>t` zvi$sh^~_F5HTAU4N?JQrF+eO6?k{EqP3tjD0RApQWKmIuT^-Jq&+!wx{q9A<Wcb@TdauA<=MNluXd4==Fgpye;L*t0c$EYVWOEL$Jo*02(+syCl-8;a%?7-UQ#$rWr%n{ zLs$ReA}0_^!H=tjvzQ*F@d^1)$vw({0Rdco#WE?8$MV??@FI}^A8to=ERuDXLa#RL z7%$Z;3njdK#QuZCMv6}@&^MR)cD1W>QoQRe6^@aG7kw;GZVfK2RAjmC=(f2CZ=C#`jOK&2O zoSX^K4EXU35ck5iD_8mADC@a%O@@n;%P(9&UzJNfJ2C#GPv%YVEN~Qh*dz|pe=$Jc zMD#9)7WZ(eX2ccEe3>gqu)0pkd^x+G)$EmF3U(n4mCI-ihGkp{IqdylAa2B8SVmg= ziId2*jw8>wT^ah{6XM5>&E#`kvf+nHpI`|F+KfH2xjX1GZy_R7-&|SKF6ukR5(Q2|x>cxb3jaGWe|wMgSMRYU;|C0GNh3jI15=qKRRr_cs$Mwh`%Fir8{1+4Em*`SNOO)fytUgVzqg%z`|6CFYn#kpQvsdRY zZmHgTIw0lX=g)sBng1P$_rxxZfWKVDGHtZ zC72ZoG1r?V^iC>gGDz+N&XA6OMEPss2`VgGSAzoSKOfewe=;t>M#pv^1tkV2h~P7S zfMy)1FJDFqZ=9=t8>?*=#p0y+iCxRl_GYNsw z?K8w|x+Fr{*{#%#`x>;Z4|&sSg#!5ovHBPU;gb-Ep(>pMpv&nR)L+j)i+sQWc2Mv> z!uf~dEi?gqR5UxP9kPVw$sJ)jrLDbK*RFq`4C_E6D5GJV~hPpxI2fm>i{dKHsk(Dmo|MH%7Z92f%AOZ&H&8H zAxe!J#kz*{~xe};;{72A3UPtajR;G@KrbWnwKuoKguz!=8tPC_B?U-gE zJ;vq#PkO9Uv+`Yf^LujnO>hxytTl+`{2plijEe!M3tA3RuiZIq(s{5cdxizS=GqH|(cBZ_Y-Pe8T zesr$b55J4=O1jV{Ylv8~6E=M$HjJ+)iVG^t=I#F8ioR3~Z3pr~u`bqEXgfeE?y{i0 znkh@~vsddP+;N4g-|4J)3SHU5`wq!TT94OweE$0YCIB?b37p4lheNOV!?1 zrUDjJ2x!cPrRN8j=9CwvE(i?L~fJjK}yk z-dA28ggXC=ys-LDr0dE-hJEuO55oc`nj3-Pby?T4^Md$S_xbn)E$M=Y= zX9`ruip9=Ptv*`CL1R_)1eo0oySWX&iYXYhJ27$uGj}f?(lvR*)^V=9c>)l@v2!*6 zHk}?BZ;JQ2^-=Xa$mu;Qj3A)P1G3H3N+>{3R`~5y3^q4XO?rcFuBXM&A!idzZmgOEA9^TL;55&c@r$ovVWF zMFzYd60STC2a*)=I`ii}u8T32c>C3Tu)hbFi0!@>FG&jYb@!IWP@+up9?|wIDU-*6 z`|;OVRq@z$rRloMi}X&r%buDZ)bYj8pZTwsxteLKHs} zByeG29HsWARWv9djC}KU0Z2Fqz_Z$KugqnA_Y;6+g170r4f2aTA6+yezI1cri!Qd1 z-qkD={ZMCyZ?doqE zVEML|B>LE{+m^gWv%V>gC8Dr6`vc#cn9{X2`KSSUyb4jZ4SoS(Q;sVgx&hT+yr1K& z&jDV&PW(k8+PAMS#`pccDN%qJZ4b}TB*UFZiad&XejEVUv!F|Nr(JgCt55I+=fy(7 zG-c3VZa5tq^d$a`_Y9=eA5C3GBp*;bxtYX_?Y$EeI7vc1|8q;S4Id_l=CZw2cml} znwg`4{*iCd;Y>dI_~mgiH)gDhlnGxy?PU|;#Y8UvU91~N`FdPZ8<)&iz6Qjs3_WcT z?4ba)@}p)oqiDBN6*MTe`SqhevnrkA&WpsJcWrx|bDwMRs6nhcv_42rx1TR|Kk3F* zWs~NJbt_B_ZIZQ{TzPi}c#+d90 z1`D6P9cVHuY^3sjyjMc2U6}}E@=DP8s?O}~{xcPodmz;ex59NNyZq5@3a{aY^`>== zu}xb^(#`Iw%&SBz9u4f}!#-IZ|O z9TyUPMT zJI<^IR?HwNMwd0$izjadg5E-sAD!i8>0yaBTx9jMU=wm$R`|+4r+2;Ao8U2eu5|hd#Xn>ev;N9={1hMax}-N zIH4rzVt(T#1SZ)oVL&R9s>An>*2ajGjwL5X9O}8ptS)mNJV09(X{LURolg}vVFGzX z>poK(=?cIO$GX?g{ z+M3*6R#i$$r0mPNHkxq~AqJUajsT-#!lJPZ8nmM(KvYH86hMAywR(Xb($#|mBft9E z@ZEXO%#KBJ=9$R3f>)?LdW4A!B*nj{Ym4R2DWqIAi)R`*k{XDcFl6KBPf_>j`10v} zOwbbv<1`HcP1`xB@id_}C^VDpK5{9!F=>>ZEkayHG=|c>%V@bYELzbVDr$_~+F*D& z(hy*dGC{0^XjB9k)KQ?I^#o4<@MP(wW8QJN^Qg%>qWeS{go`?jw>3nm`>9b?i{Bg@ zrD1O68x3q?dG9M96r-J_I0AcHu~>wz5MQ!L&`I~8dl@CP(?7U-*UV*Yozs8;Nt8G5 z)b{anj1tAiMoUVMfjLL|+kkDLUAX}IXJ$>84J>oFT@i8`ua z-0f1yhB9kS4&ze6+~ja$uxRbdozJeftw8a!mp>u=+Td8duDr2iwTN(+)FvZI6sO-MtLaL4W4)W952-EjxplsXhcD%^w7Mm(X4lKd#%?81 zpPV8xkzo~!?cLQ& z1V!WD`IQSbWuZXWi2>{OrO zQ2FAy7=Ft)n8sXC2{BV_0VXfn)pE+w5VEL-P0biUyDwM1Og;~e?e8n==N%`Qm0vxC zChL)>f1#xHj=I6)@DZ|AW- zhwZN~`Ezjq3}bALSAnC`YhL7gvv<9+KrzJVxPe8^#*LOwB2==6QH_y=rzN!EXb~;b z{CgO8URV>SvYs$39mJRdZtuW7b<9%uJZYKby8IDHoE3?f(!L#N$+sl;s5kuC@7?e%h9m{e2_B-L=AbEN{Vc!nhe7OA>gvxl zi&aCgYPqIz=*S^Ms@}(LCn8CREYy}K4h?M2c_P|%%fHMPT$n&0{c_<*w$&_GUQ`mP zXYQR;r9rhlXosK7juWXzgEoBKD&jte&zrQTrP2#KR8KhyA~vvhBc;@c3n0ZxyI@xv zYG@|V4oAR4{!7ZBi}FE^6MTFsI*GGJiSI?OfFP++*vM@tq?=K?5sbeMI^4}MvPCC- zA?C-F=OEDdx17XS&ax~I(3)tb%b04-(1~KZM^T6dS3E9sDzt!*RWS)}u$q}`Pz>vg zr;zgI{z#v?Z0Pv|Tz)kl9#Za%0?=}$4b*rYCqGH^WQe?zFnn&I%Xur|3E9%^#CxA5 zxq2@>hdO0sJ9H?tiswf=?KaXI-=B8}Om0`pq14`@)@$%NO-WCEN&Wqe_=mvWUCWJY zUEG&5x4PggTi#oqc0EPL6tifia?`j{$N-q z*5hi=!K;v@t=ut=1ziS*1jTgQ3FVZ}`n0{6`}Zv;+Bk8vr@u%pKkip-1i+A4q~9;L+24mFNEYBw4|^v6uH$5xeLy|Xiej3hC6A#ca8_osSY~v@vZB%J$%(T>$HxX9Yj2xrBE%>bFJ!f` zc@gEwkPy?Hy1R5d_kktdkqeiBo_FU|8A$P&NFLq4L#i4m1+cE{F1f7s2=P0ukK0wK z#wg*V2cW`xPI1eZbGsy0TmzU+18*t>&S(M3{8f>OM4Yi6;Mk;PX%uRQ@QYCazR6Oj zpXJx@*8o1A)OMfVsZNpb7vRyM7jDmQ_2@BPN3K3LW-zlusv#Z)0RDjd*QdXJzXa%a zhx;OSCqoJuSpZa0?gRH^+Z`aT0jq8aYk{H_1I&HMy5!}Q$l zdhuO*3n}M0gAm`6q9wLR%2C8Wk!~iwqqM&sao`$^t;W3J_)dcfJq_1;k#z~YfDjEC zV6QSC#lOxpZ_PD5<_KyXL(_$rgh|gPXZUu;Ah_7mU4vUigl))AjDC9(o}l;vyS!l7 zYz%E7Tp_?z6^A|ORD8V3AGmHSNEEV)NR5 zYUM6abMX1nAYM2)-pT>&Eh^DsbAVOrfWmq*ucuoI8pPN^=3{OGO??q9VBH;36Vh|z zt!>(?zoEj^EhY)ZbrIZbR3h_%*@o76!gKQ6(AJhe5>-|vKGvENfpy<34raQ1)ir#$ z20Vy(i%JJuM4OHv>y`ml&C)|luAP><9qBD8)Ed^>Rl{MmS&n2dT-~gVkxL5n5e}QR zAMQWwDx za@RfQE@6ZOjhq&>>VzdCBBIOiJ=OUVG5|&>gU-TBW((TAP;pBJx<@n2u?3L@lrR&) z5Nf+*Mi1h_vfEwkiDYC7{w|JX6hi9&!Og5uI{5}eb+fM;1*m)b!D$C3Q(#i5v zo;HuVVC)hZb*JRBJs!|bkV4THl@+pJ(2ml!-Lrzto@C zQb$|dPo1Yfxrm3tZZ$MmLytg&EZBckNRGnfj3;P@Qi-kQ$;XP8=jf#`0I-^J1#j&R zjz-?!Uj7Vsnfa_inQC1JmYX3W&Wp7qRKll$Y!wPc&>9duz~un-J3K=BM4ZwWy$ASi z*Ok@tKw35;ypDDrZIU>n{PE>t;iFZ}bS+nKeEqV!=RQd-2uA_`NKgYs-)^aX?BDRx z)6l~fB(}NM!n+BLR5hT`#BK?wa=QvAOrqe+n|s>Z=M?I`y~0-msd7ZixaFOnD)0PnYTL9N2~=Z3AdZ(7 z!fU(y%(tcjO^BZ_bz9!qkE?F_FA8cQDQd7f<0m2uz*+xv+yl#3kg^m31IBhHL(A=eOQC3o=kRr8dCs zDmf3EFyUA6jcwMI`5A3mAjXqMp~y*}BjyeQTWa@}B+qKhr=b@2d;DQ`L1~N$&fj2+ zneo~55eKruR6^W3y6*1o5h?nGYuP$+|)ggI0TTJ7KRm|<1@cGn>Q z_M-=w%_T?&+s-T4q!-WD^7BsgHJJW*9}h`Y8)-FEx~wGZI}SC`j04C^LF2*>MGV_@ zPSuQzZ(!LL@gn9d2tR7mqA;#bi!N8amWIIW&GdrP{6pK1$ES8*t3aVa3)HDzCVD`? zsmEV%gQ9EWPIMjj?J3_wB$uHW$`sgvLTlu!&mVh8%YzaPxj-h*z0>~v*Qr2Oxr_wG z*qbUBx`*3iv4p#?)k2C6!DAIsy7-`TfeN zT~ft|;ow!wM|B9DZGccz`C@v+c&o9Ly1mNa7u^=aFDucc0=Rnm&=9d&^%I5HMuqFerqM5+7QVQJz zR(nm>8!4+r%KHcf-o*i8-QT^R(JXcae}#iCg27FdL&$#P<7UfRm)p}^`I*jNAkO^F_(gB1AH~l&4X2i1-iI>?(L;m`re#``@WW_apQB9pqJ$44w z5X}0#9pxZYBD-1?jopvhlmL!y7=fYeSn+yF^lLPkwj$2}s)M|N1MTZ;&UCkfNjqq&$W2 zvv)tnTbSd7?40?Fpi$B2-f{^js=4INTiZxO@mN#IAn}^g8{w~y?qM!>gj?sp!`7s6U)lhV9h$)J`HmF$g{02Ldfp7u*P%g*`Nm z>kI8Ci*o_$5X@`5lD}&{XKybdn;0FQL=40_2D`&$xzZLDdwU=6D$A8xnjPvfiqojN z&ASG_L)Q)@%83ysBEuq2dWd&H?5BX4YaHEvt{C-z*D)ci*AT_p*131jo+b;tSzefEtIz>Nh8bT;GhT-D^O2s%VJh8RPBD!z*g`FC|)xARsGc zgjmS>Dx`{*yCI>gO0bPc?!%S-`GK~8)BJm~s=S9s)>1IO9qf*#HDe&huSP(x zOGi93`w*5*p}8>OLn-!<-!VXl0LVk1Bo2sj2*44R@!Uomd$r)(Y=wn0Dpt_8*88&^ z3k%AB0&RNK0P`FTOIK~INUo~6-0!X9T%oWtN?L^o3jynhp7S!4*W}?(!e_h7Agz@= zO(ZOZ#4Et)ymSUE1-Lkm4=$4AUh77*{DGKfws!O5v-U-ST)jMKtCJeJ_q1WiB;RQv zc_q(3d-u$6y*jqL1ngaY#JRtdj}~mr0^;7GCUVI1SElj|9v*O)S>@NLy7|?WDBiF| z-{@e!NjE4{${gWto8oXH{JbTltHxgS;r$|isuY2 zGfb4-96sRF`qZ2v9I(lg;6N7ywAnGOVo?12`2n>76>}EtlE|o6-g7jU@=Q9rNPj5H znt3{;s_`P>Hr*_h<$A6jXbHGM*`}as{>6i(C%rVV+mvlWlI2LZ6V^ZR%a#&$*YK0m z-v`d9yfRiQG%q@@M0lw=@knex1YZb659mAOiq+9r!iXDyz;=*CwoGGxQLg?oTarOY zTb6q~Oa(DH#vH(SZLR%ApZ3LWwCVn#Lx+N`^k2uk+v^Dyc%z4!aM@PNvJiYqCLf{p zLg-S6o`}`(vzYD4E8<;{g8J*CqU;zBUUd^8?+~rbZOr04T8|W&S@Jx@hKX`(Ru#-{Y8oLE3KY+PBgdr@Dc_>NKbK{6 zgq|I+)4-M_#Y)F&gmGr+rpk|y&czu`DOl`LQGDj21kSv`z~_L6jb;1oxN+8#@7it9 z9(J&$kaHF|Ko(I|iohVGAMyP&&|GAoe7HL|N^y2dn>yAvINUe$ie$yb#k*qmT-`zP z{)2Lv^M?_56v2G>>t<(0p%zu)_-&hUnz+k;8tDD(I^DCY)NplKcYfP>OZy^(OG&2S$`K3r724SCVw2Yo*%m? zbK}MhX0_hm>It{_j2tuQ9)`=7EQQyBf&KZTrX>0}BvzsNLlP-LHqx z{1}LluV3nuZ4q1ljPGCnmmHcY6i{>#f3EJ1bQMfA;;rev_0r(#ue%UWJ|r`a>Nu8izZ|1Sn2xp@ZSuUMSG|Lf7o#oGS=r#IcjwnY z5{!u4$;#jvM_1!pe6XbVv(e(L8nI3K5D4(^vfn}91xXVoIJlbKQrktfY};v0-#~QGQUz#XlbzM#Xz>P3 zAB|hdcaGLX3k4KzK!WU838Il?z*9;tgn;Fh25HW52$y(L`TfL{#ESOq|IdR6&Jz|S zZq&K=`VU{ahhpg>q(&{0y`ca6g|q;oLMyR!)t@rDWCYgpUPFKi7)pEvb8lo}0FGOhef3WD&aa!*|*saj`mz}FF1zcH- zOdt&^R=`^Al6iMrI%&0O9^awMe5~da3^?|J>*ig#tTsbl+9VjP!yVf*_DB z=)aQblF#YqdNcV>errylZk6IR7`_=9_C(acPGota6d!x!S7-FU7yB8fAY@L8&eu=) zy_o2b#k3fa1Y$adO4FxO(d(dzw^!{x2VKH6pl~3WqPH-9_{0Qcm_{$1CA~Vd2mOWA zYLk_E4AD+q#aan6mZ{i!cCpPO&Sq?f>m#o$IS7e((Wxw;nbMR+W!X^!NJSIqCm$rF zyyl&#g^U$IE|KXGXt>Nb(xY%RFV68-UN|v(XPj*JZsQsC%d1)6l$M99gIfG**j>y0 zofgcjC9;)vsq0x(oYbw9=Nilz?*oVt&4>yA*8NF0lEQBaJ(W95Cz$>tc{J-MoqMvQ z>e21t`5NfBkNVb&{j+QiarZW&I-Jav@|AIgrWk!%2el=`)=!XA=F&q6Gy-?4zWy~X zQK^_MhxGc3g+2S^lO)E@Q_AQ0T&{^o_fXea9;~6}3glEtdjrO3hg7aixJvEw;2adO zo6KNCl?;Wm(_yvR*auA2o?k4D&+=pQ^ zj(Lx5$C`&K!V^SYmg2}-F}UVdz*AdpKxfh?B_di5u2D-;{9_mUgTW)L`QB_H!i%kw0_FJ^M=vl7K@jCu>4s^h z-4r|c<$!NY<=v}?QSGT1nTUJcc<>V0+uNE_YF)=8ZLg|iTJCc_r#{_Qc8EfUP_Vv8 z^K`$*NuToXxE}V`a}Y4C=3}j&O%Z7nJ8{y=V1ip|oG_)FGdbm}BM@#C4keljJY0SL zPU*C-l5myY+L^`pgn?~`s=)>uZ+neY6Xoxt_(`EhDapMF!-er25SyJ^D0C($v@aVw zqk8(;AAy$__orf)y0Dbq#of8$Kf=`-!a056{gsH&FNv$;8nNmdh3!(NTOc+gNIR%s8``Nv6f5SgfZ^tZ4m%5XP|bg$JRfe+ zXZQWhR}J1z3+0RCxqBZ_*rWzK)`c_Rnp>9VXoJG8#F&nKBkxNSr0?q4#8DB?3}y-s^P%nQzx zraa5Jh67$XzaoW4Iw#KMmRZryQiybIwO8$(ydx#w^U>I^(Rr?goOv!> zSeK5NQqsMDeGgoU!j!g$2WjO_rbt2S5nslQ9AG{pH3D1+A!@QK2RDULPmnpUNn8-B zKHIstue-oDi>$>UJ3V*Jnn|(AG(LTb)MOo6XWx*u#}_2c;B}NrR~Og&i0@s@D7(Zn zpS(fc+aTsJqsZq!T4_!&Y3jX%V_R0CC05^Kx_&o*R^8r@V0>ofbK=~#PaDY?EiN!x zQ~Z9|GpXWMWM$tMgcW0o(z@E&ZOi?Q<-{W_>V%WNo;>?ev((KGfQ^keub?T5w%2Wa z!JxokCNaDE%ggO&RTa3*B}1+tdC{aI-kWlj^N@41RrHts*=&kVec-S#dLz|5mJ^qk!MRy+>D{ugpM zbV_p5@%4xqbTu3vUlur0cbEADiMdPUeaq&wG_8UIy4A2yUG4RjYQ%pMvx1Ql;+S7P z2@>zZi@c;-7E6>7;45jp?HHh~QV{|m*IHTK-@gx}hb2`L|4roIquE~v10yRETU6YA z+xYAA36^jZJR7KUF5AbzPn4lk$M?@*Z$-g_dlq>?a0gAq8Wz}X<(sf%zYl3dRbx^} zPHju$AV*)b79y&h)KYmVlb9_k+3N1xrz}GYb2vgHEbEyu~9Q`TPG`tnaDdLzVRT zxTMXwuiHwc0jj&c?{UoUIP=e*`al1yVLWi;$Z3dZ2B&Q%JNo#0f>8VoccPF!cjPlq z4?Y0{Iu4Z+lx~+iGK zTX+et7b&Dj%@4s_T-5@KS_ z8PII{;IQxt#jm9i^=EC6AC{2;JtAmL^m6K46x$XJsLQ--AAB`4{c^i`DYBuevN!d8tUj`)7Zn?#h{SvBci8Wug$OiQaJJG zK`wr^(Qk)~Qz93SuhD=1`{K~5*b%#eJ+{NepCKcEWmx$uqwt6&h3YXEC=Z7>HKn*s zljr>jegA!h-AWP{7mvd_=(<5<;ibL%NZ?87v>T<19)P!QJq__-3ScqI0_&a|FnZZp zXG@ZQzsB#qgpqUagL=BNV=V@u(L#C4woALp+=fPme~q6dK)mwBt3-|by#PfRf_mpi zjpA#p7PHmXwA)`!W{TL;(-SCK8Q`RK-EOjjnTd(X?f3JwPrAht3vT<;{e7H!maf9u@&9=}%JcH?C1wTDlZDiR&vVRV0+ zJ{JHZCyz<1?W9@yuNzq7f=?38#F6|zzWCQ{dziz^?>ZpE@!vn$gCH3Hw@Cl%!~efU z`hSab+gJS```iEjcT$-s@f90ps&@2g6%vvM(*^simap}94UBJ+BkpN?|Ek8jS%OF_ z$U-m(|6_M4vxVTtMN^R~`k&Ph9op*fi|GlCfwCI{1!9XK0w-I^dAJWVUyh88=qKe} zs6U&zDkXSy#**f43Fqlnzg7kkq(>B5glln5glTQPpZ%;Gqhy4C5`6msS)n&zSNQu+ zJ%5~<=`s!(65CwP1F8x86-rLy+^Aqa?VB|*6J!F*jpxZ5g5(ybHe?&3R#pq>eDln~ zQx3R3S%}2V%EtikPYeg9MKuNYynkjrG!0kJkKwD!sW#<+3(%XjdI}^pTFt}QVjON2 z*yH=T2w$^Qn5&eIwvI;eoH@oEabZ_==)x3v(03<$J*pc6V74uibryMKy>pTC3G8b~Ft`0%$0XCt8B*KNg6UGnwFZ&dpC z5x^)5dv!=?MCIQ@I>t+$H{Vv)fZ{k;U4;9DK#qRBniam7s(P+b>=~~cxWK`)UzLnwNNWN#!jK(J6JBigyKrA(|MriM913>y#m)vpyJoo}Z2i(_a z@pjbo(A2T>sFINwcY)Xd(G~lsu4m&3Kz2&8y?ghQPQJ5%PUKHY4~{$UN4ridC1(SK zqjbq+NrGg8FbEJA`Lu3__d$~03SsA0*%|gXrskSI^k0#U5WPdQ`AUK;z4~n8oMu?5 z!tUx1azq!#gRGmga~mSb%3Ej*LT_eWs0(9JqgiPXQm@9@=h@;bUQ- zRpf9p7AKCVo~MxICjVRgY+EImKr+&`qbRmeA;1;XY*&Jz_@=e7j?V{a;r)uYyNS#p zF#hrW=56rJc7%R^Ljjki8*fN@C0W^x_PCgeHD?Tb$-kKCjOlv3pRH?x*&p0rlG8B*p~|(;(@YB!e4$4#zRN!#@=h0vemdLjd{KlbqgVyxrKmyI-O^sywBZpB zsC*&x0-4SY#cyhs(=BP`QfXOywtB=gHSqC$N$fAX|NHbaOlpikrPt&Z*Dfw!F4X@XgT?5j$ z_ZuDd{&o6vdeMcOC*0R=HXbUo$F*KNn@x97|FQh5*>}(!m}`PXe^%n|wr(s2UX&^M z-fQ@9@0jxg*D05oeO23HAuArgkYT{$zCnD!dU#)>$lK(Z=<@@|UkTbmr(Wino1hkiAsdGh7;5lYe6swcWNuX&&QXfi+vBO0tV-4on5J!j_{g|fda zQ`_UARZR{W?;lh=iJvww*T$pJ#_eX!XiI9!`m}<3cF-mCV10!F%S%%P%{3a7-<;9; zML#Q#4f*kP2ZNX2Sh1U(^+o4J4ae~hX@UV^w&bIQLtklQL*93-flVRyP!m*4TW;Vj zYhGQ9a9N#d7xb}bzI#1d@G=dU8Mltgy|u|c=UDON6IVvj=7z6^OcAJ3tDM&;aUtdN z-`pUaTpmwp#4WTnf_}qkKRVnn`;*k#9B_t+fp#O)$+b#9^Oi&(e2eJtj||Hs=gI(j zfkS%Q7mPMK2yGP2sl%i-s<$qW($ifvE-7|12sBw@l_?mvsacxjtUHcLnsd-6T?8e=pIY@O9W z*N+P{x7y+syG~S730njx)ApQ=78FTqRM9WqhyxY(ee3pvB3Y?jd76cnZpDcc*{3R% zG)D6EkYenB>&?(y;wq#<1Zu#%uo{349*nm%`~%PZTBR~^kVg~uq4)hg)p9v`0MxeX z*8CYZleu!%63Ao>G)4_1l1X!ErWIn=3Ml%)SN<$$YDPq8Pt&GB^J?*U_&v~sbSA6< zs#**E%1j(8ZqW9Z$(W~+KWp|uKV{~a*oK;|PDgWnx1U;M2wUkpiPob>`OF^q1SmQ@ z(!n?V_`*Vwdcrk3WPWlvG)mC+f&`I8UM($1L)SIGzwrdi%N=PV7_Rj!ERDI-YS|W8#$Da)HU3p746VOzTG2&>e(jfn(<0`=+@^gI=%83kQ`HB72{?*ZgLWd z*o>ZDo-Q=EjVTESE6+e0PBqZ7Hpb>3=IH+D=|-C>I5kvxhz2Fys;^2q1DcW=O|g7< zKeZ2n%Ft263C0GEx;Ns)nO^Z2CJWD2ucsvoC6{+)GOmDX`ge;(HCyQMZsn~g`KW!Z zBaP_3tZVL7vuda!L+8GanRCWTA{5fqG%h$nlRI1P_fo7ylrBQEh01`?`_UCZ=JcW^ZtAO zIr%HslPAx8KTq!a_uTnC-{0pOcFf^ox=5Sm`1a;_>QT-3?;csA`wE|v9*E=}z+>vc zJW@ULhmPXepP8)N#&y^Pi|m2zPxikm_FZA#SegRz=z5s2i|iZjY2VJM_ylw~;=a7D zOB>ui{;SF7ixXrz&iOl=xDOcBSiz^#K{b>pxWl2@A)XpJr@V6k&~xuwB1;7xQwNK> z_ffFp_8@;o_YF8IRZpFcpcdb@p^BZdpNL~0wP3OvxpYJtMD=b`ESpE^H`nE;R!N?zt~!u7#Sh|n_UoZ{N9^h46QlRJab z5eyyMzV_x{6|A7_d(e>4$nJ+lH9N+?DplBtU!eeu@fhi5xbUX&YMI@}fOBj8{$|kQ z`u$F&YH2RX0fPWDJCJPY#0YSFTAg3Q^}etI7FUB1QW1~y#=D?0W<`A%WdC`?u~L%{ zA0hw%WJv+Xx8#bCGos<9u@Hm)Zmf5GPzN7vl56uMA;Vfhu1>c;ZQs?VRD%wqGU67` z|BF>iu}a}+Xeco$K=I&Y%oW#Rr4PKXi z8$SVI9%~j0qnfzjHW~8r86(~Ug`gZf{F9=A#RP)8Eth@MPBp$ozjT`>f0R)rb@q=A zYZ{`1=$8D%^=9+>fivMrdO~HiE(Cc_raS3*?@Ef-X0Yu7!hAGa^|kRJ<=j*w4C_F% zA6f#J@Odn=S~`{j;KI**5(eQ*K!Y~GwKDUQi(H#!|7dE~;r;=8QP^v#$;@yl@2*s3 z9q+=y$Fz0;kQm6P-#%8M>}%-XjX=*vAkiaV0i*|mV&H;Xfj&+RAo2^gfTQ1HiV9e3 zq?@6`mqd9BU}c%(q?K?8Y2WZaWic8cSrzs!6LV=-y5rEY+?zleko-SKOyj0DBM8PE z)U!1JwW*=YLfsrd6&C1>)qHqqep{e&|3?VqK+e_67aTxU#~6+XIBNri57J}HJM!R9 zCB)NJ;B%XVWDF>i=vii6Co5Gz1zU5apU37Wj^&C{ZQ-0sko$E9>Sb*wXwX28+_@N4 zIdeD7;P2b2;9-45QoY+1{d3)aEKV0^C9YFUs|VFhl~YCuSzi@4eo{75vN}Qj(imPQ zvoQmV6Eo)?3^|v^ER6G_33t==l~7qXL4E3dFsCcnJ;TWYnn~ZKQUl;kagjUEeW&YI z*(6#3bdJDlT1`S8N9@>JvG&IG7BTrgARsJg+y5>ZL|-QW9%2H4*dG3W1c_EG@FvJ0!VlbLT0m4qzY6Zss0eA- znEnSj1k<3ZQz}D_e-Yxku+7iMB22h5EB~cre5b9?36zD7Q-*=XjQfi{UP!&Tu3W*4 zU$YNdGWh87j{5EOwE@k19e+^{+s$=+!14ONeSSPa`&^9M0M$(gOCPvZ53^7xa1=~L zI7?``u8w5T2D1{k9jKS>dL83OWx9bu31?vsfT+ZR5J4*zPUH3ghWNjhc0d657$gv{ zmLNuVZ#-0L4&b(Py=_Imu{r{U?11yY?~YuzOVvti%TonocI9$ z2Qh{Vdcmo_;>Wy25msb{4pGU&{Q)+6?T-6Bx@f*MsJLWIL8%WZ-uO>TVX)2G^ahzW-2Zgj}FUv9%9=gv&`RHpExCIa_x zR1{_n%Gqz!hMEA+XqfgfhkI8Dq74LoL-<+boYYHiz725OTrBh`!SRy`i#$R61xs4Y zd|96z6~_;cqMRcS5wel9lqY`l?aDFji#-3>vEc)gQLKew&yMEFMM-c`3HY*)5G$%KAmtv9~pi zVf3EmBr;-a^0vIvHP0XvR}MiN&g!qM7Iy>J&)fBK-I*APnL0os9j6G_oPkjO@ynwC zW@pQ);A$n)qjq(w*SCTH3oNFS5F1+38H&bz(a0#Kp#5vgI_1&sE45%@LNHo`7sZKd z5?>;n5gntOjU$hjurGC@+`+9+SVZiQnt394bdcCp=CI?)3zQ<^(cqOZ9M4h!gget z5e`8tpVGzVeLMXPr&O*NDtOyfRpA1KbHoPVO4lxwws7H&1bo!<0M+9Cn9lTIz z9iAKH5K!%TJD<&dGwPSm$GDNvA!wM1mU}F#=CJHbP)wu)D?5;=Q*rc|M`eg99ul=M zWXm|4Z{KCsb(#qGkqf0$RJ()(@ybpR1AV>*)t2g+cYABYc6xt*i;TYoL}@7>{M*V7 zWao$~H-DLI&W59@D3$6Q|QTF$A{<58dGdq2oaorGf4y@Er;m1V0r95OzuQ(DHt ztG~bUox@>CP&Mj2Zw(u0f zF;+T@QRAx&onD`G{_7Au%%6cK>Xkh}f=u|dpa`S#bUWsz#ZK+#s8w>PgErQ|I&M7T zKYA+z4h~O$k6VI2dLbO~xrP3iYuhk=d@c2t89q;t_vv+XLnjO!+&~H@g>T=9+xzNT ztr4wc@#&rq)0l__sXjo5vDrKl%XrcMHE6=x64Np5i0ra93R=n=k}YyfNfBQ%pC`U({BN&NF4+qWoU)wpW*1g z6iR<2To3vt+z zp)^_9k?TG1ASa)a8Ph&}fHE?f=Vh$UgD37#*#$re{a5T1F>MnTo|IahjXJ+;<4$Cq zd@RzET8c0jKUY}km&O?hO85wEc#1$qr|j-f6^Om%g?-h|fBW{g`Lwe)(aju!8fXo| zd~5fw;Js^0e?}stCd+2j1ITs%c7D6|E)EnD3UgGg_$d8vc2fHR0Zz-!I3#xWZ?e1N zf42LKC@RwA7~gOnJfq)zQFb*48Zn28izNolR%|Kx%-B|vU87KM3GuHA)z*VQXFm&-4D{rFE*Zu*)4 literal 0 HcmV?d00001 From e87e5ed522f6f084110e42649117e78289f97dff Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Sun, 11 Jan 2026 11:43:27 +0100 Subject: [PATCH 108/108] Updated Changelog for v0.1 --- Changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Changelog.md b/Changelog.md index 825c32f..6c7862d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1 +1,10 @@ # Changelog + +## 0.1 + +- Created first working project setup +- Created GH Actions workflows for static code analysis +- Added working versions of project components + - web-app - chat bot conversation handling, uploading PDFs, visualizing retrieved documents, basic info & error messages handling + - llm-proxy - streaming chat responses, safety and relevance guardrails + - context-retriever - simple PDF document chunking, embeddings, handling vector store operations, basic query lookup, query reformulation \ No newline at end of file