From 5ef92def999cc1bf45a8c64aa15ce8be54479f80 Mon Sep 17 00:00:00 2001 From: Maxime de Pachtere Date: Thu, 15 Feb 2024 14:04:42 +0100 Subject: [PATCH] initial commit Co-authored-by: pbrochar Co-authored-by: mde-pach --- .env.template | 4 + .github/workflows/ci.yml | 30 + .gitignore | 168 ++ LICENSE.txt | 1 + README.md | 76 + blitz/__init__.py | 5 + blitz/alembic/README | 1 + blitz/alembic/env.py | 81 + blitz/alembic/script.py.mako | 27 + blitz/api/__init__.py | 3 + blitz/api/blitz_admin.py | 38 + blitz/api/blitz_api.py | 202 ++ blitz/api/logs.py | 79 + blitz/app.py | 207 ++ blitz/cli/__init__.py | 5 + blitz/cli/app.py | 18 + blitz/cli/commands/__init__.py | 0 blitz/cli/commands/clean.py | 16 + blitz/cli/commands/compile.py | 7 + blitz/cli/commands/create.py | 77 + blitz/cli/commands/list.py | 22 + blitz/cli/commands/release.py | 31 + blitz/cli/commands/start.py | 73 + blitz/cli/commands/swagger.py | 100 + blitz/core.py | 39 + blitz/db/__init__.py | 0 blitz/db/db.py | 54 + blitz/db/errors.py | 2 + blitz/db/migrations.py | 128 + blitz/models/__init__.py | 9 + blitz/models/base.py | 224 ++ blitz/models/blitz/__init__.py | 15 + blitz/models/blitz/config.py | 11 + blitz/models/blitz/field.py | 171 ++ blitz/models/blitz/file.py | 27 + blitz/models/blitz/resource.py | 61 + blitz/models/utils.py | 32 + blitz/parser.py | 66 + blitz/patch.py | 39 + blitz/settings.py | 28 + blitz/tools/__init__.py | 0 blitz/tools/erd.py | 110 + blitz/ui/__init__.py | 0 blitz/ui/assets/blitz_logo.png | Bin 0 -> 76836 bytes blitz/ui/assets/blitz_logo_and_text.png | Bin 0 -> 82064 bytes blitz/ui/assets/blitz_logo_and_text_2.png | Bin 0 -> 43841 bytes blitz/ui/assets/favicon.ico | Bin 0 -> 15406 bytes blitz/ui/assets/github_logo.png | Bin 0 -> 6393 bytes blitz/ui/assets/github_white.png | Bin 0 -> 4837 bytes blitz/ui/assets/swagger.png | Bin 0 -> 10969 bytes blitz/ui/assets/swagger.svg | 2 + blitz/ui/blitz_ui.py | 95 + blitz/ui/components/__init__.py | 0 blitz/ui/components/gpt_chat_components.py | 249 ++ blitz/ui/components/header.py | 141 + blitz/ui/components/json_editor.py | 120 + blitz/ui/components/logger.py | 29 + blitz/ui/components/status.py | 42 + blitz/ui/domains/__init__.py | 0 blitz/ui/main.py | 106 + blitz/ui/pages/__init__.py | 0 blitz/ui/pages/admin.py | 33 + blitz/ui/pages/blitz_file.py | 12 + blitz/ui/pages/dashboard.py | 55 + blitz/ui/pages/diagram.py | 46 + blitz/ui/pages/gpt_builder.py | 444 +++ blitz/ui/pages/log.py | 10 + blitz/ui/pages/projects.py | 61 + blitz/ui/pages/swagger.py | 26 + blitz/ui/preprompt.txt | 49 + blitz/ui/static/jse_theme_dark.css | 115 + blitz/ui/static/style.css | 29 + custom_templates/pydantic_v2/BaseModel.jinja2 | 39 + custom_templates/pydantic_v2/RootModel.jinja2 | 44 + custom_templates/root.jinja2 | 6 + docs/api/index.md | 2 + docs/blitzfile/config.md | 32 + docs/blitzfile/index.md | 181 ++ docs/blitzfile/reference.md | 2 + docs/blitzfile/relationship.md | 249 ++ docs/blitzfile/resources.md | 310 +++ docs/cli/create.md | 25 + docs/cli/index.md | 6 + docs/cli/list.md | 18 + docs/cli/references.md | 3 + docs/cli/release.md | 15 + docs/cli/start.md | 26 + docs/css/colors.css | 0 docs/css/custom.css | 178 ++ docs/css/termynal.css | 109 + docs/dashboard.md | 2 + docs/features.md | 19 + docs/images/blitz_banner.png | Bin 0 -> 42907 bytes docs/images/logo.png | Bin 0 -> 209328 bytes docs/index.md | 82 + docs/installation.md | 6 + docs/js/custom.js | 189 ++ docs/js/termynal.js | 283 ++ docs/quickstart.md | 1 + main.py | 5 + mkdocs.yml | 106 + poetry.lock | 2459 +++++++++++++++++ pyproject.toml | 44 + 103 files changed, 8392 insertions(+) create mode 100644 .env.template create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 blitz/__init__.py create mode 100644 blitz/alembic/README create mode 100644 blitz/alembic/env.py create mode 100644 blitz/alembic/script.py.mako create mode 100644 blitz/api/__init__.py create mode 100644 blitz/api/blitz_admin.py create mode 100644 blitz/api/blitz_api.py create mode 100644 blitz/api/logs.py create mode 100644 blitz/app.py create mode 100644 blitz/cli/__init__.py create mode 100644 blitz/cli/app.py create mode 100644 blitz/cli/commands/__init__.py create mode 100644 blitz/cli/commands/clean.py create mode 100644 blitz/cli/commands/compile.py create mode 100644 blitz/cli/commands/create.py create mode 100644 blitz/cli/commands/list.py create mode 100644 blitz/cli/commands/release.py create mode 100644 blitz/cli/commands/start.py create mode 100644 blitz/cli/commands/swagger.py create mode 100644 blitz/core.py create mode 100644 blitz/db/__init__.py create mode 100644 blitz/db/db.py create mode 100644 blitz/db/errors.py create mode 100644 blitz/db/migrations.py create mode 100644 blitz/models/__init__.py create mode 100644 blitz/models/base.py create mode 100644 blitz/models/blitz/__init__.py create mode 100644 blitz/models/blitz/config.py create mode 100644 blitz/models/blitz/field.py create mode 100644 blitz/models/blitz/file.py create mode 100644 blitz/models/blitz/resource.py create mode 100644 blitz/models/utils.py create mode 100644 blitz/parser.py create mode 100644 blitz/patch.py create mode 100644 blitz/settings.py create mode 100644 blitz/tools/__init__.py create mode 100644 blitz/tools/erd.py create mode 100644 blitz/ui/__init__.py create mode 100644 blitz/ui/assets/blitz_logo.png create mode 100644 blitz/ui/assets/blitz_logo_and_text.png create mode 100644 blitz/ui/assets/blitz_logo_and_text_2.png create mode 100644 blitz/ui/assets/favicon.ico create mode 100644 blitz/ui/assets/github_logo.png create mode 100644 blitz/ui/assets/github_white.png create mode 100644 blitz/ui/assets/swagger.png create mode 100644 blitz/ui/assets/swagger.svg create mode 100644 blitz/ui/blitz_ui.py create mode 100644 blitz/ui/components/__init__.py create mode 100644 blitz/ui/components/gpt_chat_components.py create mode 100644 blitz/ui/components/header.py create mode 100644 blitz/ui/components/json_editor.py create mode 100644 blitz/ui/components/logger.py create mode 100644 blitz/ui/components/status.py create mode 100644 blitz/ui/domains/__init__.py create mode 100644 blitz/ui/main.py create mode 100644 blitz/ui/pages/__init__.py create mode 100644 blitz/ui/pages/admin.py create mode 100644 blitz/ui/pages/blitz_file.py create mode 100644 blitz/ui/pages/dashboard.py create mode 100644 blitz/ui/pages/diagram.py create mode 100644 blitz/ui/pages/gpt_builder.py create mode 100644 blitz/ui/pages/log.py create mode 100644 blitz/ui/pages/projects.py create mode 100644 blitz/ui/pages/swagger.py create mode 100644 blitz/ui/preprompt.txt create mode 100644 blitz/ui/static/jse_theme_dark.css create mode 100644 blitz/ui/static/style.css create mode 100644 custom_templates/pydantic_v2/BaseModel.jinja2 create mode 100644 custom_templates/pydantic_v2/RootModel.jinja2 create mode 100644 custom_templates/root.jinja2 create mode 100644 docs/api/index.md create mode 100644 docs/blitzfile/config.md create mode 100644 docs/blitzfile/index.md create mode 100644 docs/blitzfile/reference.md create mode 100644 docs/blitzfile/relationship.md create mode 100644 docs/blitzfile/resources.md create mode 100644 docs/cli/create.md create mode 100644 docs/cli/index.md create mode 100644 docs/cli/list.md create mode 100644 docs/cli/references.md create mode 100644 docs/cli/release.md create mode 100644 docs/cli/start.md create mode 100644 docs/css/colors.css create mode 100644 docs/css/custom.css create mode 100644 docs/css/termynal.css create mode 100644 docs/dashboard.md create mode 100644 docs/features.md create mode 100644 docs/images/blitz_banner.png create mode 100644 docs/images/logo.png create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 docs/js/custom.js create mode 100644 docs/js/termynal.js create mode 100644 docs/quickstart.md create mode 100644 main.py create mode 100644 mkdocs.yml create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..bc7905e --- /dev/null +++ b/.env.template @@ -0,0 +1,4 @@ +BLITZ_PORT=8100 +DEFAULT_FILE="blitz.json" +BLITZ_DB_TYPE="MEMORY" +BLITZ_OPENAI_API_KEY="" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..567f162 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: documentation +on: + push: + branches: + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - name: Install Poetry + uses: snok/install-poetry@v1 + - run: poetry install --with=doc + - run: poetry run mkdocs gh-deploy --force \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56c2ad3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,168 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +app.db +database.db + +*migration.py +.python-version +.DS_Store +.nicegui/ \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..8ab70c0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1 @@ +MIT \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e6cbfe --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# + +![alt text](./docs/images/blitz_banner.png) +

+ ⚡️ Lightspeed API builder ⚡️ +

+ +![app version](https://img.shields.io/badge/version-0.1.0-brightgreen) +![app license](https://img.shields.io/badge/license-MIT-brightgreen) + +> [!CAUTION] +> Do not use in production, this is an alpha version. + +Full [Documentation](https://paperz-org.github.io/blitz/) here. + +# **What is Blitz ?** +Blitz is a tool that build restfull API on the fly based on a simple and easy to maintain configuration file. + +Here is an example of how simple a Blitz file is: + ```yaml + config: + name: Hello world + description: Here is a simple blitz configuration file. + version: 0.1.0 + models: + - name: TodoList + fields: + name: str + description: str + - name: Todo + fields: + name: str + due_date: str + todo_list_id: TodoList.id + ``` +> [!NOTE] +> Also available in Json format. + +# Quickstart + +## Installation + +### Using [pipx](https://pipx.pypa.io/stable/installation/) (recommanded) +```bash +pipx install git+https://github.com/Paperz-org/blitz.git@0.1.0 +``` + +## Create a blitz app + +```console +blitz create your-blitz-app +``` + +## Start your blitz app + +```console +blitz start your-blitz-app +``` + +*And yeah, that's it.* + +Just add some resources in the blitz file, and you have now a fully functional API with models and the corresponding database schema with all the modern feature you can expect from a modern app like: + +- Automatic Swagger UI for the API +- Admin +- Dashboard +- Data validation and error messages (thanks to Fastapi and SQLModel) +- Automatic database migration based on the changes of your blitz file +- Generated ERD diagram +- and more... + +

+ Made with :heart: and :coffee: by mde-pach and pbrochar +

+ + diff --git a/blitz/__init__.py b/blitz/__init__.py new file mode 100644 index 0000000..490b7f3 --- /dev/null +++ b/blitz/__init__.py @@ -0,0 +1,5 @@ +from .core import BlitzCore + +__all__ = [ + "BlitzCore", +] diff --git a/blitz/alembic/README b/blitz/alembic/README new file mode 100644 index 0000000..98e4f9c --- /dev/null +++ b/blitz/alembic/README @@ -0,0 +1 @@ +Generic single-database configuration. \ No newline at end of file diff --git a/blitz/alembic/env.py b/blitz/alembic/env.py new file mode 100644 index 0000000..e411149 --- /dev/null +++ b/blitz/alembic/env.py @@ -0,0 +1,81 @@ +from logging.config import fileConfig + +from sqlalchemy import engine_from_config +from sqlalchemy import pool +from blitz.models import BaseResourceModel + +from alembic import context + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +if config.config_file_name is not None: + fileConfig(config.config_file_name) + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +target_metadata = BaseResourceModel.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +def run_migrations_offline() -> None: + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, + target_metadata=target_metadata, + literal_binds=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online() -> None: + connectable = config.attributes.get("connection", None) + + if connectable is None: + # only create Engine if we don't have a Connection + # from the outside + connectable = engine_from_config( + config.get_section(config.config_ini_section, {}), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure(connection=connection, target_metadata=target_metadata) + + with context.begin_transaction(): + context.run_migrations() + else: + context.configure(connection=connectable, target_metadata=target_metadata) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/blitz/alembic/script.py.mako b/blitz/alembic/script.py.mako new file mode 100644 index 0000000..6ce3351 --- /dev/null +++ b/blitz/alembic/script.py.mako @@ -0,0 +1,27 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision: str = ${repr(up_revision)} +down_revision: Union[str, None] = ${repr(down_revision)} +branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} +depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} + + +def upgrade() -> None: + ${upgrades if upgrades else "pass"} + + +def downgrade() -> None: + ${downgrades if downgrades else "pass"} diff --git a/blitz/api/__init__.py b/blitz/api/__init__.py new file mode 100644 index 0000000..7d019a6 --- /dev/null +++ b/blitz/api/__init__.py @@ -0,0 +1,3 @@ +from .blitz_api import create_blitz_api + +__all__ = ["create_blitz_api"] diff --git a/blitz/api/blitz_admin.py b/blitz/api/blitz_admin.py new file mode 100644 index 0000000..e491d83 --- /dev/null +++ b/blitz/api/blitz_admin.py @@ -0,0 +1,38 @@ +from fastapi import FastAPI +from blitz.db.db import get_sqlite_engine +from starlette_admin.contrib.sqla import Admin, ModelView +from typing import TYPE_CHECKING +from starlette_admin.views import Link + +from blitz.settings import Settings, get_settings + +if TYPE_CHECKING: + from blitz.app import BlitzApp + + +class BlitzAdmin: + def __init__( + self, blitz_app: "BlitzApp", settings: Settings = get_settings() + ) -> None: + self.blitz_app = blitz_app + self.admin = Admin( + title=f"{blitz_app.name} Admin", + # FIXME find a better way to get the engine + engine=get_sqlite_engine( + blitz_app, in_memory=blitz_app._in_memory, file_name="app.db" + ), + base_url=f"/admin/", + ) + for resource in blitz_app.resources: + self.admin.add_view(ModelView(resource.model)) + + self.admin.add_view( + Link( + label="Go Back to Dashboard", + icon="fa fa-link", + url=f"http://localhost:{settings.BLITZ_PORT}/dashboard/projects/{self.blitz_app.name}", + ) + ) + + def mount_to(self, app: FastAPI) -> None: + self.admin.mount_to(app) diff --git a/blitz/api/blitz_api.py b/blitz/api/blitz_api.py new file mode 100644 index 0000000..798f313 --- /dev/null +++ b/blitz/api/blitz_api.py @@ -0,0 +1,202 @@ +from functools import partial +import os +from typing import Any + +import warnings + +from fastapi.responses import RedirectResponse +from blitz.api.blitz_admin import BlitzAdmin +from blitz.core import BlitzCore +from blitz.db.db import get_db +from blitz.db.errors import NoChangesDetectedError +from blitz.app import BlitzApp +from fastapi import FastAPI, APIRouter +from fastapi_crudrouter.core import CRUDGenerator # type: ignore +from fastapi_crudrouter import SQLAlchemyCRUDRouter # type: ignore +from semver import Version +from blitz.models.blitz.resource import BlitzResource +from blitz.patch import patch_fastapi_crudrouter +from blitz.settings import DBTypes, get_settings +from blitz.db.migrations import generate_migration, run_migrations +from blitz.api.logs import configure as configure_logs +from rich import print + +from sqlalchemy.exc import SAWarning + +# Patch the crudrouter to work with pydantic v2 +patch_fastapi_crudrouter() + + +class BlitzAPI(FastAPI): + def __init__( + self, + blitz_app: BlitzApp, + enable_config_route: bool = True, + *args: Any, + docs_url: str = "/api/docs", + redoc_url: str = "/api/redoc", + **kwargs: Any, + ) -> None: + super().__init__(*args, docs_url=docs_url, redoc_url=redoc_url, **kwargs) + self.blitz_app = blitz_app + self.blitz_app.load() + self.logger = self.blitz_app.logger + + if enable_config_route: + self.include_router(self._create_blitz_config_router()) + + for resource in self.blitz_app.resources: + router = self._create_crud_router(resource=resource) + self.include_router(router, prefix="/api") + + self._add_healthcheck() + self._add_redirect() + + configure_logs(self) + + def _add_healthcheck(self) -> None: + self.router.add_api_route( + "/api", + lambda: {"status": "ok"}, + methods=["GET"], + tags=["health"], + include_in_schema=False, + ) + + def _add_redirect(self) -> None: + self.router.add_api_route( + "/", + lambda: RedirectResponse(f"/dashboard/projects/{self.blitz_app.name}"), + methods=["GET"], + include_in_schema=False, + ) + + def _create_blitz_config_router(self) -> APIRouter: + path = "/blitz-config" + router = APIRouter() + router.add_api_route( + path=path, + endpoint=lambda: self.blitz_app.file.model_dump(by_alias=True), + methods=["GET"], + summary="Get Blitz Config", + description="Returns the Blitz Config for all resources", + ) + return router + + def _create_crud_router(self, resource: BlitzResource) -> CRUDGenerator: + read_model = resource.model.read_model() + create_model = resource.model.create_model() + update_model = resource.model.update_model() + + # Rebuild the model to include forward ref types that was not available at the time of the model creation + # We need to use the model AFTER the rebuild because if not, all the relationship and cie will not be set + # correctly. + types_namespace = {resource.model.__name__: resource.model for resource in self.blitz_app.resources} + read_model.model_rebuild(_types_namespace=types_namespace) + create_model.model_rebuild(_types_namespace=types_namespace) + update_model.model_rebuild(_types_namespace=types_namespace) + resource.model.model_rebuild(_types_namespace=types_namespace) + + return SQLAlchemyCRUDRouter( + schema=read_model, + create_schema=create_model, + update_schema=update_model, + db_model=resource.model, + db=partial( + get_db, + self.blitz_app, + get_settings().BLITZ_DB_TYPE == DBTypes.MEMORY, + "app.db", + ), + delete_all_route=False, + get_all_route=resource.config.can_read, + get_one_route=resource.config.can_read, + update_route=resource.config.can_update, + create_route=resource.config.can_create, + delete_one_route=resource.config.can_delete, + ) + + +def create_blitz_api( + blitz_app: BlitzApp | None = None, + enable_config_route: bool = True, + admin: bool = True, + *args: Any, + docs_url: str = "/api/docs", + redoc_url: str = "/api/redoc", + **kwargs: Any, +) -> BlitzAPI: + from blitz.ui.main import init_ui + + if blitz_app is None: + blitz = BlitzCore() + blitz_app_name = os.getenv("BLITZ_APP") + blitz_app_version = os.getenv("BLITZ_VERSION") + if blitz_app_name is None: + raise Exception("No blitz app name provided.") + enable_config_route = os.getenv("BLITZ_CONFIG_ROUTE", "").lower() == "true" + admin = os.getenv("BLITZ_ADMIN", "").lower() == "true" + blitz_app = blitz.get_app(blitz_app_name) + if blitz_app_version is not None: + blitz_app = blitz_app.get_version(Version.parse(blitz_app_version)) + + # TODO Maybe to remove + blitz_app.load() + blitz_api = BlitzAPI( + blitz_app, + enable_config_route, + *args, + docs_url=docs_url, + redoc_url=redoc_url, + **kwargs, + ) + + if not blitz_app_version: + run_migrations( + blitz_app=blitz_app, + in_memory=blitz_app._in_memory, + ) + + try: + generate_migration( + message="Blitz autogenerated migration", + blitz_app=blitz_app, + in_memory=blitz_app._in_memory, + ) + except NoChangesDetectedError: + pass + else: + run_migrations( + blitz_app=blitz_app, + in_memory=blitz_app._in_memory, + ) + else: + run_migrations( + blitz_app=blitz_app, + in_memory=blitz_app._in_memory, + is_release=True, + ) + + if admin: + # FIXME We need to fix the the relationship here. + # Proposed solution: "To silence this warning, add the parameter 'overlaps="todos"' to the 'Todo.todo_list' relationship." + # https://docs.sqlalchemy.org/en/20/errors.html#error-qzyx + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=SAWarning) + BlitzAdmin(blitz_app).mount_to(blitz_api) + + print("\n[bold yellow]This is still an alpha. Please do not use in production.[/bold yellow]") + print("[bold yellow]Please report any issues on https://github.com/Paperz-org/blitz[/bold yellow]") + print( + "\n".join( + ( + "\n[bold medium_purple1]Blitz app deployed.", + f" - Blitz UI : http://localhost:{get_settings().BLITZ_PORT}", + f" - Blitz admin : http://localhost:{get_settings().BLITZ_PORT}/admin", + f" - Swagger UI : http://localhost:{get_settings().BLITZ_PORT}/api/docs[/bold medium_purple1]\n", + ) + ) + ) + + init_ui(blitz_api=blitz_api) + return blitz_api diff --git a/blitz/api/logs.py b/blitz/api/logs.py new file mode 100644 index 0000000..3bd3d22 --- /dev/null +++ b/blitz/api/logs.py @@ -0,0 +1,79 @@ +from loguru import logger +import logging +import inspect +import sys +from typing import TYPE_CHECKING + +from blitz.app import BlitzApp + +if TYPE_CHECKING: + from blitz.api.blitz_api import BlitzAPI + + +class InterceptHandler(logging.Handler): + def __init__(self, level: int = logging.NOTSET) -> None: + super().__init__(level) + + def emit(self, record: logging.LogRecord) -> None: + # Get corresponding Loguru level if it exists. + level: str | int + try: + level = logger.level(record.levelname).name + except ValueError: + level = record.levelno + + if record.name in ("uvicorn.access",): + if record.args[2].startswith("/projects"): # type: ignore + record.name += ".ui" + elif record.args[2].startswith("/api"): # type: ignore + record.name += ".api" + elif record.args[2].startswith("/admin"): # type: ignore + record.name += ".admin" + + # Find caller from where originated the logged message. + frame, depth = inspect.currentframe(), 0 + while frame and (depth == 0 or frame.f_code.co_filename == logging.__file__): + frame = frame.f_back + depth += 1 + if record.name in ["uvicorn.access.ui", "uvicorn.access.admin"]: + pass + else: + logger.opt( + depth=depth, + exception=record.exc_info, + ).log(level, record.getMessage()) + + +def filter_logs(record: logging.LogRecord, blitz_app: BlitzApp) -> bool: + if record["name"].startswith("uvicorn.access"): # type: ignore + return True + if record["name"].startswith("uvicorn.server"): # type: ignore + return True + if record["name"].startswith("uvicorn.lifespan"): # type: ignore + return True + if record["name"].startswith("uvicorn.error"): # type: ignore + return True + if record["name"].startswith("uvicorn.asgi"): # type: ignore + return True + if record["name"].startswith("uvicorn.protocols"): # type: ignore + return True + if record["extra"].get("blitz_app", "") == blitz_app.name: # type: ignore + return True + return False + + +def configure(app: "BlitzAPI") -> None: + logger.remove() + logger.bind(app_name=app.blitz_app.name) + logger.add( + sys.stderr, + format=("{level: <9}" f" {app.blitz_app.name} " "{message}"), + colorize=True, + filter=lambda record: filter_logs(record, app.blitz_app), # type: ignore + ) + logger.level("INFO", color="") + logger.level("DEBUG", color="") + logger.level("ERROR", color="") + logger.level("WARNING", color="") + + logging.basicConfig(handlers=[InterceptHandler()], level=logging.INFO, force=True) diff --git a/blitz/app.py b/blitz/app.py new file mode 100644 index 0000000..e5628db --- /dev/null +++ b/blitz/app.py @@ -0,0 +1,207 @@ +from pathlib import Path + +from blitz.db.errors import NoChangesDetectedError +from blitz.models.base import BaseResourceModel, clear_metadata, create_resource_model +from blitz.models.blitz.field import _BlitzNullValue, AllowedBlitzFieldTypes, BlitzField, BlitzType +from blitz.models.blitz.file import BlitzFile +from blitz.models.blitz.resource import BlitzResource, BlitzResourceConfig +from blitz.parser import _find_blitz_file_path, parse_file +from blitz.db.migrations import generate_migration, run_migrations +import warnings +from sqlalchemy import exc as sa_exc +from semver import Version +from loguru import logger + + +class BlitzApp: + def __init__( + self, name: str, path: Path, file: BlitzFile, in_memory: bool = False, version: Version | None = None + ) -> None: + self.name = name + self.path = path + self.file = file + self.version = version + self.logger = logger.bind(blitz_app=self.name) + + # TODO Change to a database connector to make BlitzApp agnostic of the database implementation + self._in_memory = in_memory + self.resources: list[BlitzResource] = [] + self._is_loaded = False + self._base_resource_model: type[BaseResourceModel] = BaseResourceModel + self._available_version: list[Version] = [] + + self._load_versions() + + def _load_versions(self) -> None: + if not self.path.exists() or not self.path.is_dir(): + return + + for directory in self.path.iterdir(): + if directory.is_dir(): + try: + version = Version.parse(directory.name) + except: + continue + + try: + _find_blitz_file_path(self.path / str(version)) + except: + raise ValueError( + f"Blitz app {self.name} has a version dir '{version}' without a blitz file inside." + ) + self._available_version.append(version) + + self._available_version = sorted(self._available_version) + + def get_version(self, version: Version) -> "BlitzApp": + if version not in self._available_version: + raise ValueError(f"Version {version} not found for Blitz app {self.name}") + return BlitzApp( + name=self.name, + path=self.path, + file=parse_file(_find_blitz_file_path(self.path / str(version))), + in_memory=self._in_memory, + version=version, + ) + + def load(self) -> None: + """ + Can be more elegant + """ + if self._is_loaded: + return + + models_by_name: dict[str, type[BaseResourceModel]] = {} + config_by_name: dict[str, BlitzResourceConfig] = {config.name: config for config in self.file.resources_configs} + for config in self.file.resources_configs: + relationships: dict[str, list[str]] = {} + for field in config.fields.values(): + # Change the field type depending of the target table column type + if field.type == AllowedBlitzFieldTypes.foreign_key: + if not isinstance(field.foreign_key, _BlitzNullValue): + table, column = field.foreign_key.split(".") + if table not in config_by_name: + raise ValueError(f"Table `{table}` not found for foreign key `{field.foreign_key}`") + + if column in self._base_resource_model.__default_columns__: + field.type = BlitzType( + type=AllowedBlitzFieldTypes.from_class( + self._base_resource_model.__annotations__[column] + ) + ) + elif column in config_by_name[table].fields: + field.type = config_by_name[table].fields[column].type + else: + raise ValueError( + f"Column `{column}` not found in table `{table}` for foreign key `{field.foreign_key}`" + ) + else: + raise ValueError(f"Foreign key `{field.foreign_key}` is missing.") + + # We loop through the relationships to create the relationship field in the other table + for relationship in relationships: + config.fields[relationship.lower()] = BlitzField( + type=AllowedBlitzFieldTypes.relationship, # type: ignore + relationship=relationship, + ) + try: + model = create_resource_model(config, already_created_models=models_by_name) + models_by_name[config.name] = model + except Exception: + raise + self.resources.append(BlitzResource(config=config, model=model)) + + self._is_loaded = True + + def release(self, level: str, force: bool = False) -> Version: + clear_metadata() + + latest_version = self._available_version[-1] if self._available_version else None + + # If there is already a released version + if latest_version is not None: + # Check if the path (then the app) exists + latest_version_path = self.path / f"{latest_version}" + assert latest_version_path.exists() + + # We bump the version regarding the release level + match level: + case "major": + new_version = latest_version.bump_major() + case "minor": + new_version = latest_version.bump_minor() + case "patch": + new_version = latest_version.bump_patch() + + # We run the migrations to the latest version + latest_blitz_app = BlitzApp( + "", latest_version_path, parse_file(latest_version_path / self.file.path.name), in_memory=True + ) + + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=sa_exc.SAWarning) + latest_blitz_app.load() + + run_migrations( + blitz_app=self, + in_memory=True, + is_release=True, + ) + # Else, we consider it's the first release + else: + try: + # Use the version in the blitz file as initial version + new_version = Version.parse(self.file.config.version) + except: + logger.warning( + ( + f"Version in blitz file {self.file.path} is not a valid semver version." + "Using 0.1.0 as the new version." + ) + ) + new_version = Version(major=0, minor=1, patch=0) + + new_version_path = self.path / str(new_version) + new_blitz_file = self.file.model_copy() + new_blitz_file.config.version = str(new_version) + + # Now we run generate the migration for this blitz app + released_blitz_app = BlitzApp( + name=self.name, + path=self.path, + file=self.file, + in_memory=True, + ) + clear_metadata() + + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=sa_exc.SAWarning) + released_blitz_app.load() + + try: + generate_migration( + message="Blitz autogenerated migration", + blitz_app=released_blitz_app, + in_memory=True, + is_release=True, + ) + except NoChangesDetectedError: + if force is False: + raise + + # If everything went well, we create the new version directory + if not new_version_path.exists(): + new_version_path.mkdir(parents=True) + + # We copy the current blitz file to the new version directory + new_version_blitz_file_path = new_version_path / self.file.path.name + new_version_blitz_file_path.write_text(self.file.path.read_text()) + + # Automatically update the blitz file version needs a specific write method + # new_blitz_file = self.file.model_copy() + # new_blitz_file.config.version = str(new_version) + # new_version_blitz_file_path = new_version_path / self.file.path.name + # with open(new_version_blitz_file_path, "w") as f: + # new_blitz_config = new_blitz_file.config.version = str(new_version) + + return new_version diff --git a/blitz/cli/__init__.py b/blitz/cli/__init__.py new file mode 100644 index 0000000..13ec6cd --- /dev/null +++ b/blitz/cli/__init__.py @@ -0,0 +1,5 @@ +from .app import app + +__all__ = [ + "app", +] diff --git a/blitz/cli/app.py b/blitz/cli/app.py new file mode 100644 index 0000000..d6c3fdc --- /dev/null +++ b/blitz/cli/app.py @@ -0,0 +1,18 @@ +# from .commands.swagger import list_routes +from .commands.swagger import list_routes +from .commands.start import start_blitz +from .commands.clean import clean_blitz +from .commands.list import list_blitz_app +from .commands.create import create_blitz_app +from .commands.release import release_blitz + +import typer + +app = typer.Typer() +app.command(name="create")(create_blitz_app) +app.command(name="list")(list_blitz_app) +app.command(name="start")(start_blitz) +app.command(name="release")(release_blitz) +app.command(name="swagger")(list_routes) +# dev only +# app.command(name="clean")(clean_blitz) diff --git a/blitz/cli/commands/__init__.py b/blitz/cli/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/cli/commands/clean.py b/blitz/cli/commands/clean.py new file mode 100644 index 0000000..9bcbe3b --- /dev/null +++ b/blitz/cli/commands/clean.py @@ -0,0 +1,16 @@ +import os +import glob + + +def clean_blitz() -> None: + try: + os.remove("app.db") + except FileNotFoundError: + pass + + for file in glob.glob("**/versions/*_migratiob.py"): + if os.path.isfile(file): + try: + os.remove(file) + except FileNotFoundError: + pass diff --git a/blitz/cli/commands/compile.py b/blitz/cli/commands/compile.py new file mode 100644 index 0000000..98e8b36 --- /dev/null +++ b/blitz/cli/commands/compile.py @@ -0,0 +1,7 @@ +import typer + +from typing import Annotated + + +def compile_blitz(filename: Annotated[str, typer.Argument()]) -> None: + print(f"{filename}") diff --git a/blitz/cli/commands/create.py b/blitz/cli/commands/create.py new file mode 100644 index 0000000..f6617ac --- /dev/null +++ b/blitz/cli/commands/create.py @@ -0,0 +1,77 @@ +from pathlib import Path +from typing import Annotated, Optional +from rich import prompt, print +from blitz.models.blitz.file import BlitzFile +import yaml +from blitz.models.blitz.config import BlitzAppConfig +import typer + +DEFAULT_VERSION = "0.1.0" + + +def write_blitz_file(blitz_file: BlitzFile, blitz_file_format: str) -> Path: + if blitz_file_format == "json": + blitz_file_data = blitz_file.model_dump_json(indent=4, by_alias=True) + elif blitz_file_format == "yaml": + blitz_file_data = yaml.dump(blitz_file.model_dump(by_alias=True), default_flow_style=False) + else: + raise ValueError("Invalid blitz file format") + + with open(blitz_file.path, "w") as file: + file.write(blitz_file_data) + + return blitz_file.path + + +def create_blitz_app( + blitz_app_name: Annotated[ + Optional[str], typer.Argument(help="The name of the blitz app you want to create") + ] = None, +) -> None: + if not blitz_app_name: + # Interactive prompt to create a new blitz app + blitz_app_name = prompt.Prompt.ask( + "Enter the name of your blitz app", + default="Random Blitz App", + ) + blitz_app_description = prompt.Prompt.ask( + "Enter the description of your blitz app", + default="", + ) + blitz_file_format = prompt.Prompt.ask( + "Choose the format of the blitz file (can be changed later)", + choices=["json", "yaml"], + default="yaml", + ) + + blitz_app_path = Path(blitz_app_name.lower().replace(" ", "-")) + try: + # Create the blitz file + blitz_file = BlitzFile( + path=blitz_app_path / f"blitz.{blitz_file_format}", + config=BlitzAppConfig( + name=blitz_app_name, + description=blitz_app_description, + version=DEFAULT_VERSION, + ), + resources_configs=[], + raw_file={}, + ) + except Exception as e: + print(f"[red bold]Error[/red bold] while creating the blitz file: {e}") + typer.Exit(code=1) + try: + # Create the blitz app directory, the .blitz file and the blitz file + blitz_app_path.mkdir(parents=True) + blitz_app_file_path = blitz_app_path / ".blitz" + blitz_app_file_path.touch() + blitz_file_path = write_blitz_file(blitz_file, blitz_file_format) + with open(blitz_app_file_path, "w") as blitz_app_file: + blitz_app_file.write(str(blitz_file_path)) + except Exception as e: + print(f"[red bold]Error[/red bold] while creating the blitz app in the file system: {e}") + typer.Exit(code=1) + + print(f"\n[medium_purple1 bold]{blitz_app_name}[/medium_purple1 bold] created successfully !") + print("To start your app, you can use:") + print(f" [bold medium_purple1]blitz start {blitz_app_path}[/bold medium_purple1]") diff --git a/blitz/cli/commands/list.py b/blitz/cli/commands/list.py new file mode 100644 index 0000000..dd3a537 --- /dev/null +++ b/blitz/cli/commands/list.py @@ -0,0 +1,22 @@ +from rich.console import Console +from rich.table import Table +from blitz.core import BlitzCore + + +from blitz.app import BlitzApp + + +def print_blitz_app(blitz_apps: list[BlitzApp]) -> None: + console = Console() + table = Table("Blitz app name", "Version") + if len(blitz_apps) > 0: + for blitz_app in blitz_apps: + table.add_row(blitz_app.name, blitz_app.file.config.version) + else: + table.add_row("No blitz app found.") + console.print(table) + + +def list_blitz_app() -> None: + blitz = BlitzCore() + print_blitz_app(blitz.apps) diff --git a/blitz/cli/commands/release.py b/blitz/cli/commands/release.py new file mode 100644 index 0000000..7edd7a4 --- /dev/null +++ b/blitz/cli/commands/release.py @@ -0,0 +1,31 @@ +from typing import Annotated +from blitz import BlitzCore +import typer +from rich import print +import enum + +from blitz.db.errors import NoChangesDetectedError + + +class ReleaseLevel(enum.Enum): + major = "major" + minor = "minor" + patch = "patch" + + +def release_blitz( + blitz_app_name: Annotated[str, typer.Argument(..., help="Blitz app to release")], + level: Annotated[ReleaseLevel, typer.Argument(..., help="Release level")], + force: Annotated[bool, typer.Option(help="Force the release even if no changes are detected")] = False, +) -> None: + blitz = BlitzCore() + + app = blitz.get_app(blitz_app_name) + try: + new_version = app.release(level.value, force=force) + except NoChangesDetectedError: + typer.echo(f"No changes detected since the latest version. Use --force to release anyway.") + raise typer.Exit(code=1) + typer.echo(f"Blitz app {blitz_app_name} released at version {new_version}") + typer.echo("You can now start your versioned blitz app by running:") + print(f" [bold medium_purple1]blitz start {blitz_app_name} --version {new_version}[/bold medium_purple1]") diff --git a/blitz/cli/commands/start.py b/blitz/cli/commands/start.py new file mode 100644 index 0000000..f429fda --- /dev/null +++ b/blitz/cli/commands/start.py @@ -0,0 +1,73 @@ +import time +from semver import Version +import typer +import os +import uvicorn + +from pathlib import Path +from typing import Annotated, Optional +from uvicorn.supervisors import ChangeReload + +from blitz.api import create_blitz_api +from blitz.core import BlitzCore + +from blitz.settings import get_settings +from rich import print + + +def start_blitz( + blitz_app_name: Annotated[str, typer.Argument(..., help="Blitz app name")], + admin: Annotated[bool, typer.Option(help="Don't create admin.")] = True, + port: Annotated[int, typer.Option(help="Define the port of the server")] = get_settings().BLITZ_PORT, + config_route: Annotated[bool, typer.Option(help="Enable the blitz config route.")] = True, + hot_reload: Annotated[bool, typer.Option(help="Enable the hot reload.")] = True, + version: Annotated[Optional[str], typer.Option(help="Define the version of the app.")] = None, +) -> None: + blitz = BlitzCore() + + try: + blitz_app = blitz.get_app(blitz_app_name) + if version is not None: + blitz_app = blitz_app.get_version(Version.parse(version)) + except Exception as exc: + print(f"[red bold]There is no blitz app named {blitz_app_name}[/red bold]") + print("To list the available blitz apps run:") + print("[bold] blitz list[bold]") + print(f"Error: {exc}") + raise typer.Exit() + + print( + """[bold medium_purple1] +██████╗ ██╗ ██╗████████╗███████╗ ██████╗ ██╗ ██████╗ +██╔══██╗██║ ██║╚══██╔══╝╚══███╔╝ ██╔═████╗ ███║ ██╔═████╗ +██████╔╝██║ ██║ ██║ ███╔╝ ██║██╔██║ ╚██║ ██║██╔██║ +██╔══██╗██║ ██║ ██║ ███╔╝ ████╔╝██║ ██║ ████╔╝██║ +██████╔╝███████╗██║ ██║ ███████╗ ╚██████╔╝██╗██║██╗╚██████╔╝ +╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝╚═╝╚═╝ ╚═════╝ + [/bold medium_purple1]""" + ) + time.sleep(1) + if hot_reload: + # Need to be refacto + os.environ["BLITZ_APP"] = str(blitz_app.name) + if version is not None: + os.environ["BLITZ_VERSION"] = str(version) + os.environ["BLITZ_ADMIN"] = str(admin).lower() + os.environ["BLITZ_CONFIG_ROUTE"] = str(config_route).lower() + + server_config = uvicorn.Config( + "blitz.api:create_blitz_api", + factory=True, + host="localhost", + port=port, + reload=True, + reload_includes=str(blitz_app.file.path.relative_to(Path.cwd())), + reload_excludes=["*_migration.py", "migrations/*.py"], + log_config=None, + log_level="info", + ) + server = uvicorn.Server(server_config) + ChangeReload(server_config, target=server.run, sockets=[server_config.bind_socket()]).run() + else: + blitz_api = create_blitz_api(blitz_app, enable_config_route=config_route, admin=admin) + uvicorn.run(blitz_api, host="localhost", port=port, log_config=None, log_level="warning") diff --git a/blitz/cli/commands/swagger.py b/blitz/cli/commands/swagger.py new file mode 100644 index 0000000..036db09 --- /dev/null +++ b/blitz/cli/commands/swagger.py @@ -0,0 +1,100 @@ +import typer +from semver import Version +from typing import Annotated, Optional +from blitz.core import BlitzCore +from rich import print +from blitz.models import BlitzResource +from rich.style import Style +from rich.panel import Panel + + +class SwaggerPrinter: + POST_STYLE = Style(color="#49cc90") + GET_STYLE = Style(color="#61affe") + DELETE_STYLE = Style(color="#f93e3e") + PATCH_STYLE = Style(color="#fca130") + BOLD_STYLE = "[white bold]" + + def __init__(self, routes: list[BlitzResource]) -> None: + self.routes = routes + + def _get_create_panel(self, resource_name: str): + return Panel( + f"[{self.POST_STYLE}]POST [white bold]/{resource_name} [white dim frame]Create One", + border_style=self.POST_STYLE, + ) + + def _get_read_panel(self, resource_name: str): + + return [ + Panel( + f"[{self.GET_STYLE}]GET [white bold]/{resource_name} [white dim frame]Get One", + border_style=self.GET_STYLE, + ), + Panel( + f"[{self.GET_STYLE}]GET [white bold]/{resource_name}/{{item_id}} [white dim frame]Get All", + border_style=self.GET_STYLE, + ), + ] + + def _get_can_delete_panel(self, resource_name: str): + return Panel( + f"[{self.DELETE_STYLE}]DELETE [white bold]/{resource_name}/{{item_id}} [white dim frame]Delete One", + border_style=self.DELETE_STYLE, + ) + + def _get_can_update_panel(self, resource_name: str): + return Panel( + f"[{self.PATCH_STYLE}]PUT [white bold]/{resource_name}/{{item_id}} [white dim frame]Update One", + border_style=self.PATCH_STYLE, + ) + + def _get_name_panel(self, resource_name: str): + return Panel(f"[white bold]{resource_name.upper()}") + + def get_panels(self): + panels = [] + for resource in self.routes: + resource_name = resource.config.name.lower() + panels.append(self._get_name_panel(resource_name)) + if resource.config.can_create: + panels.append(self._get_create_panel(resource_name)) + if resource.config.can_read: + panels.extend(self._get_read_panel(resource_name)) + if resource.config.can_delete: + panels.append(self._get_can_delete_panel(resource_name)) + panels.append("\n") + return panels + + def print(self): + panels = self.get_panels() + for panel in panels: + print(panel) + + +def list_routes( + blitz_app_name: Annotated[str, typer.Argument(..., help="Blitz app name")], + model: Annotated[str, typer.Option()] = None, + version: Annotated[ + Optional[str], typer.Option(help="Define the version of the app.") + ] = None, +) -> None: + blitz = BlitzCore() + try: + blitz_app = blitz.get_app(blitz_app_name) + if version is not None: + blitz_app = blitz_app.get_version(Version.parse(version)) + blitz_app.load() + except Exception as exc: + print(f"[red bold]There is no blitz app named {blitz_app_name}[/red bold]") + print("To list the available blitz apps run:") + print("[bold] blitz list[bold]") + print(f"Error: {exc}") + raise typer.Exit() + if model: + for resource in blitz_app.resources: + if resource.config.name.lower() == model.lower(): + resources = [resource] + else: + resources = blitz_app.resources + SwaggerPrinter(resources).print() diff --git a/blitz/core.py b/blitz/core.py new file mode 100644 index 0000000..cfc6192 --- /dev/null +++ b/blitz/core.py @@ -0,0 +1,39 @@ +from pathlib import Path + +from blitz.app import BlitzApp +from blitz.parser import _find_blitz_app_path, _find_blitz_file_path, parse_file +from blitz.settings import DBTypes, get_settings + + +class BlitzCore: + BLITZ_DOT_FILE = ".blitz" + + def __init__(self) -> None: + self.apps: list[BlitzApp] = [] + self._discover_apps() + + def get_app(self, name: str) -> BlitzApp: + for app in self.apps: + if app.name == name: + return app + raise Exception(f"Blitz app {name} not found.") + + def _discover_apps(self) -> None: + """ + Discovers Blitz apps in the current directory and its subdirectories. + """ + + for dotfile in Path(".").glob(f"**/*{self.BLITZ_DOT_FILE}"): + blitz_app_name = dotfile.parent.name + blitz_app_path = _find_blitz_app_path(blitz_app_name) + blitz_file_path = _find_blitz_file_path(blitz_app_path) + blitz_file = parse_file(blitz_file_path) + + self.apps.append( + BlitzApp( + blitz_app_name, + blitz_app_path, + blitz_file, + in_memory=get_settings().BLITZ_DB_TYPE == DBTypes.MEMORY, + ) + ) diff --git a/blitz/db/__init__.py b/blitz/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/db/db.py b/blitz/db/db.py new file mode 100644 index 0000000..fcd40ae --- /dev/null +++ b/blitz/db/db.py @@ -0,0 +1,54 @@ +from pathlib import Path + +from sqlmodel import Session, create_engine +from typing import Any, Generator +from functools import lru_cache +from sqlalchemy import Engine, event +from sqlalchemy import pool +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from blitz.app import BlitzApp + + +def _fk_pragma_on_connect(dbapi_con: Any, con_record: Any) -> None: + """ + Enable foreign keys on SQLite. + """ + dbapi_con.execute("pragma foreign_keys=ON") + + +@lru_cache +def get_engine(url: str) -> Engine: + return create_engine(url, connect_args={"check_same_thread": False}, poolclass=pool.StaticPool) + + +# FIXME find how to avoid that +@lru_cache +def get_sqlite_engine( + blitz_app: "BlitzApp", + in_memory: bool, + file_name: str, +) -> Engine: + # TODO find a better implementation + if blitz_app.version: + file_name = f"{blitz_app.version}/{file_name}" + + if in_memory is True: + url = "sqlite://" + else: + url = f"sqlite:///{blitz_app.path.absolute()}/{file_name}" + engine = get_engine(url) + event.listen(engine, "connect", _fk_pragma_on_connect) + return engine + + +def get_db(blitz_app: "BlitzApp", in_memory: bool, file_name: str) -> Generator[Session, None, None]: + with Session(get_sqlite_engine(blitz_app, in_memory, file_name)) as session: + try: + yield session + session.commit() + except: + session.rollback() + finally: + session.close() diff --git a/blitz/db/errors.py b/blitz/db/errors.py new file mode 100644 index 0000000..a23625b --- /dev/null +++ b/blitz/db/errors.py @@ -0,0 +1,2 @@ +class NoChangesDetectedError(Exception): + pass diff --git a/blitz/db/migrations.py b/blitz/db/migrations.py new file mode 100644 index 0000000..28cde05 --- /dev/null +++ b/blitz/db/migrations.py @@ -0,0 +1,128 @@ +from pathlib import Path + +from alembic.script import Script +from argparse import Namespace +from alembic.config import Config +from alembic.util import AutogenerateDiffsDetected +from functools import lru_cache + +# from blitz.db.db import get_sqlite_engine + +from alembic.command import check, revision, upgrade + +from blitz.db.db import get_sqlite_engine +from blitz.db.errors import NoChangesDetectedError +import logging +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from blitz.app import BlitzApp + + +logging.getLogger("alembic").setLevel(logging.CRITICAL) + +DEFAULT_MIGRATION_FILE_NAME_TEMPLATE = "%%(epoch)s_%%(rev)s" +RELEASE_MIGRATION_FILE_NAME_TEMPLATE = "migration" + + +def get_alembic_config( + blitz_app: "BlitzApp", + file_name: str, + in_memory: bool = False, + is_release: bool = False, +) -> Config: + + # TODO find a better implementation + if blitz_app.version: + file_name = f"{blitz_app.version}/{file_name}" + + if in_memory: + url = "sqlite://" + else: + url = f"sqlite:///{blitz_app.path.absolute()}/{file_name}" + + if is_release: + file_name_template = RELEASE_MIGRATION_FILE_NAME_TEMPLATE + migrations_paths = set( + [str(blitz_app.path / str(version)) for version in blitz_app._available_version] + + [str(blitz_app.path / str(blitz_app.file.config.version))] + ) + else: + file_name_template = DEFAULT_MIGRATION_FILE_NAME_TEMPLATE + migrations_paths = set([str(blitz_app.path / "migrations")]) + + alembic_cfg = Config(cmd_opts=Namespace(quiet=True)) + + # FIXME: Ugly way to find the alembic folder + alembic_cfg.set_main_option("script_location", f"{Path(__file__).parent.parent.resolve()}/alembic") + alembic_cfg.set_main_option("sqlalchemy.url", url) + alembic_cfg.set_main_option("file_template", file_name_template) + alembic_cfg.set_main_option("version_locations", " ".join(migrations_paths)) + + alembic_cfg.set_main_option("recursive_version_locations", "true") + + return alembic_cfg + + +def generate_migration( + message: str, + blitz_app: "BlitzApp", + file_name: str = "app.db", + in_memory: bool = False, + is_release: bool = False, +) -> Path: + alembic_config = get_alembic_config( + blitz_app=blitz_app, + file_name=file_name, + in_memory=in_memory, + is_release=is_release, + ) + + # We attach the connection to the alembic config following the alembic sqlalchemy cookbook + # https://alembic.sqlalchemy.org/en/latest/cookbook.html#sharing-a-connection-across-one-or-more-programmatic-migration-commands + with get_sqlite_engine(blitz_app=blitz_app, in_memory=in_memory, file_name=file_name).begin() as connection: + alembic_config.attributes["connection"] = connection + + try: + check(alembic_config) + except AutogenerateDiffsDetected: + if is_release: + version_path = blitz_app.path / blitz_app.file.config.version + else: + version_path = blitz_app.path / "migrations" + + # Generate the migration + migration = revision( + alembic_config, + message=message, + autogenerate=True, + version_path=str(version_path), + ) + if isinstance(migration, Script): + return Path(migration.path) + else: + raise Exception("Too many migration generated.") + else: + raise NoChangesDetectedError("No migration to generate.") + + +def run_migrations( + blitz_app: "BlitzApp", + file_name: str = "app.db", + in_memory: bool = False, + is_release: bool = False, +) -> None: + # We attach the connection to the alembic config following the alembic sqlalchemy cookbook + # https://alembic.sqlalchemy.org/en/latest/cookbook.html#sharing-a-connection-across-one-or-more-programmatic-migration-commands + with get_sqlite_engine(blitz_app=blitz_app, in_memory=in_memory, file_name=file_name).begin() as connection: + alembic_config = get_alembic_config( + blitz_app=blitz_app, + file_name=file_name, + in_memory=in_memory, + is_release=is_release, + ) + alembic_config.attributes["connection"] = connection + upgrade( + alembic_config, + revision="head", + ) diff --git a/blitz/models/__init__.py b/blitz/models/__init__.py new file mode 100644 index 0000000..9168327 --- /dev/null +++ b/blitz/models/__init__.py @@ -0,0 +1,9 @@ +from .blitz import BlitzResource, BlitzResourceConfig, BlitzField +from .base import BaseResourceModel + +__all__ = [ + "BlitzResource", + "BlitzResourceConfig", + "BlitzField", + "BaseResourceModel", +] diff --git a/blitz/models/base.py b/blitz/models/base.py new file mode 100644 index 0000000..4a32049 --- /dev/null +++ b/blitz/models/base.py @@ -0,0 +1,224 @@ +from typing import Optional, TypeVar +import typing +import uuid +from sqlalchemy.orm import declared_attr +from pydantic import BaseModel, create_model +from uuid import UUID +from sqlmodel import Relationship, SQLModel, Field +from pydantic.fields import FieldInfo +from types import UnionType +from blitz.models.blitz.field import _BlitzNullValue, AllowedBlitzFieldTypes +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + from blitz.models.blitz.resource import BlitzResourceConfig + +T = TypeVar("T", bound="BaseModel") + + +class BaseResourceModel(SQLModel): + """ + Base class for SQL models. + + Attributes: + id (UUID): The primary key of the model. + """ + + @declared_attr # type: ignore + def __tablename__(cls) -> str: + """ + Get the table name for the model. + + Returns: + str: The table name. + """ + return cls.__name__ + + id: UUID = Field( + default_factory=uuid.uuid4, + description="Unique identifier for this resource.", + primary_key=True, + index=True, + nullable=False, + ) + + __default_columns__ = ["id"] + + @classmethod + def read_model(cls: type["BaseResourceModel"], *, depth: int = 1) -> type[BaseModel]: + """ + Create a read model based on the current model. + + Args: + depth: The depth of relationships to include in the read model. + + Returns: + The read model class. + """ + excluded_fields = [] # type: ignore + new_annotations = {} + fields = dict(cls.model_fields.items()) + + # If depth is 0, we don't want to include any relationship representation + if depth != 0: + fields.update( + { + relationship: cls.__annotations__[relationship] + for relationship in cls.__sqlmodel_relationships__.keys() + } + ) + + for field_name, field_info in fields.items(): + # if field_name in excluded_fields and not isinstance(field_info, Mapped): + if field_name not in excluded_fields: + if type(field_info) == typing._GenericAlias: # type: ignore + if type(field_info.__args__[0]) == BaseResourceModel: + type_ = field_info.__args__[0].read_model(depth=depth - 1) + else: + type_ = field_info.__args__[0] + elif type(field_info) == UnionType: # type: ignore + type_ = field_info.__args__ # type: ignore + elif isinstance(field_info, FieldInfo): + type_ = field_info.annotation # type: ignore + + new_annotations[field_name] = type_ + + new_model = type(f"{cls.__name__}Read", (BaseModel,), {"__annotations__": new_annotations}) + return new_model + + @classmethod + def create_model(cls: type["BaseResourceModel"]) -> type[BaseModel]: + """ + Create a create model based on the current model. + + Returns: + The create model class. + """ + excluded_fields = cls.__default_columns__ + new_annotations = {} + + for field_name, field_info in cls.model_fields.items(): + # if field_name in excluded_fields and not isinstance(field_info, Mapped): + if field_name not in excluded_fields: + if type(field_info) == typing._GenericAlias: # type: ignore + type_ = field_info.__args__[0] + continue + elif isinstance(field_info, FieldInfo): + type_ = field_info.annotation + else: + type_ = field_info + + new_annotations[field_name] = type_ + + new_model = type(f"{cls.__name__}Create", (BaseModel,), {"__annotations__": new_annotations}) + return new_model + + @classmethod + def update_model(cls: type["BaseResourceModel"]) -> type[BaseModel]: + """ + Create an update model based on the current model. + + Returns: + The update model class. + """ + excluded_fields = cls.__default_columns__ + new_annotations = {} + + for field_name, field_info in cls.model_fields.items(): + # if field_name in excluded_fields and not isinstance(field_info, Mapped): + if field_name not in excluded_fields: + if type(field_info) == typing._GenericAlias: # type: ignore + type_ = field_info.__args__[0] + continue + elif isinstance(field_info, FieldInfo): + type_ = field_info.annotation + else: + type_ = field_info + + new_annotations[field_name] = type_ + + new_model = type(f"{cls.__name__}Update", (BaseModel,), {"__annotations__": new_annotations}) + return new_model + + +def create_resource_model( + resource_config: "BlitzResourceConfig", already_created_models: dict[str, type[BaseResourceModel]] +) -> type[BaseResourceModel]: + """ + Creates a new BaseSqlModel class based on the provided BlitzResourceConfig. + + Args: + resource_config: The configuration object containing the information for creating the model. + already_created_models: A dictionary containing the already created models with their corresponding table names as key. + + Returns: + The newly created BaseSqlModel class based on the provided BlitzResourceConfig. + + This function iterates over the fields defined in the resource_config and creates the corresponding fields for the model. + It handles different field types such as foreign keys and relationships, and sets the appropriate attributes for each field. + """ + + fields: dict[Any, Any] = {} + for field_name, field in resource_config.fields.items(): + extra = {} + if not isinstance(field.default, _BlitzNullValue): + extra["default"] = field.default + + if not isinstance(field.foreign_key, _BlitzNullValue): + extra["foreign_key"] = field.foreign_key + + if not isinstance(field.nullable, _BlitzNullValue): + extra["nullable"] = field.nullable + else: + extra["nullable"] = True + + if extra["nullable"] is True and not "default" in extra: + extra["default"] = None + + if not isinstance(field.unique, _BlitzNullValue): + extra["unique"] = field.unique + + if field.type == AllowedBlitzFieldTypes.foreign_key: + pass + elif field.type == AllowedBlitzFieldTypes.relationship: + field_info = Relationship() + if not isinstance(field.relationship, _BlitzNullValue): + if field.relationship not in already_created_models: + try: + field_type = eval(field.relationship) + except NameError: + field_type = f"{field.relationship}" + if field.relationship_list is True: + field_type = list[field_type] # type: ignore + else: + field_type = already_created_models[field.relationship] + else: + raise ValueError(f"Relationship `{field.relationship}` is missing.") + else: + field_info = Field(**extra) + field_type = field.type.value + + if extra.get("nullable", False) is True: + field_type = Optional[field_type] + + fields[field_name] = ( + field_type, + field_info, + ) + + new_class = create_model( + resource_config.name, + __base__=BaseResourceModel, + __cls_kwargs__={"table": True}, + **fields, + ) + + return new_class + + +def clear_metadata() -> None: + """ + Clear the metadata of the BaseResourceModel and SQLModel classes. + """ + SQLModel.metadata.clear() + BaseResourceModel.metadata.clear() diff --git a/blitz/models/blitz/__init__.py b/blitz/models/blitz/__init__.py new file mode 100644 index 0000000..99ca7f3 --- /dev/null +++ b/blitz/models/blitz/__init__.py @@ -0,0 +1,15 @@ +from .config import BlitzAppConfig +from .resource import BlitzResourceConfig, BlitzResource +from .field import BlitzField, AllowedBlitzFieldTypes, BlitzType, _BlitzNullValue +from .file import BlitzFile + +__all__ = [ + "BlitzAppConfig", + "BlitzResourceConfig", + "BlitzResource", + "BlitzField", + "AllowedBlitzFieldTypes", + "BlitzType", + "_BlitzNullValue", + "BlitzFile", +] diff --git a/blitz/models/blitz/config.py b/blitz/models/blitz/config.py new file mode 100644 index 0000000..472f310 --- /dev/null +++ b/blitz/models/blitz/config.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel + + +class BlitzAppConfig(BaseModel): + """ + The Blitz config is the configuration for a Blitz app. It contains the name, description, and version of the app. + """ + + name: str + description: str | None = None + version: str diff --git a/blitz/models/blitz/field.py b/blitz/models/blitz/field.py new file mode 100644 index 0000000..850059c --- /dev/null +++ b/blitz/models/blitz/field.py @@ -0,0 +1,171 @@ +import enum +from blitz.models.utils import ContainsEnum +from typing import Any, ClassVar + +from pydantic import BaseModel, Field, computed_field, field_validator, model_serializer +import uuid +from datetime import datetime +import logging + +logger = logging.getLogger(__name__) + + +class _BlitzNullValue: + """ + This class is used to represent a null value in BlitzField. + """ + + ... + + +class AllowedBlitzFieldTypes(enum.StrEnum, metaclass=ContainsEnum): + str = "str" + int = "int" + float = "float" + uuid = "uuid" + datetime = "datetime" + foreign_key = "foreign_key" + relationship = "relationship" + + @classmethod + def from_class(cls, v: Any) -> "AllowedBlitzFieldTypes": + return cls(v.__name__.lower()) + + +class BlitzType(BaseModel): + TYPE_MAPPING: ClassVar[dict[AllowedBlitzFieldTypes, Any]] = { + AllowedBlitzFieldTypes.str: str, + AllowedBlitzFieldTypes.int: int, + AllowedBlitzFieldTypes.float: float, + AllowedBlitzFieldTypes.uuid: uuid.UUID, + AllowedBlitzFieldTypes.datetime: datetime, + } + TYPE_FACTORY_MAPPING: ClassVar[dict[AllowedBlitzFieldTypes, Any]] = { + AllowedBlitzFieldTypes.str: lambda: "string", + AllowedBlitzFieldTypes.int: int, + AllowedBlitzFieldTypes.float: float, + AllowedBlitzFieldTypes.uuid: uuid.uuid4, + AllowedBlitzFieldTypes.datetime: datetime.now, + } + type: AllowedBlitzFieldTypes + + def __init_subclass__(cls, **kwargs: Any) -> None: + for allowed_type in AllowedBlitzFieldTypes: + if allowed_type not in cls.TYPE_MAPPING: + logger.warning(f"Type {allowed_type} is not mapped with a factory in {cls.__name__}.TYPE_MAPPING.") + + @computed_field # type: ignore + @property + def value(self) -> Any: + return self.TYPE_MAPPING.get(self.type, None) + + @computed_field # type: ignore + @property + def factory(self) -> Any: + return self.TYPE_FACTORY_MAPPING.get(self.type, None) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(type='{self.type}')" + + def __eq__(self, __value: object) -> bool: + return self.type.value == __value + + @model_serializer + def _serialize_model(self) -> str: + return self.type.value + + +class BlitzField(BaseModel): + class Config: + arbitrary_types_allowed = True + + # Modifiers are used to define the properties of a field in the shortcut version of the blitz field + _unique_modifier: ClassVar[str] = "!" + _nullable_modifier: ClassVar[str] = "?" + _required_modifier: ClassVar[str] = "!" + _relationship_list_modifier: ClassVar[str] = "[]" + + _field_name_shortcut_modifiers: ClassVar[str] = "".join(_unique_modifier) + _field_value_shortcut_modifiers: ClassVar[str] = "".join( + [ + _nullable_modifier, + _required_modifier, + _relationship_list_modifier, + ] + ) + + # We store the raw values for writing them back in the blitz file + _raw_field_name: str | None = None + _raw_field_value: str | dict[str, Any] | None = None + + type: BlitzType + default: Any = Field(_BlitzNullValue(), exclude=True) + foreign_key: str | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + relationship: str | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + relationship_list: bool | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + back_populates: str | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + nullable: bool | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + unique: bool | _BlitzNullValue = Field(_BlitzNullValue(), exclude=True) + + @field_validator("type", mode="before") + def _string_to_customtype(cls, v: str | BlitzType) -> BlitzType: + if isinstance(v, str): + return BlitzType(type=AllowedBlitzFieldTypes(v)) + return v + + # Need a fix in pydantic maybe use a custom method to serialize the model and not the @model_serializer + # @model_serializer + # def _serialize_model(self) -> dict[str, Any] | str: + # if isinstance(self._raw_field_value, dict): + # return self.model_dump() + # elif isinstance(self._raw_field_value, str): + # return self.model_shortcut_dump() + # else: + # raise ValueError(f"Type `{type(self._raw_field_value)}` not allowed") + + @classmethod + def from_shortcut_version(cls, raw_field_name: str, raw_field_value: str) -> "BlitzField": + field_name = raw_field_name.strip(cls._field_name_shortcut_modifiers) + field_name_modifiers = raw_field_name[len(field_name) :] + + field_value = raw_field_value.strip(cls._field_value_shortcut_modifiers) + field_value_modifiers = raw_field_value[len(field_value) :] + + if cls._required_modifier in field_value_modifiers and cls._nullable_modifier in field_value_modifiers: + raise ValueError(f"Field `{field_name}` cannot be both required and nullable.") + + if field_value in AllowedBlitzFieldTypes: + field_type = AllowedBlitzFieldTypes(field_value) + elif "." in field_value: + field_type = AllowedBlitzFieldTypes.foreign_key + else: + field_type = AllowedBlitzFieldTypes.relationship + + return cls( + _raw_field_name=raw_field_name, + _raw_field_value=raw_field_value, + type=field_type, # type: ignore + nullable=cls._nullable_modifier in field_value_modifiers, + unique=cls._unique_modifier in field_name_modifiers, + default=None if cls._nullable_modifier in field_value_modifiers else _BlitzNullValue(), + foreign_key=field_value if field_type == AllowedBlitzFieldTypes.foreign_key else _BlitzNullValue(), + relationship=field_value if field_type == AllowedBlitzFieldTypes.relationship else _BlitzNullValue(), + relationship_list=( + cls._relationship_list_modifier in field_value_modifiers + if field_type == AllowedBlitzFieldTypes.relationship + else _BlitzNullValue() + ), + ) + + def model_shortcut_dump(self) -> str: + modifiers = [] + + if self.relationship_list is True: + modifiers.append(self._relationship_list_modifier) + + if self.nullable is True: + modifiers.append(self._nullable_modifier) + elif self.nullable is False: + modifiers.append(self._required_modifier) + + return f"{self.type}{''.join(modifiers)}" diff --git a/blitz/models/blitz/file.py b/blitz/models/blitz/file.py new file mode 100644 index 0000000..de7fc61 --- /dev/null +++ b/blitz/models/blitz/file.py @@ -0,0 +1,27 @@ +from typing import Any, ClassVar +from pydantic import BaseModel, Field +from blitz.models.blitz.config import BlitzAppConfig +from blitz.models.blitz.resource import BlitzResourceConfig +from pathlib import Path +from enum import StrEnum + +class FileType(StrEnum): + JSON = "json" + YAML = "yaml" + +class BlitzFile(BaseModel): + """ + The Blitz file is the configuration file for a Blitz app. It contains the BlitzAppConfig and a list of BlitzResourceConfig. + """ + + path: Path | None = Field(None, exclude=True) + file_type: FileType | None = Field(None, exclude=True) + config: BlitzAppConfig + resources_configs: list[BlitzResourceConfig] = Field( + [], serialization_alias="resources" + ) + raw_file: dict = Field(exclude=True) + + # def write(self) -> None: + # with open(self.path, "w") as blitz_file: + # blitz_file.write(self.model_dump_json) diff --git a/blitz/models/blitz/resource.py b/blitz/models/blitz/resource.py new file mode 100644 index 0000000..ba094f6 --- /dev/null +++ b/blitz/models/blitz/resource.py @@ -0,0 +1,61 @@ +from typing import Any +from pydantic import BaseModel, field_validator +from blitz.models.blitz.field import BlitzField +from blitz.models.base import BaseResourceModel + + +class BlitzResourceConfig(BaseModel): + """ + The BlitzResourceConfig is the configuration of a BlitzResource. It contains the name of the resource, the allowed + methods and the fields. The fields can be a string or a BlitzField object. + If the fields is a string, we are reading it like a shortcut version of a BlitzField object. + """ + + name: str + allowed_methods: str = "CRUD" + fields: dict[str, BlitzField] + + @field_validator("fields", mode="before") + def _string_to_fields(cls, v: dict[str, Any | dict[str, Any]]) -> dict[str, BlitzField]: + fields: dict[str, BlitzField] = {} + for raw_field_name, raw_field_value in v.items(): + field_name = raw_field_name.strip(BlitzField._field_name_shortcut_modifiers) + # If the field values is a string, it can be an blitz type or a relationship related field + if isinstance(raw_field_value, str): + fields[field_name] = BlitzField.from_shortcut_version(raw_field_name, raw_field_value) + # Else if the field value is a dict, it must be a BlitzField object + elif isinstance(raw_field_value, dict): + fields[field_name] = BlitzField( + _raw_field_name=raw_field_name, + _raw_field_value=raw_field_value, + **raw_field_value, + ) + else: + raise ValueError(f"Type `{type(raw_field_value)}` not allowed for field `{raw_field_name}`") + return fields + + @property + def can_create(self) -> bool: + return "C" in self.allowed_methods + + @property + def can_read(self) -> bool: + return "R" in self.allowed_methods + + @property + def can_update(self) -> bool: + return "U" in self.allowed_methods + + @property + def can_delete(self) -> bool: + return "D" in self.allowed_methods + + +class BlitzResource(BaseModel): + """ + The BlitzResource is the representation of a resource in Blitz. It contains the configuration used to generate the resource + and the SQLmodel class. + """ + + config: BlitzResourceConfig + model: type[BaseResourceModel] diff --git a/blitz/models/utils.py b/blitz/models/utils.py new file mode 100644 index 0000000..2b072da --- /dev/null +++ b/blitz/models/utils.py @@ -0,0 +1,32 @@ +import enum +from typing import Any + + +class ContainsEnum(enum.EnumMeta): + """ + Metaclass for Enums that provides a __contains__ method. + + This metaclass allows checking if a value is a valid member of the Enum by using the 'in' operator. + + Example: + >>> class MyEnum(Enum, metaclass=ContainsEnum): + ... VALUE1 = 'value1' + ... VALUE2 = 'value2' + + >>> print('value1' in MyEnum) # Output: True + >>> print('value3' in MyEnum) # Output: False + + """ + + def __new__(mcs, name: str, bases: tuple[Any], classdict: Any) -> "ContainsEnum": + return super().__new__(mcs, name, bases, classdict) + + def __contains__(cls, item: Any) -> bool: + try: + instance: enum.Enum = cls(item) + if isinstance(instance.value, enum.auto): + return False + except ValueError: + return False + else: + return True diff --git a/blitz/parser.py b/blitz/parser.py new file mode 100644 index 0000000..067373f --- /dev/null +++ b/blitz/parser.py @@ -0,0 +1,66 @@ +import json +from pathlib import Path + +import yaml +from typing import Any, NoReturn + +from blitz.models.blitz import BlitzFile + + +def _get_data_from_json(file: Path) -> dict[str, Any]: + with open(file, "r") as f: + return dict(json.load(f)) + + +def _get_data_from_yaml(file: Path) -> dict[str, Any]: + with open(file, "r") as f: + return dict(yaml.safe_load(f)) + + +def _no_parser_for_suffix(file: Path) -> NoReturn: + raise ValueError(f"No parser for {file}") + + +def _find_blitz_app_path(blitz_app_name: str) -> Path: + blitz_app_path = (Path(".") / Path(blitz_app_name)).absolute() + if not blitz_app_path.is_dir(): + raise FileNotFoundError(f"Could not find a Blitz app in {blitz_app_path}.") + return blitz_app_path + + +def _find_blitz_file_path(blitz_app_path: Path) -> Path: + yaml_blitz_file = blitz_app_path / "blitz.yaml" + json_blitz_file = blitz_app_path / "blitz.json" + + if yaml_blitz_file.exists() and json_blitz_file.exists(): + raise ValueError( + f"Found both a YAML and a JSON Blitz file in {blitz_app_path}." + ) + if yaml_blitz_file.exists(): + return yaml_blitz_file + elif json_blitz_file.exists(): + return json_blitz_file + else: + raise FileNotFoundError(f"Could not find a Blitz file in {blitz_app_path}.") + + +def parse_file(file_path: Path) -> BlitzFile: + blitz_file_fields = { + ".json": _get_data_from_json, + ".yaml": _get_data_from_yaml, + }.get(file_path.suffix, _no_parser_for_suffix)(file_path) + return BlitzFile( + path=file_path.absolute(), + file_type=file_path.suffix.removeprefix("."), + config=blitz_file_fields["config"], + resources_configs=blitz_file_fields["resources"], + raw_file=blitz_file_fields, + ) + + +def create_blitz_file_from_dict(blitz_file_content: dict) -> BlitzFile: + return BlitzFile( + config=blitz_file_content.get("config"), + resources_configs=blitz_file_content.get("resources"), + raw_file=blitz_file_content, + ) diff --git a/blitz/patch.py b/blitz/patch.py new file mode 100644 index 0000000..d90822f --- /dev/null +++ b/blitz/patch.py @@ -0,0 +1,39 @@ +def patch_fastapi_crudrouter() -> None: + import fastapi_crudrouter # type: ignore + from fastapi_crudrouter.core._types import T, PYDANTIC_SCHEMA # type: ignore + from typing import Any + from pydantic import __version__ as pydantic_version + + PYDANTIC_MAJOR_VERSION = int(pydantic_version.split(".", maxsplit=1)[0]) + + def get_pk_type_patch(schema: type[PYDANTIC_SCHEMA], pk_field: str) -> Any: + try: + if PYDANTIC_MAJOR_VERSION >= 2: + return schema.model_fields[pk_field].annotation + else: + return schema.__fields__[pk_field].type_ + except KeyError: + return int + + from pydantic import create_model + + def schema_factory_patch(schema_cls: type[T], pk_field_name: str = "id", name: str = "Create") -> type[T]: + """ + Is used to create a CreateSchema which does not contain pk + """ + + fields = {f.name: (f.type_, ...) for f in schema_cls.__fields__.values() if f.name != pk_field_name} + if PYDANTIC_MAJOR_VERSION >= 2: + # pydantic 2.x + fields = {fk: (fv.annotation, ...) for fk, fv in schema_cls.model_fields.items() if fk != pk_field_name} + else: + # pydantic 1.x + fields = {f.name: (f.type_, ...) for f in schema_cls.__fields__.values() if f.name != pk_field_name} + + name = schema_cls.__name__ + name + schema: type[T] = create_model(__model_name=name, **fields) # type: ignore + return schema + + fastapi_crudrouter.core._utils.get_pk_type = get_pk_type_patch + fastapi_crudrouter.core._utils.schema_factory = schema_factory_patch + fastapi_crudrouter.core._base.schema_factory = schema_factory_patch diff --git a/blitz/settings.py b/blitz/settings.py new file mode 100644 index 0000000..b32687b --- /dev/null +++ b/blitz/settings.py @@ -0,0 +1,28 @@ +import enum +from functools import lru_cache +import os + +from pydantic_settings import BaseSettings + +DOTENV = os.path.join(os.path.dirname(__file__), ".env") + + +class DBTypes(enum.StrEnum): + SQLITE = "SQLITE" + MEMORY = "MEMORY" + + +class Settings(BaseSettings): + class Config: + env_file = DOTENV + extra = "ignore" + + BLITZ_PORT: int = 8100 + DEFAULT_FILE: str = "blitz.json" + BLITZ_DB_TYPE: DBTypes = DBTypes.SQLITE + BLITZ_OPENAI_API_KEY: str = "" + + +@lru_cache() +def get_settings() -> Settings: + return Settings() diff --git a/blitz/tools/__init__.py b/blitz/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/tools/erd.py b/blitz/tools/erd.py new file mode 100644 index 0000000..21f393c --- /dev/null +++ b/blitz/tools/erd.py @@ -0,0 +1,110 @@ +import base64 +import json +from typing import Any +import zlib + +from sqlalchemy import Column, MetaData, Table + + +def determine_relationship_type(column: Column[Any], tables: dict[str, Table]) -> str: + """ + Determine the relationship type based on a foreign key column. + Args: + column: The foreign key column which contains information about both + the referencing and referenced table. + tables: A dictionary of table names to Table objects. + Returns: + The relationship type as a string. + #TODO can be improved with an enum + Raises: + Exception: If the relationship type cannot be determined. + """ + if not column.foreign_keys: + raise Exception(f"{column.table.name}.{column.name} does not have a foreign key reference.") + + foreign_key = list(column.foreign_keys)[0] + + current_side = "o|" if column.nullable else "||" + referenced_table = foreign_key.column.table + + for _, other_table in tables.items(): + for other_column in other_table.columns: + if other_column.foreign_keys: + if list(other_column.foreign_keys)[0].column.table.name == referenced_table.name: + if other_column.unique: + return f"|| -- {current_side}" + other_side = "}o" if other_column.nullable else "}|" + return f"{other_side} -- {current_side}" + + raise Exception(f"Could not determine relationship type for {column.table.name}.{column.name}") + + +def generate_mermaid_erd(metadata: MetaData) -> str: + """ + Generate Mermaid ERD from SQLAlchemy Metadata. + #TODO improve documentation + """ + erd = ["erDiagram"] + + tables = metadata.tables + + for table_name, table in tables.items(): + columns = [] + for col in table.columns: + col_desc = f"{col.name} {col.type}" + if col.primary_key: + col_desc += " PK" + if col.foreign_keys: + col_desc += " FK" + columns.append(col_desc) + columns_definition = "\n ".join(columns) + erd.append(f" {table_name} {{\n {columns_definition}\n }}") + + visited_relations = set() + for table_name, table in tables.items(): + for column in table.columns: + if column.foreign_keys: + referenced_table = list(column.foreign_keys)[0].column.table.name + + relation = determine_relationship_type(column, tables) + relation_key = tuple(sorted([table_name, referenced_table])) + + if relation and relation_key not in visited_relations: + erd.append(f' {table_name} {relation} {referenced_table}: " "') + visited_relations.add(relation_key) + + return "\n".join(erd) + + +def mermaid_serialize(erd: str) -> str: + """ + Based on the mermaid-live-editor implementation + For data format: + https://github.com/mermaid-js/mermaid-live-editor/blob/414c5bb59b162dae0a2ecc775828069a50725ee8/src/lib/types.d.ts#L21 + For data serialization: + https://github.com/mermaid-js/mermaid-live-editor/blob/414c5bb59b162dae0a2ecc775828069a50725ee8/src/lib/util/serde.ts#L19 + """ + data = json.dumps( + { + "code": erd, + "mermaid": '{ "theme": "dark" }', + "autoSync": False, + "updateDiagram": False, + "panZoom": True, + "pan": {"x": 0, "y": 0}, + "zoom": 1, + } + ) + compressed = zlib.compress(data.encode("utf-8"), level=9) + return base64.urlsafe_b64encode(compressed).decode("utf-8") + + +def _mermaid_deserialize(state: str) -> dict[str, Any]: + """ + For development purpose if you want to deserialize the data. + """ + missing_padding = len(state) % 4 + if missing_padding: + state += "=" * (4 - missing_padding) + data = base64.urlsafe_b64decode(state) + return dict(json.loads(zlib.decompress(data).decode("utf-8"))) diff --git a/blitz/ui/__init__.py b/blitz/ui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/ui/assets/blitz_logo.png b/blitz/ui/assets/blitz_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..93e5f41cfe8cf30503ff7a3144a74c0e5e0e4860 GIT binary patch literal 76836 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≺Bv=H#%yv-f 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 literal 0 HcmV?d00001 diff --git a/blitz/ui/assets/blitz_logo_and_text_2.png b/blitz/ui/assets/blitz_logo_and_text_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a1733a7f9746066f583c6cd86872af93efb4f08c GIT binary patch literal 43841 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 F_8-rZE3E(k literal 0 HcmV?d00001 diff --git a/blitz/ui/assets/favicon.ico b/blitz/ui/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..16ea44631a0bda63a0ed5e507d54bf4799ee64e0 GIT binary patch literal 15406 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 literal 0 HcmV?d00001 diff --git a/blitz/ui/assets/github_logo.png b/blitz/ui/assets/github_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb3b705d018006a2bd4200ea94c9d5fb98b6f76 GIT binary patch literal 6393 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 Hu0mjfZ$b4` literal 0 HcmV?d00001 diff --git a/blitz/ui/assets/github_white.png b/blitz/ui/assets/github_white.png new file mode 100644 index 0000000000000000000000000000000000000000..50b81752278d084ba9d449fff25f4051df162b0f GIT binary patch literal 4837 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 literal 0 HcmV?d00001 diff --git a/blitz/ui/assets/swagger.png b/blitz/ui/assets/swagger.png new file mode 100644 index 0000000000000000000000000000000000000000..80fd69849c18622230cb5781d1cff44366410984 GIT binary patch literal 10969 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 +Swagger icon \ No newline at end of file diff --git a/blitz/ui/blitz_ui.py b/blitz/ui/blitz_ui.py new file mode 100644 index 0000000..e96ff04 --- /dev/null +++ b/blitz/ui/blitz_ui.py @@ -0,0 +1,95 @@ +from functools import lru_cache +from pathlib import Path +from typing import Any +from blitz.app import BlitzApp +from blitz.core import BlitzCore +from blitz.settings import Settings, get_settings +from blitz.tools.erd import generate_mermaid_erd + + +# @lru_cache +# def get_erd(app: BlitzApp) -> str: +# return generate_mermaid_erd(app._base_resource_model.metadata) + + +class BlitzUI: + def __init__(self, settings: Settings = get_settings()) -> None: + self.blitz_app: BlitzCore = BlitzCore() + self.apps = self.blitz_app.apps + self.preprompt = self._get_preprompt() + + self.settings = settings + self.localhost_url = f"http://localhost:{settings.BLITZ_PORT}" + self.erd = None + self._current_project = None + self._current_app = None + + @property + def current_project(self) -> str | None: + return self._current_project + + @property + def current_app(self) -> BlitzApp | None: + return self._current_app + + @current_app.setter + def current_app(self, app: BlitzApp) -> None: + if not self.current_app: + self._current_app = app + self._current_project = app.name + self.erd = generate_mermaid_erd(app._base_resource_model.metadata) + + # @current_project.setter + # def current_project(self, project): + # if project and project != self.current_project: + # self._current_project = project + # self._current_app = self.get_current_app() + + def get_ressources(self) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + columns = [ + { + "name": "name", + "label": "Name", + "field": "name", + "required": True, + "align": "left", + "sortable": True, + }, + { + "name": "allowed_methods", + "label": "Allowed Methods", + "field": "allowed_methods", + "sortable": True, + }, + ] + rows = [] + for ressource in self.current_app.resources: + rows.append( + { + "name": ressource.config.name, + "allowed_methods": ressource.config.allowed_methods, + } + ) + + return columns, rows + + def get_current_app(self) -> BlitzApp | None: + if self.current_project: + return self.blitz_app.get_app(self.current_project) + return None + + def add(self, blitz_app: BlitzCore) -> None: + self.blitz_app = blitz_app + + def _get_preprompt(self) -> str: + with open(Path(__file__).parent / "./preprompt.txt", "r") as f: + return f.read() + + def reset_preprompt(self) -> None: + self.preprompt = self._get_preprompt() + print(self.preprompt) + + +@lru_cache +def get_blitz_ui() -> BlitzUI: + return BlitzUI() diff --git a/blitz/ui/components/__init__.py b/blitz/ui/components/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/ui/components/gpt_chat_components.py b/blitz/ui/components/gpt_chat_components.py new file mode 100644 index 0000000..6ad28cb --- /dev/null +++ b/blitz/ui/components/gpt_chat_components.py @@ -0,0 +1,249 @@ +import json +import re +from typing import Any +from nicegui import ui +from pydantic import ValidationError +from blitz.parser import create_blitz_file_from_dict +from blitz.ui.components.json_editor import JsonEditorComponent + + +from blitz.ui.components.header import DARK_PINK, MAIN_PINK +import yaml + + +class ResponseJSON: + def __init__(self, text: str) -> None: + self.text = text + self.json = self.extract_json(text) + + self.is_valid_blitz_file = self.validate_blitz_file(self.json) + + self.blitz_app_title = self._get_expansion_title(self.json) + self.color = self._get_color(self.is_valid_blitz_file) + + self._expansion = None + self._expansion_is_open = True + self._dialog = None + + @staticmethod + def _get_expansion_title(blitz_file: dict[str, str]) -> str: + name_part = blitz_file.get("config", {}).get("name", "Blitz App") + version = blitz_file.get("config", {}).get("version", "0.0.0") + return f"{name_part} v{version}" + + @staticmethod + def _get_color(is_valid: bool) -> str: + if is_valid: + return "text-green" + return "text-red" + + def validate_blitz_file(self, json: dict[str, Any]) -> bool: + try: + create_blitz_file_from_dict(json) + except ValidationError: + return False + else: + return True + + @staticmethod + def extract_json(text): + json_pattern = r"```json([\s\S]*?)```" + return json.loads(re.search(json_pattern, text).group(1)) + + async def copy_code(self): + ui.run_javascript("navigator.clipboard.writeText(`" + str(self.json) + "`)") + ui.notify("Copied to clipboard", type="info", color="green") + + def action_buttons(self): + with ui.row(wrap=False).classes("items-center"): + ui.button( + icon="content_copy", + color="transparent", + on_click=self.copy_code, + ).props("dense flat size=xm color=grey") + ui.button( + icon="file_download", color="transparent", on_click=self._dialog.open + ).props("dense flat size=xm color=grey") + + def download_dialog(self): + with ui.dialog() as self._dialog, ui.card().classes("w-full px-4"): + if not self.is_valid_blitz_file: + self.invalid_blitz_file() + # with ui.expansion("Edit File", icon="edit").classes("w-full h-auto rounded-lg border-solid border overflow-hidden grow overflow-hidden"): + # JsonEditorComponent(self.json).render() + with ui.row().classes("w-full justify-end"): + ui.button( + "Export as JSON", + on_click=self._download_json, + ).props("flat") + ui.button("Export as YAML", on_click=self._download_yaml).props("flat") + + def _download_json(self): + ui.download( + str.encode(json.dumps(self.json, indent=4)), + filename=self._get_filename("json"), + ) + + def _download_yaml(self): + ui.download( + str.encode(yaml.dump(self.json)), filename=self._get_filename("yaml") + ) + + def _get_filename(self, extension: str) -> str: + return f"{self.blitz_app_title.replace(' ', '_').replace('.', '_').lower()}.{extension}" + + def invalid_blitz_file(self): + with ui.row().classes("items-center"): + ui.icon("error", color="red", size="sm") + ui.label("This is not a valid Blitz file.").classes("text-red") + + def _toggle_expansion(self): + self._expansion_is_open = not self._expansion_is_open + self._expansion.value = self._expansion_is_open + + @ui.refreshable + def render(self): + self.download_dialog() + with ui.row(wrap=False).classes("items-center w-full"): + with ui.expansion( + self.blitz_app_title, + icon="settings_suggest", + value=self._expansion_is_open, + on_value_change=self._toggle_expansion, + ).classes("rounded-lg border-solid border overflow-hidden grow").props( + f"overflow-hidden header-class={self.color}" + ) as self._expansion: + if not self.is_valid_blitz_file: + self.invalid_blitz_file() + ui.markdown(self.text) + self.action_buttons() + + +class MarkdownResponse: + def __init__(self, text: str) -> None: + self.text = text + + @ui.refreshable + def render(self): + ui.markdown(self.text) + + +class GPTChatComponent: + def __init__( + self, + label: str, + icon: str, + text: str, + avatar_color: str | None = None, + ) -> None: + self.response_json = None + self.label = label + self.text = text + self.icon = icon + self.avatar_color = avatar_color + self.text_components = None + + @ui.refreshable + def render(self): + with ui.row(wrap=False).classes("w-full"): + ui.space().classes("w-1/3") + with ui.column().classes("justify-start w-2/3"): + with ui.row(wrap=False).classes("items-center w-full"): + with ui.avatar(color=self.avatar_color).props("size=sm"): + ui.icon(self.icon, size="xs", color="white") + ui.label(self.label).classes("font-bold") + + if self.text_components: + for component in self.text_components: + with ui.element().classes("px-10 w-full"): + component.render() + else: + with ui.element().classes("px-10"): + ui.markdown(self.text) + ui.space().classes("w-1/3") + + def as_gpt_dict(self) -> dict[str, str]: + raise NotImplementedError + + def to_dict(self) -> dict[str, str]: + raise NotImplementedError + + +class UserQuestion(GPTChatComponent): + LABEL = "You" + ICON = "person" + AVATAR_COLOR = "#a72bff" + ROLE = "user" + + def __init__(self, text: str = "") -> None: + super().__init__( + label=self.LABEL, text=text, icon=self.ICON, avatar_color=self.AVATAR_COLOR + ) + + def as_gpt_dict(self) -> dict[str, str]: + return {"role": self.ROLE, "content": self.text} + + def to_dict(self) -> dict[str, str]: + return self.as_gpt_dict() + + @classmethod + def from_gpt_dict(cls, gpt_dict: dict[str, str]) -> "UserQuestion": + return cls(text=gpt_dict.get("content")) + + +class GPTResponse(GPTChatComponent): + LABEL = "GPT" + ICON = "self_improvement" + AVATAR_COLOR = "#74aa9c" + ROLE = "assistant" + + def __init__(self, text: str = "", text_is_finished: bool = False) -> None: + super().__init__( + label=self.LABEL, text=text, icon=self.ICON, avatar_color=self.AVATAR_COLOR + ) + self._text_is_finished = None + self.text_is_finished = text_is_finished + + def add(self, text: str) -> None: + self.text += text + self.render.refresh() + + @property + def text_is_finished(self) -> bool: + return self._text_is_finished + + @text_is_finished.setter + def text_is_finished(self, value: bool) -> None: + if value is True: + self._text_is_finished = value + self.text_components = self.split_response(self.text) + self.render.refresh() + else: + self._text_is_finished = value + + def as_gpt_dict(self) -> dict[str, str]: + return {"role": self.ROLE, "content": self.text} + + def to_dict(self) -> dict[str, str]: + dict_ = self.as_gpt_dict() + dict_["text_is_finished"] = self.text_is_finished + return dict_ + + @staticmethod + def split_response(text) -> list: + json_pattern = r"(```json[\s\S]*?```)" + + # Search for JSON content in the Markdown text + components = [] + for match in re.split(json_pattern, text): + if re.match(json_pattern, match): + components.append(ResponseJSON(match)) + else: + components.append(MarkdownResponse(match)) + return components + + @classmethod + def from_gpt_dict(cls, gpt_dict: dict[str, str]) -> "UserQuestion": + return cls( + text=gpt_dict.get("content"), text_is_finished=gpt_dict["text_is_finished"] + ) diff --git a/blitz/ui/components/header.py b/blitz/ui/components/header.py new file mode 100644 index 0000000..bdf158e --- /dev/null +++ b/blitz/ui/components/header.py @@ -0,0 +1,141 @@ +from contextlib import contextmanager +from pathlib import Path + +from nicegui import Tailwind, ui, app + +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui + +MAIN_PINK = "#cd87ff" +DARK_PINK = "#a72bff" + + +class HeaderMenuComponent: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + pass + + def render(self): + ui.button(icon="menu").props("flat") + + +class HeaderComponent: + def __init__(self, title: str = "", blitz_ui: BlitzUI = get_blitz_ui(), drawer=None) -> None: + self.title = title + self.blitz_ui = blitz_ui + + self.dark_mode = ui.dark_mode(value=True) + self.home_link = f"dashboard/projects/{blitz_ui.current_project}" if blitz_ui.current_project else "projects" + self.drawer = drawer + ui.add_head_html(f"") + + ui.add_head_html( + f"" + ) + + ui.colors( + primary="fffafa", + secondary="#a72bff", + accent="#111B1E", + positive="#53B689", + dark="#3e3e42", + ) + + def render(self): + with ui.header(bordered=True).classes("pl-1 pr-8 justify-between content-center h-16 backdrop-blur-sm"): + + with ui.row().classes("items-center space-x-20 content-center my-auto"): + + with ui.row().classes("items-center space-x-0 content-center "): + if self.drawer is not None: + ui.button(icon="menu", on_click=self.drawer.toggle).props("flat") + ui.icon(name="bolt", color=DARK_PINK, size="32px") + with ui.link(target=f"/projects/{self.blitz_ui.current_project}"): + ui.label("Blitz Dashboard") + + with ui.row().classes("items-center justify-between content-center"): + with ui.link(target=f"{self.blitz_ui.localhost_url}/projects").classes("disabled"): + ui.tooltip("Multiple App management is coming soon") + ui.label("Projects") + with ui.link(target="/gpt"): + ui.label("GPT Builder") + with ui.link(target="https://paperz-org.github.io/blitz/", new_tab=True): + ui.label("Documentation") + with ui.row().classes("items-center content-center my-auto"): + with ui.element(): + ui.button( + icon="dark_mode", + on_click=lambda: self.dark_mode.set_value(True), + ).props( + "flat fab-mini color=black disabled" + ).bind_visibility_from(self.dark_mode, "value", value=False) + ui.button( + icon="light_mode", + on_click=lambda: self.dark_mode.set_value(False), + ).props( + "flat fab-mini color=white disabled" + ).bind_visibility_from(self.dark_mode, "value", value=True) + ui.tooltip("White mode is coming soon") + with ui.link(target="https://github.com/Paperz-org/blitz", new_tab=True).classes(" w-8"): + ui.image(Path(__file__).parent.parent / "./assets/github_white.png").classes("w-8 ") + + +class MenuLink: + def __init__(self, label: str, link: str, icon: str) -> None: + self.label = label + self.link = link + self.icon = icon + + def render(self): + + with ui.link(target=self.link).classes("w-full"), ui.button(on_click=self.go_to).props( + "flat align=left" + ).classes("px-4 hover:bg-slate-700 rounded-sm w-full") as self.button: + ui.icon(name=self.icon, size="sm").props("flat").classes("pr-4") + ui.label(self.label) + + def go_to(self): + ui.open(self.link) + + +class FrameComponent: + def __init__( + self, + blitz_ui: BlitzUI = get_blitz_ui(), + show_drawer: bool = True, + drawer_open: bool = True, + ) -> None: + self.blitz_ui = blitz_ui + self.current_project = blitz_ui.current_project + self.show_drawer = show_drawer + self.drawer_open = drawer_open + + # Only for declarative + self.drawer = None + + def left_drawer(self): + with ui.left_drawer(value=self.drawer_open, fixed=True, bottom_corner=True).props("width=200").classes( + "px-0 bg-[#14151a]" + ) as self.drawer: + + MenuLink("Dashboard", f"/projects/{self.current_project}", "dashboard").render() + MenuLink( + "Admin", + f"{self.blitz_ui.localhost_url}/admin/", + "table_chart", + ).render() + MenuLink("Swagger", f"/projects/{self.current_project}/swagger", "api").render() + MenuLink( + "Blitz File", + f"/projects/{self.current_project}/blitz-file", + "article", + ).render() + MenuLink( + "Diagram", + f"/projects/{self.current_project}/diagram", + "account_tree", + ).render() + MenuLink("Logs", f"/projects/{self.current_project}/logs", "list").render() + + def render(self): + if self.show_drawer and self.current_project is not None: + self.left_drawer() + HeaderComponent(drawer=self.drawer).render() diff --git a/blitz/ui/components/json_editor.py b/blitz/ui/components/json_editor.py new file mode 100644 index 0000000..d236782 --- /dev/null +++ b/blitz/ui/components/json_editor.py @@ -0,0 +1,120 @@ +import json +from typing import Any +from nicegui import ui, app +from pydantic import ValidationError +import yaml +from blitz.models.blitz.file import FileType +from blitz.parser import create_blitz_file_from_dict, parse_file +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from blitz.ui.components.header import DARK_PINK, MAIN_PINK + + +class JsonEditorComponent: + primary_color = DARK_PINK + highlight_color = MAIN_PINK + + def __init__( + self, + content: dict[str, Any], + ) -> None: + self.content = content + + def render(self): + ui.json_editor({"content": {"json": self.content}, "readOnly": False}).classes( + "w-full jse-theme-dark rounded-lg" + ).style( + f"--jse-theme-color: {self.primary_color}; --jse-theme-color-highlight: {self.highlight_color}" + ) + + +class BlitzFileEditorComponent: + primary_color = DARK_PINK + highlight_color = MAIN_PINK + + def __init__( + self, + content: dict[str, Any], + mode: str = "text", + blitz_ui: BlitzUI = get_blitz_ui(), + ) -> None: + self.blitz_ui = blitz_ui + self._original_content = content + if app.storage.user.get("blitz_file_content") is not None: + self.content = app.storage.user.get("blitz_file_content") + else: + self.content = content + self.mode = mode + self._read_only = True + + async def get_data(self) -> None: + raw_content: dict = await self.editor.run_editor_method("get") + try: + json_content = json.loads(raw_content.get("text")) + except (json.JSONDecodeError, TypeError): + return + self.content = json_content + app.storage.user["blitz_file_content"] = self.content + + def enable_editor(self): + self._read_only = not self._read_only + self.editor.run_editor_method("updateProps", {"readOnly": self._read_only}) + + def reset_content(self): + self.content = self._original_content + self.editor.run_editor_method("update", {"json": self.content}) + app.storage.user["blitz_file_content"] = self.content + ui.notify("Content Reset", type="positive") + + def validate(self): + try: + create_blitz_file_from_dict(self.content) + except ValidationError: + ui.notify("Invalid Blitz File", type="negative") + else: + ui.notify("Valid Blitz File", type="positive") + + def save(self): + try: + create_blitz_file_from_dict(self.content) + except ValidationError: + ui.notify("Invalid Blitz File", type="negative") + return + try: + with open(self.blitz_ui.current_app.file.path, "w") as f: + if self.blitz_ui.current_app.file.file_type == FileType.JSON: + f.write(json.dumps(self.content, indent=4)) + elif self.blitz_ui.current_app.file.file_type == FileType.YAML: + f.write(yaml.dump(self.content, indent=4)) + except Exception: + ui.notify("Error While Saving File", type="negative") + else: + ui.notify("Content Saved", type="positive") + + def render(self): + with ui.row().classes( + "w-full justify-between align-center p-4 rounded-lg border" + ): + with ui.row().classes("justify-between"): + ui.switch("Edit BlitzFile", on_change=self.enable_editor) + ui.button( + "Reset", on_click=self.reset_content, icon="restart_alt" + ).props("flat") + with ui.row().classes("justify-between"): + ui.button("Validate", on_click=self.validate, icon="verified").props( + "flat" + ) + ui.button("Save", on_click=self.save, icon="save").props("flat") + self.editor = ( + ui.json_editor( + { + "content": {"json": self.content}, + "readOnly": self._read_only, + "mode": self.mode, + }, + on_change=self.get_data, + ) + .classes("w-full jse-theme-dark rounded-lg") + .style( + f"--jse-theme-color: {self.primary_color}; --jse-theme-color-highlight: {self.highlight_color}" + ) + ) diff --git a/blitz/ui/components/logger.py b/blitz/ui/components/logger.py new file mode 100644 index 0000000..d89ab54 --- /dev/null +++ b/blitz/ui/components/logger.py @@ -0,0 +1,29 @@ +import logging +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from nicegui import ui +from blitz.api.logs import InterceptHandler + + +class LogElementHandler(InterceptHandler): + """A logging handler that emits messages to a log element.""" + + def __init__(self, element: ui.log, level: int = logging.NOTSET) -> None: + self.element = element + super().__init__(level) + + def emit(self, record: logging.LogRecord) -> None: + try: + if record.name != "uvicorn.access.ui": + self.element.push(record.getMessage()) + except Exception: + self.handleError(record) + + +class LogComponent: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + self._logger = logging.getLogger("uvicorn.access") + + def render(self): + log = ui.log(max_lines=None).classes("w-full h-64 text-sm") + self._logger.addHandler(LogElementHandler(log)) diff --git a/blitz/ui/components/status.py b/blitz/ui/components/status.py new file mode 100644 index 0000000..c822cad --- /dev/null +++ b/blitz/ui/components/status.py @@ -0,0 +1,42 @@ +from nicegui import ui + +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from httpx import AsyncClient + + +class StatusComponent: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + self.app = self.blitz_ui.current_app + self.api_up = False + self.admin_up = False + ui.timer(10.0, self.set_status) + + async def _is_api_up(self): + async with AsyncClient() as client: + response = await client.get(f"{self.blitz_ui.localhost_url}/api") + return response.status_code == 200 + + async def _is_admin_up(self): + async with AsyncClient() as client: + response = await client.get(f"{self.blitz_ui.localhost_url}/admin/") + return response.status_code == 200 + + async def set_status(self): + self.api_up = await self._is_api_up() + self.admin_up = await self._is_admin_up() + self.render.refresh() + + @ui.refreshable + def render(self): + with ui.grid(rows=2, columns=2).classes("gap-4"): + ui.label(f"API:").classes("text-lg font-bold") + if self.api_up: + ui.icon(name="check_circle").classes("text-green-500") + else: + ui.icon(name="error").classes("text-red-500") + ui.label(f"Admin:").classes("text-lg font-bold") + if self.admin_up: + ui.icon(name="check_circle").classes("text-green-500") + else: + ui.icon(name="error").classes("text-red-500") diff --git a/blitz/ui/domains/__init__.py b/blitz/ui/domains/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/ui/main.py b/blitz/ui/main.py new file mode 100644 index 0000000..fabe42b --- /dev/null +++ b/blitz/ui/main.py @@ -0,0 +1,106 @@ +import logging +from typing import TYPE_CHECKING, Annotated + +from blitz.app import BlitzApp +from blitz.core import BlitzCore +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from blitz.ui.pages.admin import AdminPage +from blitz.ui.pages.blitz_file import BlitzFilePage +from blitz.ui.pages.dashboard import DashboardPage +from blitz.ui.pages.diagram import MermaidPage +from blitz.ui.pages.gpt_builder import AskGPTPage +from blitz.ui.pages.log import LogPage +from blitz.ui.pages.projects import HomePage +from blitz.ui.pages.swagger import SwaggerPage +from pathlib import Path +from nicegui import ui + +from nicegui import ui +from pydantic import BaseModel +from nicegui import app, ui + +from blitz.ui.components.header import FrameComponent, HeaderComponent + + +from fastapi import Depends, FastAPI, Request + +from nicegui import app, ui + +if TYPE_CHECKING: + from blitz.api.blitz_api import BlitzAPI + + +async def _post_dark_mode(request: Request) -> None: + print("dark mode") + app.storage.browser["dark_mode"] = (await request.json()).get("value") + + +@ui.page("/projects/{uuid}", title="Dashboard") +def dashboard_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + DashboardPage().render_page() + FrameComponent().render() + + +@ui.page("/projects/{uuid}/diagram", title="Diagram") +def diagram_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + MermaidPage().render_page() + FrameComponent().render() + + +@ui.page("/projects/{uuid}/blitz-file", title="Blitz File") +def blitz_file_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + BlitzFilePage().render_page() + FrameComponent().render() + + +@ui.page("/projects/{uuid}/swagger", title="Swagger") +def swagger_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + SwaggerPage().render_page() + FrameComponent().render() + + +@ui.page("/projects/{uuid}/logs") +def log_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + ui.page_title("Logs") + LogPage().render_page() + FrameComponent().render() + + +# @ui.page("/projects/{uuid}/admin") +# def log_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: +# ui.page_title("Admin") +# AdminPage().render_page() +# FrameComponent(drawer_open=False).render() + + +@ui.page("/gpt") +def ask_gpt_page(blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: + ui.page_title("GPT Builder") + AskGPTPage().render_page() + FrameComponent(show_drawer=False).render() + + +# @ui.page("/projects") +# def projects_page(blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None: +# ui.page_title("Projects") +# HomePage().render_page() +# FrameComponent(show_drawer=False).render() + + +def init_ui( + blitz_api: "BlitzAPI", + mount_path: str = "/dashboard", + storage_secret: str = "secret", + title: str = "Dashboard", +) -> None: + logging.getLogger("niceGUI").setLevel(logging.WARNING) + blitz_ui = get_blitz_ui() + blitz_ui.current_app = blitz_api.blitz_app + ui.run_with( + app=blitz_api, + title=title, + dark=True, + mount_path=mount_path, + storage_secret=storage_secret, + favicon=Path(__file__).parent / "./assets/favicon.ico", + ) diff --git a/blitz/ui/pages/__init__.py b/blitz/ui/pages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/blitz/ui/pages/admin.py b/blitz/ui/pages/admin.py new file mode 100644 index 0000000..25dfb7b --- /dev/null +++ b/blitz/ui/pages/admin.py @@ -0,0 +1,33 @@ +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from nicegui import ui + + +class AdminPage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + + def resize_iframe(self): + ui.run_javascript( + """ + var iframe = document.querySelector('iframe'); + var resizeIframe = function() { + iframe.style.height = iframe.contentWindow.document.body.scrollHeight + 'px'; + }; + var navList = iframe.getElementById('navList'); + if (navList) { + console.log('hello') + var lastNavItem = navList.lastElementChild; + if (lastNavItem) { + lastNavItem.style.pointerEvents = 'none'; + lastNavItem.style.color = 'gray'; + } + } + }; + """ + ) + + def render_page(self): + self.resize_iframe() + ui.element("iframe").props( + f"src={self.blitz_ui.localhost_url}/admin/ frameborder=0 onload=resizeIframe()" + ).classes("w-full rounded-sm bg-white h-screen overflow-hidden") diff --git a/blitz/ui/pages/blitz_file.py b/blitz/ui/pages/blitz_file.py new file mode 100644 index 0000000..9bb80fd --- /dev/null +++ b/blitz/ui/pages/blitz_file.py @@ -0,0 +1,12 @@ +from nicegui import ui +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from blitz.ui.components.json_editor import BlitzFileEditorComponent + + +class BlitzFilePage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui(), project: str = None) -> None: + self.blitz_ui = blitz_ui + self.blitz_app = blitz_ui.current_app + + def render_page(self): + BlitzFileEditorComponent(self.blitz_app.file.raw_file).render() diff --git a/blitz/ui/pages/dashboard.py b/blitz/ui/pages/dashboard.py new file mode 100644 index 0000000..2d4897a --- /dev/null +++ b/blitz/ui/pages/dashboard.py @@ -0,0 +1,55 @@ +from nicegui import ui + +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +import uuid +from httpx import AsyncClient + +from blitz.ui.components.logger import LogComponent +from blitz.ui.components.status import StatusComponent + +class ProjectDetailComponent: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + self.app = self.blitz_ui.current_app + + def render(self) -> None: + with ui.row().classes("w-full justify-between items-center"): + ui.label(f"{self.app.file.config.name}").classes( + "text-xl font-bold" + ) + ui.label(f"Version: {self.app.file.config.version}").classes( + "font-bold text-sm" + ) + ui.separator() + ui.label(f"Project Path: {self.app.path}").classes("text-sm") + ui.label( + f"Description: {self.app.file.config.description}" + ).classes("text-sm font-normal") + +class DashboardPage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + self.app = self.blitz_ui.current_app + self.columns, self.rows = self.blitz_ui.get_ressources() + + def render_page(self) -> None: + with ui.element("div").classes("w-full h-full flex flex-row justify-center"): + with ui.column().classes("w-2/3 h-full border rounded-lg border-gray-300"): + with ui.expansion("Project", value=True, icon="info").classes( + "w-full text-bold text-2xl " + ): + ProjectDetailComponent().render() + with ui.expansion("Models", value=True, icon="help_outline").classes( + "w-full text-bold text-2xl" + ): + ui.table( + columns=self.columns, rows=self.rows, row_key="name" + ).classes("w-full no-shadow") + with ui.expansion( + "Status", value=True, icon="health_and_safety" + ).classes("w-full text-bold text-2xl"): + StatusComponent().render() + with ui.expansion("Logs", value=False, icon="list").classes( + "w-full text-bold text-2xl" + ): + LogComponent().render() diff --git a/blitz/ui/pages/diagram.py b/blitz/ui/pages/diagram.py new file mode 100644 index 0000000..f7ba29e --- /dev/null +++ b/blitz/ui/pages/diagram.py @@ -0,0 +1,46 @@ +from nicegui import ui +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui + + +class MermaidPage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui(), project: str = None) -> None: + self.project = project + self.blitz_ui = blitz_ui + self._width = 100 + + def remove_style(self): + ui.run_javascript( + """ + var svg = document.querySelector('svg'); + svg.removeAttribute("style"); + """ + ) + + def zoom_svg(self): + self._width += 50 + self.remove_style() + ui.run_javascript( + f""" + var svg = document.querySelector('svg'); + svg.setAttribute("width", "{self._width}%"); + """ + ) + + def unzoom_svg(self): + self._width -= 50 + if self._width < 100: + self._width = 100 + self.remove_style() + ui.run_javascript( + f""" + var svg = document.querySelector('svg'); + svg.setAttribute("width", "{self._width}%"); + """ + ) + + def render_page(self): + with ui.scroll_area().classes("w-full h-screen justify-center content-center"): + ui.mermaid(self.blitz_ui.erd) + with ui.footer().classes("w-full justify-start "): + ui.button(icon="zoom_in", on_click=self.zoom_svg).classes("borderrounded-sm").props("flat") + ui.button(icon="zoom_out", on_click=self.unzoom_svg).classes("border rounded-sm").props("flat") diff --git a/blitz/ui/pages/gpt_builder.py b/blitz/ui/pages/gpt_builder.py new file mode 100644 index 0000000..db8af97 --- /dev/null +++ b/blitz/ui/pages/gpt_builder.py @@ -0,0 +1,444 @@ +from functools import lru_cache +from typing import AsyncGenerator, Callable + +from nicegui import ui, app +from nicegui.events import KeyEventArguments +from openai import APIConnectionError, AsyncOpenAI, AuthenticationError + +from blitz.settings import get_settings +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from blitz.ui.components.gpt_chat_components import ( + GPTChatComponent, + GPTResponse, + UserQuestion, +) + +DEV_TEXT = """Sure! Here is a sample blitz_file with randomly generated models and fields: + +```json +{ + "config": { + "name": "Random App", + "description": "A randomly generated Blitz app", + "version": "1.0.0" + }, + "models": [ + { + "name": "User", + "fields": { + "name": "str", + "age": "int", + "email": "str", + "address": "str" + } + }, + { + "name": "Product", + "fields": { + "name": "str", + "description": "str", + "price": "float", + "quantity": "int" + } + }, + { + "name": "Order", + "fields": { + "user_id": "User.id", + "product_id": "Product.id", + "quantity": "int", + "total_price": "float" + } + } + ] +} +``` + +Please note that this blitz_file is randomly generated and may not have any specific meaning or logic.""" + + +class GPTClient: + def __init__( + self, api_key: str, model: str = "gpt-3.5-turbo", pre_prompt: str | None = None + ) -> None: + self.model = model + self._api_key = api_key + self.pre_prompt = pre_prompt + self.client = self._get_client(api_key=api_key) if api_key else None + + @staticmethod + def _get_client(api_key: str): + return AsyncOpenAI(api_key=api_key) + + def _add_preprompt(self, messages: list[dict[str, str]]): + messages.insert( + 0, + { + "role": "system", + "name": "BlitzUI", + "content": self.pre_prompt, + }, + ) + return messages + + def refresh_client(self, api_key: str) -> None: + self._api_key = api_key + self.client = self._get_client(api_key=api_key) + + async def stream(self, messages: list[dict[str, str]]) -> AsyncGenerator[str, None]: + if self.pre_prompt: + messages = self._add_preprompt(messages) + return await self.client.chat.completions.create( + model=self.model, + messages=messages, + stream=True, + ) + + async def list_models(self): + return await self.client.models.list() + + +@lru_cache +def get_gpt_client() -> GPTClient: + return GPTClient(api_key=get_settings().BLITZ_OPENAI_API_KEY) + + +class AskGPTPage: + def __init__( + self, + gpt_client: GPTClient = get_gpt_client(), + blitz_ui: BlitzUI = get_blitz_ui(), + ) -> None: + self.gpt_client = gpt_client + self.gpt_client.pre_prompt = blitz_ui.preprompt + + self.blitz_ui = blitz_ui + self._gpt_client_error = False + self.gpt_request: str = "" + + if messages := app.storage.user.get("gpt_messages", []): + self.gpt_messages: list[GPTChatComponent] = [ + ( + UserQuestion.from_gpt_dict(message) + if message["role"] == "user" + else GPTResponse.from_gpt_dict(message) + ) + for message in messages + ] + else: + self.gpt_messages: list[GPTChatComponent] = [] + + # Theses variables are the result of `ui.state(False)` defined in the chat_area method + # because it need to be in a ui.refreshable component + self.thinking: bool + self.set_thinking: Callable[[bool], None] + + # Here because otherwise when the ui refresh the scroll is reset to top (???) + self._scroll_area = ui.scroll_area().classes("flex-grow") + + # Only declarative + self.settings_dialog = None + + @property + def can_send_request(self) -> bool: + return self.gpt_request != "" or self.thinking is True + + @property + def gpt_client_is_valid(self) -> bool: + return self.gpt_client.client is not None and self._gpt_client_error is False + + @property + def gpt_client_error(self): + return self._gpt_client_error + + def render_page(self): + # Allow the full size of the scrollable zone + ui.query(".q-page").classes("flex") + ui.query(".nicegui-content").classes("w-full") + + # Allow the usage of cmd + enter to send the request + ui.keyboard(on_key=self.handle_key, ignore=[]) + + self.settings_dialog = ChatSettings(self.gpt_client) + self.settings_dialog.render() + self.delete_conversation() + + # All the components of the chat + self.chat_area() + + # The footer with the input and the send button + self.footer() + + def refresh_dialog(self, api_key_input: str): + self.gpt_client.refresh_client(api_key=api_key_input) + self.gpt_client_error = False + self.dialog.refresh() + + def footer(self): + with ui.footer().classes("items-center space-y-0 pt-0 justify-center px-5"): + with ui.grid(columns=10).classes("w-full items-center gap-5"): + with ui.button(on_click=self.delete_conversation_dialog.open).props( + "flat size=sm" + ).classes("justify-self-start"): + ui.icon("delete_outline", color="grey-8", size="md").props( + "fab-mini" + ) + with ui.button(on_click=self.open_settings).props("flat").classes( + "justify-self-end" + ): + ui.icon("settings", color="grey-6", size="md").props("fab-mini") + + with ui.row(wrap=False).classes( + "w-full items-center rounded-lg pl-2 border-solid border col-start-3 col-span-6" + ): + ui.textarea(on_change=lambda: self.ask_button.refresh()).props( + "borderless autogrow standout clearable dense" + ).classes("flex-grow w-auto ").bind_value(self, "gpt_request") + self.ask_button() + ui.space().classes("col-span-2") + + ui.label( + "ChatGPT can make mistakes. Consider checking important information." + ).classes("text-xs text-gray-500 w-full text-center") + + def delete_conversation(self): + with ui.dialog() as self.delete_conversation_dialog, ui.card().classes( + "no-shadow" + ): + ui.label("Are you sure you want to delete this conversation?") + with ui.row().classes("w-full items-center"): + ui.button( + "Cancel", on_click=self.delete_conversation_dialog.close + ).props("flat") + ui.button("Delete", on_click=self._handle_delete_conversation).props( + "flat" + ) + + def _handle_delete_conversation(self): + self.remove_conversation() + self.delete_conversation_dialog.close() + + def open_settings(self): + self.settings_dialog.refresh() + self.settings_dialog.open() + + def remove_conversation(self): + self.gpt_messages = [] + app.storage.user["gpt_messages"] = [] + self.chat_area.refresh() + + @ui.refreshable + def chat_area(self): + self.thinking, self.set_thinking = ui.state(False) + + # Here because otherwise when the ui refresh the scroll is reset to top (???) + # Same as comment in __init__, we need to clean the scroll_area otherwise all the message are duplicated + self._scroll_area.clear() + + with self._scroll_area: + for message in self.gpt_messages: + message.render() + + @ui.refreshable + def ask_button(self): + ask_button = ( + ui.button(on_click=self.ask_button_trigger) + .props("flat") + .bind_enabled_from(self, "can_send_request") + ) + + with ask_button: + if not self.thinking: + ui.icon("send", color="#a72bff").props("fab-mini") + else: + ui.icon("stop_circle", color="#a72bff").props("fab-mini") + + async def handle_key(self, e: KeyEventArguments): + if e.modifiers.meta and e.key.enter and self.can_send_request: + await self.ask_button_trigger() + + async def ask_button_trigger(self): + self.set_thinking(not self.thinking) + if self.thinking: + self.gpt_messages.append(UserQuestion(self.gpt_request)) + self.chat_area.refresh() + try: + await self._handle_ask_event() + except AuthenticationError: + self.gpt_client_error = True + + self.set_thinking(False) + else: + self.gpt_request = "" + + app.storage.user["gpt_messages"] = [ + message.to_dict() for message in self.gpt_messages + ] + self.ask_button.refresh() + + async def _handle_ask_event(self): + gpt_response = GPTResponse() + self.gpt_messages.append(gpt_response) + + self.chat_area.refresh() + self.gpt_request = "" + + async for i in self.ask_gpt(): + gpt_response.add(i) + self._scroll_area.scroll_to(percent=100) + gpt_response.text_is_finished = True + + async def ask_gpt(self): + messages = [ + { + "role": "system", + "name": "BlitzUI", + "content": self.blitz_ui.preprompt, + } + ] + messages.extend([message.as_gpt_dict() for message in self.gpt_messages]) + + stream = await self.gpt_client.stream(messages=messages) + + async for chunk in stream: + if self.thinking is False: + break + if chunk.choices[0].delta.content is not None: + yield chunk.choices[0].delta.content + + +class ChatSettings: + def __init__( + self, gpt_client: GPTClient, blitz_ui: BlitzUI = get_blitz_ui() + ) -> None: + self.gpt_client = gpt_client + self.dialog = ui.dialog().props( + "maximized transition-show=slide-up transition-hide=slide-down" + ) + self.blitz_ui = blitz_ui + self.quit_dialog = ui.dialog(value=False) + + @ui.refreshable + def render(self): + """Render the settings dialog""" + with self.dialog, ui.card().classes("w-full px-4"): + self.quit_modal() + self.header() + ui.label("OpenAI").classes("text-xl font-bold") + self.openai_settings() + ui.label("Pre Prompt").classes("text-xl font-bold") + self.pre_prompt_editor() + + def api_key_input_component(self): + """Create the api key input component""" + self.api_key_input = ( + ui.input( + "OpenAI API Key", + value=self.gpt_client._api_key, + placeholder="sk-...", + password=True, + password_toggle_button=True, + ) + .props("borderless standout dense") + .classes("grow rounded-lg px-2 border-solid border") + ) + + def header(self): + """Render the header of the settings dialog""" + with ui.row().classes("w-full items-center justify-center"): + ui.button(icon="close", on_click=self.close).props("flat") + ui.label("Chat Settings").classes("text-2xl font-bold grow text-center") + ui.button("Save", icon="save", on_click=self.save).classes( + "text-color-black" + ).props("flat").bind_enabled_from(self, "settings_has_changed") + + @ui.refreshable + def openai_settings(self): + """Render the openai settings""" + with ui.row().classes("w-full items-center"): + self.model_select = ( + ui.select( + {"gpt-3.5-turbo": "3.5 Turbo", "gpt-4": "4"}, + label="Model", + value=self.gpt_client.model, + ) + .props("borderless standout dense") + .classes("w-32 rounded-lg px-2 border-solid border") + ) + self.api_key_input_component() + ui.button("Check API KEY", on_click=self.validate_api_key).props("outline") + ui.space() + + @ui.refreshable + def pre_prompt_editor(self): + with ui.row().classes("w-full items-center"): + ui.button("Reset Pre-Prompt", on_click=self.reset_preprompt).props( + "outline" + ) + switch = ui.switch("Edit Pre-Prompt", value=False) + self.preprompt = ( + ui.textarea(label="Pre-Prompt", value=self.blitz_ui.preprompt) + .classes("w-full rounded-lg px-2 border-solid border") + .props("borderless autogrow") + .bind_enabled_from(switch, "value") + ) + + def close(self): + self.dialog.close() + + def open(self): + self.dialog.open() + + @property + def settings_has_changed(self): + return ( + self.gpt_client.model != self.model_select.value + or self.blitz_ui.preprompt != self.preprompt.value + or self.gpt_client._api_key != self.api_key_input.value + ) + + def refresh(self): + self.openai_settings.refresh() + self.pre_prompt_editor.refresh() + + def reset_preprompt(self): + self.blitz_ui.reset_preprompt() + self.pre_prompt_editor.refresh() + + def quit_modal(self): + with self.quit_dialog, ui.card(): + with ui.row().classes("w-full items-center"): + ui.button(icon="close", on_click=self.quit_dialog.close).props("flat") + ui.label("Some changes wasn't saved.").classes("font-bold") + with ui.row().classes("w-full items-center"): + ui.button("Discard changes", on_click=self.quit).props("flat") + ui.button("Save", on_click=self.save).props("flat") + + def close(self): + if self.settings_has_changed: + self.quit_dialog.open() + else: + self.quit() + + def quit(self): + if self.quit_dialog.value: + self.quit_dialog.close() + self.dialog.close() + + def save(self): + if self.quit_dialog.value: + self.quit_dialog.close() + + self.gpt_client.model = self.model_select.value + self.blitz_ui.preprompt = self.preprompt.value + self.gpt_client.refresh_client(api_key=self.api_key_input.value) + ui.notify("Settings saved", type="positive") + self.dialog.close() + + async def validate_api_key(self): + try: + gpt_client = GPTClient(api_key=self.api_key_input.value) + await gpt_client.list_models() + ui.notify("Valid API Key", type="positive") + except (AuthenticationError, APIConnectionError): + ui.notify("Invalid API Key", type="warning") diff --git a/blitz/ui/pages/log.py b/blitz/ui/pages/log.py new file mode 100644 index 0000000..f126227 --- /dev/null +++ b/blitz/ui/pages/log.py @@ -0,0 +1,10 @@ +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from blitz.ui.components.logger import LogComponent + + +class LogPage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + + def render_page(self) -> None: + LogComponent().render() diff --git a/blitz/ui/pages/projects.py b/blitz/ui/pages/projects.py new file mode 100644 index 0000000..198299d --- /dev/null +++ b/blitz/ui/pages/projects.py @@ -0,0 +1,61 @@ +from nicegui import ui + +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui + + +class ProjectDetail: + def __init__( + self, + app_name: str, + project_name: str = "", + date: str = "", + description: str = "", + version: str = "", + ) -> None: + self.app_name=app_name + self.project_name = project_name + self.date = date + self.description = description + self.version = version + + + def render(self): + with ui.link(target=f"/projects/{self.app_name}").classes("w-full hover:bg-slate-700 rounded-sm"), ui.grid( + columns=20 + ).classes("w-full my-2"): + ui.label(self.app_name).classes("col-span-2 pl-2") + ui.label(self.project_name).classes("col-span-2 pl-2") + ui.label(self.date).classes("col-span-4") + ui.label(self.description).classes("col-span-11") + ui.label(self.version).classes("col-span-1") + + +class HomePage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None: + self.blitz_ui = blitz_ui + + def render_page(self): + with ui.element("div").classes( + "w-full justify-center items-center content-center p-10" + ): + with ui.card().classes("no-shadow border align-center"): + with ui.row().classes("w-full justify-between items-center"): + ui.label("Blitz Projects").classes("text-2xl") + with ui.button("New").props("disabled").props("flat"): + ui.tooltip( + "This feature is not developed yet. Create a new project with the CLI." + ) + ui.input(label="Search for project").props( + "borderless standout dense" + ).classes(" rounded-lg px-2 border-solid border w-full my-5") + with ui.grid(columns=20).classes("w-full"): + ui.label("App").classes("col-span-2 pl-2") + ui.label("Name").classes("col-span-2 pl-2") + ui.label("Last modified").classes("col-span-4") + ui.label("Description").classes("col-span-11") + ui.label("Version").classes("col-span-1") + + ui.separator() + + for app in self.blitz_ui.apps: + ProjectDetail(app_name=app.name, project_name=app.file.config.name, description=app.file.config.description,version=app.file.config.version).render() diff --git a/blitz/ui/pages/swagger.py b/blitz/ui/pages/swagger.py new file mode 100644 index 0000000..0b3f825 --- /dev/null +++ b/blitz/ui/pages/swagger.py @@ -0,0 +1,26 @@ +import pathlib +from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui +from nicegui import ui +from pathlib import Path + + +class SwaggerPage: + def __init__(self, blitz_ui: BlitzUI = get_blitz_ui(), project: str = None) -> None: + self.blitz_ui = blitz_ui + + def resize_iframe(self): + ui.run_javascript( + """ + var iframe = document.querySelector('iframe'); + var resizeIframe = function() { + iframe.style.height = iframe.contentWindow.document.body.scrollHeight + 'px'; + }; + + """) + + def render_page(self): + self.resize_iframe() + + ui.element("iframe").props( + f"src={self.blitz_ui.localhost_url}/api/docs frameborder=0 onload=resizeIframe()" + ).classes("w-full rounded-sm bg-white h-screen overflow-hidden") diff --git a/blitz/ui/preprompt.txt b/blitz/ui/preprompt.txt new file mode 100644 index 0000000..bf3f759 --- /dev/null +++ b/blitz/ui/preprompt.txt @@ -0,0 +1,49 @@ +You are an assistant to create json files. These json are used to create a blitz app which is a CRUD API. +For exemple this is a valid blitz_file: +{ + "config": { + "name": "Game Chess", + "description": "Player and Game to represent a game of chess.", + "version": "0.1.0" + }, + "models": [ + { + "name": "Test", + "fields": { + "name": "str", + "age": "int" + } + }, + { + "name": "Player", + "fields": { + "name": "str" + } + }, + { + "name": "Game", + "fields": { + "player_id": "Player.id", + "player": "Player" + } + }, + { + "name": "Resource", + "fields": { + "name": "str", + "game_id": "Game.id", + "game": "Game" + } + }, + { + "name": "Item", + "fields": { + "name": "str", + "resource_id": "Resource.id", + "player_id": "Player.id" + } + } + ] +} + +You MUST ALWAYS answer in markdown. \ No newline at end of file diff --git a/blitz/ui/static/jse_theme_dark.css b/blitz/ui/static/jse_theme_dark.css new file mode 100644 index 0000000..b48bca9 --- /dev/null +++ b/blitz/ui/static/jse_theme_dark.css @@ -0,0 +1,115 @@ +.jse-theme-dark { + --jse-theme: dark; + + /* over all fonts, sizes, and colors */ + --jse-theme-color: #2f6dd0; + --jse-theme-color-highlight: #467cd2; + --jse-background-color: #1e2129; + --jse-text-color: #d4d4d4; + --jse-text-color-inverse: #4d4d4d; + + /* main, menu, modal */ + --jse-main-border: 1px solid grey; + --jse-menu-color: #fff; + --jse-modal-background: #2f2f2f; + --jse-modal-overlay-background: rgba(0, 0, 0, 0.5); + --jse-modal-code-background: #2f2f2f; + + /* tooltip in text mode */ + --jse-tooltip-color: var(--jse-text-color); + --jse-tooltip-background: #4b4b4b; + --jse-tooltip-border: 1px solid #737373; + --jse-tooltip-action-button-color: inherit; + --jse-tooltip-action-button-background: #737373; + + /* panels: navigation bar, gutter, search box */ + --jse-panel-background: #333333; + --jse-panel-background-border: 1px solid #464646; + --jse-panel-color: var(--jse-text-color); + --jse-panel-color-readonly: #737373; + --jse-panel-border: 1px solid #3c3c3c; + --jse-panel-button-color-highlight: #e5e5e5; + --jse-panel-button-background-highlight: #464646; + + /* navigation-bar */ + --jse-navigation-bar-background: #656565; + --jse-navigation-bar-background-highlight: #7e7e7e; + --jse-navigation-bar-dropdown-color: var(--jse-text-color); + + /* context menu */ + --jse-context-menu-background: #4b4b4b; + --jse-context-menu-background-highlight: #595959; + --jse-context-menu-separator-color: #595959; + --jse-context-menu-color: var(--jse-text-color); + --jse-context-menu-pointer-background: #737373; + --jse-context-menu-pointer-background-highlight: #818181; + --jse-context-menu-pointer-color: var(--jse-context-menu-color); + + /* contents: json key and values */ + --jse-key-color: #9cdcfe; + --jse-value-color: var(--jse-text-color); + --jse-value-color-number: #b5cea8; + --jse-value-color-boolean: #569cd6; + --jse-value-color-null: #569cd6; + --jse-value-color-string: #ce9178; + --jse-value-color-url: #ce9178; + --jse-delimiter-color: #949494; + --jse-edit-outline: 2px solid var(--jse-text-color); + + /* contents: selected or hovered */ + --jse-selection-background-color: #464646; + --jse-selection-background-inactive-color: #333333; + --jse-hover-background-color: #343434; + --jse-active-line-background-color: rgba(255, 255, 255, 0.06); + --jse-search-match-background-color: #343434; + + /* contents: section of collapsed items in an array */ + --jse-collapsed-items-background-color: #333333; + --jse-collapsed-items-selected-background-color: #565656; + --jse-collapsed-items-link-color: #b2b2b2; + --jse-collapsed-items-link-color-highlight: #ec8477; + + /* contents: highlighting of search results */ + --jse-search-match-color: #724c27; + --jse-search-match-outline: 1px solid #966535; + --jse-search-match-active-color: #9f6c39; + --jse-search-match-active-outline: 1px solid #bb7f43; + + /* contents: inline tags inside the JSON document */ + --jse-tag-background: #444444; + --jse-tag-color: #bdbdbd; + + /* contents: table */ + --jse-table-header-background: #333333; + --jse-table-header-background-highlight: #424242; + --jse-table-row-odd-background: rgba(255, 255, 255, 0.1); + + /* controls in modals: inputs, buttons, and `a` */ + --jse-input-background: #3d3d3d; + --jse-input-border: var(--jse-main-border); + --jse-button-background: #808080; + --jse-button-background-highlight: #7a7a7a; + --jse-button-color: #e0e0e0; + --jse-button-secondary-background: #494949; + --jse-button-secondary-background-highlight: #5d5d5d; + --jse-button-secondary-background-disabled: #9d9d9d; + --jse-button-secondary-color: var(--jse-text-color); + --jse-a-color: #55abff; + --jse-a-color-highlight: #4387c9; + + /* svelte-select */ + --jse-svelte-select-background: #3d3d3d; + --jse-svelte-select-border: 1px solid #4f4f4f; + --list-background: #3d3d3d; + --item-hover-bg: #505050; + --multi-item-bg: #5b5b5b; + --input-color: #d4d4d4; + --multi-clear-bg: #8a8a8a; + --multi-item-clear-icon-color: #d4d4d4; + --multi-item-outline: 1px solid #696969; + --list-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.4); + + /* color picker */ + --jse-color-picker-background: #656565; + --jse-color-picker-border-box-shadow: #8c8c8c 0 0 0 1px; + } \ No newline at end of file diff --git a/blitz/ui/static/style.css b/blitz/ui/static/style.css new file mode 100644 index 0000000..bcc10b7 --- /dev/null +++ b/blitz/ui/static/style.css @@ -0,0 +1,29 @@ +html, +body { + max-width: 100%; + overflow-x: hidden; + background-color: #fefefe; + font-family: "Fira Sans", Roboto, -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif; + --q-dark-page: #1e2129; + } + +html:has(.body--dark) { + background-color: #1e2129; +} + +.body--dark .q-header { + background-color: #14151a; + } + +a:link:not(.browser-window *), +a:visited:not(.browser-window *) { + color: inherit !important; + text-decoration: none; +} + +.q-card { + background-color: #f8f8f8; +} +.q-card--dark { + background-color: #1e2129; +} \ No newline at end of file diff --git a/custom_templates/pydantic_v2/BaseModel.jinja2 b/custom_templates/pydantic_v2/BaseModel.jinja2 new file mode 100644 index 0000000..bf7357d --- /dev/null +++ b/custom_templates/pydantic_v2/BaseModel.jinja2 @@ -0,0 +1,39 @@ +{% for decorator in decorators -%} +{{ decorator }} +{% endfor -%} +class {{ class_name }}({{ base_class }}, table=True):{% if comment is defined %} # {{ comment }}{% endif %} +{%- if description %} + """ + {{ description | indent(4) }} + """ +{%- endif %} +{%- if not fields and not description %} + pass +{%- endif %} +{%- if config %} +{%- filter indent(4) %} +{% include 'ConfigDict.jinja2' %} +{%- endfilter %} +{%- endif %} +{%- for field in fields -%} + {%- if not field.annotated and field.field %} + {{ field.name }}: {{ field.type_hint }} = {{ field.field }} + {%- else %} + {%- if field.annotated %} + {{ field.name }}: {{ field.annotated }} + {%- else %} + {{ field.name }}: {{ field.type_hint }} + {%- endif %} + {%- if (not field.required or field.data_type.is_optional or field.nullable) and not field.annotated + %} = {{ field.represented_default }} + {%- endif -%} + {%- endif %} + {%- if field.docstring %} + """ + {{ field.docstring | indent(4) }} + """ + {%- endif %} +{%- for method in methods -%} + {{ method }} +{%- endfor -%} +{%- endfor -%} \ No newline at end of file diff --git a/custom_templates/pydantic_v2/RootModel.jinja2 b/custom_templates/pydantic_v2/RootModel.jinja2 new file mode 100644 index 0000000..5b5a9f2 --- /dev/null +++ b/custom_templates/pydantic_v2/RootModel.jinja2 @@ -0,0 +1,44 @@ +{%- macro get_type_hint(_fields) -%} +{%- if _fields -%} +{#There will only ever be a single field for RootModel#} +{{- _fields[0].type_hint}} +{%- endif -%} +{%- endmacro -%} + +{% for decorator in decorators -%} +{{ decorator }} +{% endfor -%} + +class {{ class_name }}({{ base_class }}[{{get_type_hint(fields)}}]):{% if comment is defined %} # {{ comment }}{% endif %} +{%- if description %} + """ + {{ description | indent(4) }} + """ +{%- endif %} +{%- if config %} +{%- filter indent(4) %} +{% include 'ConfigDict.jinja2' %} +{%- endfilter %} +{%- endif %} +{%- if not fields and not description %} + pass +{%- else %} + {%- set field = fields[0] %} + {%- if not field.annotated and field.field %} + root: {{ field.type_hint }} = {{ field.field }} + {%- else %} + {%- if field.annotated %} + root: {{ field.annotated }} + {%- else %} + root: {{ field.type_hint }} + {%- endif %} + {%- if not (field.required or (field.represented_default == 'None' and field.strip_default_none)) + %} = {{ field.represented_default }} + {%- endif -%} + {%- endif %} + {%- if field.docstring %} + """ + {{ field.docstring | indent(4) }} + """ + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/custom_templates/root.jinja2 b/custom_templates/root.jinja2 new file mode 100644 index 0000000..847a823 --- /dev/null +++ b/custom_templates/root.jinja2 @@ -0,0 +1,6 @@ +{%- set field = fields[0] %} +{%- if field.annotated %} +{{ class_name }} = {{ field.annotated }} +{%- else %} +{{ class_name }} = {{ field.type_hint }} +{%- endif %} diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000..a1e865a --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,2 @@ +!!! warning + **WORK IN PROGRESS** \ No newline at end of file diff --git a/docs/blitzfile/config.md b/docs/blitzfile/config.md new file mode 100644 index 0000000..5a4e39d --- /dev/null +++ b/docs/blitzfile/config.md @@ -0,0 +1,32 @@ + +The config section contains the general informations about your Blitz app. It is built as below: + +=== "Yaml" + + ```yaml + config: + name: Hello world # (1)! + description: Here is a simple blitz configuration file. # (2)! + version: 0.1.0 # (3)! + ``` + + 1. The name of your Blitz app. + 2. A short description of your Blitz app. + 3. The version of your Blitz app. + + +=== "Json" + + ```json + "config": { + "name": "Hello world", // (1)! + "description": "Here is a simple blitz configuration file.", // (2)! + "version": "0.1.0" // (3)! + } + ``` + + 1. The name of your Blitz app. + 2. A short description of your Blitz app. + 3. The version of your Blitz app. + + diff --git a/docs/blitzfile/index.md b/docs/blitzfile/index.md new file mode 100644 index 0000000..7457883 --- /dev/null +++ b/docs/blitzfile/index.md @@ -0,0 +1,181 @@ + +!!! warning + + **Please, keep in mind that the Blitz is still in development and may change in the future. We are open to suggestions and contributions.** + +The Blitz file is the configuration file used by Blitz to generate the API. It is a simple YAML or JSON file that contains the general configuration of the API and the database models. + +> We are building the Blitz File in a way that it is easy to read and understand with every feature needed to build a complete basic API. + +## Blitz File Structure + +The Blitz file is composed of two main sections: [`config`](#config) and [`resources`](#resources). + +### Config + +The config section contains the general configuration of the API. It is built as below: + +=== "Yaml" + + ```yaml + config: + name: Hello world + description: Here is a simple blitz configuration file. + version: 0.1.0 + ``` + +=== "Json" + + ```json + "config": { + "name": "Hello world", + "description": "Here is a simple blitz configuration file.", + "version": "0.1.0" + } + ``` + +> *Pretty easy right ?* + +### Resources + +The `resources` section contains the structure of the data you want to manipulate in your Blitz app. It's a bit more complex than the config section but still easy to understand. + +!!! note + + We are not talking about `database` or `models` here because Blitz is an abstraction of your data model and things that are represented in your Blitz file as a `resource` may be represented differently in your database. + +The resources section is built as below: + +=== "Yaml" + + ```yaml + models: + - name: TodoList + fields: + - name: Todo + fields: + ``` + +=== "Json" + + ```json + "models": [ + { + "name": "TodoList", + "fields": {} + }, + { + "name": "Todo", + "fields": {} + } + ] + ``` + +Each model is constructed with a `name` and a `fields` section. The `name` is the name of the model and the `fields` section contains the fields of the model. + +> *Still pretty easy right ?* + +___ + +#### Fields + +A field can be constructed in 2 way, the **explicit** way and the **shortcut** way. + +You can use both way in the same Blitz file because as the name says, the shortcut way is just a shortcut to the explicit way. + +Here is an example of a working Blitz file: + +=== "Yaml" + + ```yaml + models: + - name: TodoList + fields: + owner!: str + description: str + - name: Todo + fields: + due_date: str + todo_list_id: TodoList.id + ``` + +=== "Json" + + ```json + "models": [ + { + "name": "TodoList", + "fields": { + "owner!": "str", + "description": "str" + } + }, + { + "name": "Todo", + "fields": { + "due_date": "str", + "todo_list_id": "TodoList.id" + } + } + ] + ``` + +=== "Yaml (explicit)" + + ```yaml + models: + - name: TodoList + fields: + owner: + type: str + unique: true + description: + type: str + - name: Todo + fields: + due_date: + type: str + todo_list_id: + type: uuid + relationship: TodoList.id + ``` + +=== "Json (explicit)" + + ```json + "models": [ + { + "name": "TodoList", + "fields": { + "owner": { + "type": "str", + "unique": true + }, + "description": { + "type": "str" + } + } + }, + { + "name": "Todo", + "fields": { + "due_date": { + "type": "str" + }, + "todo_list_id": { + "type": "uuid", + "relationship": "TodoList.id" + } + } + } + ] + ``` + + +> *You can try it in the [Blitz Playground](#)* ! + +!!! note + + We will maintain the 4 ways of writing fields in the Blitz file because we think that the explicit way is more readable and the shortcut way is more convenient. We are also about to implement in the Blitz dashboard a way to switch between the 4 ways really easily. + +Every field is constructed at least with a `name` and a `type`. \ No newline at end of file diff --git a/docs/blitzfile/reference.md b/docs/blitzfile/reference.md new file mode 100644 index 0000000..a1e865a --- /dev/null +++ b/docs/blitzfile/reference.md @@ -0,0 +1,2 @@ +!!! warning + **WORK IN PROGRESS** \ No newline at end of file diff --git a/docs/blitzfile/relationship.md b/docs/blitzfile/relationship.md new file mode 100644 index 0000000..96c0677 --- /dev/null +++ b/docs/blitzfile/relationship.md @@ -0,0 +1,249 @@ +## Relationship +Currently supported relationships are: +- One-to-many +- One-to-one + +### One-to-Many +> A **Player** has many **Item**s. + +In the following example, a **player has many items** +=== "Yaml" + ```yaml + - name: Player + fields: + name: str + items: Item[] + - name: Item + fields: + name: str + player_id: Player.id + player: Player + ``` + +=== "Json" + ```json + [ + { + "name": "Player", + "fields": { + "name": "str", + "items": "Item[]" + } + }, + { + "name": "Item", + "fields": { + "name": "str", + "player_id": "Player.id", + "player": "Player" + } + } + ] + ``` + +=== "Yaml (explicit)" + ```yaml + - name: Player + fields: + name: + type: str + items: + type: relationship + relationship: Item + relationship_list: true + - name: Item + fields: + name: + type: str + player_id: + type: foreign_key + foreign_key: Player.id + player: + type: relationship + relationship: Player + ``` + +=== "Json (explicit)" + ```json + [ + { + "name": "Player", + "fields": { + "name": { + "type": "str" + }, + "items": { + "type": "relationship", + "relationship": "Item", + "relationship_list": true + } + } + }, + { + "name": "Item", + "fields": { + "name": { + "type": "str" + }, + "player_id": { + "type": "foreign_key", + "foreign_key": "Player.id" + + }, + "player": { + "type": "relationship", + "relationship": "Player" + } + } + } + ] + ``` + + +By specifying the player relationship from the **Item** entity, we made a `Item->Player` relationship where an **Item** is related to a single **Player**. + +Because the **Player** entity don't have any relationship declared, there is no rules concerning the relationship between `Player->Item`. + +!!! note + As you can see, you can declare a `items` relationship in the `Player` resource to make the relationship usable from the `Player` entity. + + This is fully optional and it don't do anything about the real relationship between `Player` and `Item` because evrything is set in the `Item` resource, but it allow the `Player` resource to display the linked `Item`s resources. + + +Then, one **Item** belongs to one **Player** entity and one **Player** can have multiple **Item** entities. This is a **One to Many** relationship. + + +### One to One + +In the following example, a **player has one bank account** and a **bank has many accounts**. +=== "Yaml" + ```yaml + - name: Player + fields: + name: str + account: BankAccount + - name: Bank + fields: + name: str + - name: BankAccount + fields: + bank_id: Bank.id + bank: Bank + player_id: Player.id + player: Player + ``` + +=== "Json" + ```json + [ + { + "name": "Player", + "fields": { + "name": "str", + "account": "BankAccount" + } + }, + { + "name": "Bank", + "fields": { + "name": "str" + } + }, + { + "name": "BankAccount", + "fields": { + "bank_id": "Bank.id", + "bank": "Bank", + "player_id": "Player.id", + "player": "Player" + } + } + ] + ``` + +=== "Yaml (explicit)" + ```yaml + - name: Player + fields: + name: + type: str + account: + type: relationship + relationship: BankAccount + - name: Bank + fields: + name: str + - name: BankAccount + fields: + bank_id: + type: foreign_key + foreign_key: Bank.id + bank: + type: relationship + relationship: Bank + player_id: + type: foreign_key + foreign_key: Player.id + unique: true + player: + type: relationship + relationship: Player + ``` + +=== "Json (explicit)" + ```json + [ + { + "name": "Player", + "fields": { + "name": { + "type": "str" + }, + "account": { + "type": "relationship", + "relationship": "BankAccount" + } + } + }, + { + "name": "Bank", + "fields": { + "name": "str" + } + }, + { + "name": "BankAccount", + "fields": { + "bank_id": { + "type": "foreign_key", + "foreign_key": "Bank.id" + }, + "bank": { + "type": "relationship", + "relationship": "Bank" + }, + "player_id": { + "type": "foreign_key", + "foreign_key": "Player.id", + "unique": true + }, + "player": { + "type": "relationship", + "relationship": "Player" + } + } + } + ] + ``` + +By specifying the player relationship from the **BankAccount** entity, we made a `BankAccount->Player` relationship where a BankAccount is related to a single **Player**. + +Because we also specify the **player_id** to be unique, The relationship to a player id can only exists once. Then a **Player** can have only one **BankAccount**. + + +!!! note + As you can see, you can declare a `account` relationship in the `Player` resource to make the relationship usable from the `Player` entity. + + This is fully optional and it don't do anything about the real relationship between `Player` and `BankAccount` because evrything is set in the `BankAccount` resource, but it allow the `Player` resource to display the linked `BankAccount` resource. + +Then, one **Player** has one **BankAccount** entity and one **BankAccount** is related to a single **Player**. This is a **One to One** relationship. \ No newline at end of file diff --git a/docs/blitzfile/resources.md b/docs/blitzfile/resources.md new file mode 100644 index 0000000..5e54706 --- /dev/null +++ b/docs/blitzfile/resources.md @@ -0,0 +1,310 @@ +# + +## Resources + +The `resources` section contains your Blitz resources description. It is built as below: + +=== "Yaml" + + ```yaml + resources: + - name: Book + fields: + ``` + +=== "Json" + + ```json + "resources": [ + { + "name": "Book", + "fields": {} + } + ] + ``` + +Each resource contains at least a `name` and a `fields` section. The `name` is the name of the resource and the `fields` section contains the fields of the resource. + +## Fields + +!!! note + The field section can be constructed in 2 way, the **explicit** way and the **shortcut** way. You can use both way in the same Blitz file because as the name says, the shortcut way is just a shortcut to the explicit way. + +Each field must contain at least a `name` and a `type`. + +The available field types are listed below: + +| Type | Description | Example | +| ---- | ----------- | ------- | +| `str` | A string | `Hello world` | +| `int` | An integer | `42` | +| `float` | A float | `3.14` | +| `bool` | A boolean | `true` | +| `uuid` | A UUID | `123e4567-e89b-12d3-a456-42661417` | +| `datetime` | A datetime | `2021-01-01T00:00:00` | + +=== "Yaml" + ```yaml + fields: + description: str + ``` + +=== "Json" + ```json + "fields": { + "description": "str" + } + ``` + +=== "Yaml (explicit)" + ```yaml + fields: + description: + type: str + ``` + +=== "Json (explicit)" + ```json + "fields": { + "description": { + "type": "str" + } + } + ``` + +!!! note + In this example, the name of the field is `description` and the type is `str`. + +Let's have a look with a complete resource and then break it down: + +=== "Yaml" + ```yaml + resources: + - name: Book + fields: + title: str! # (1)! + identifier!: uuid! # (2)! + author: str? # (3)! + description: # (4)! + type: str + default: "Here is a description" + ``` + + 1. The field `title` is **required** because of the `!` modifier at the end of the field type (`str!`). See the [required field](#required-field) for more details. + 2. The field `ìdentifier` is **unique** because of the `!` modifier at the end of the field name (`identifier!`). See the [unique field](#unique-field) for more details.

+ The field `identifier` is **required** because of the `!` modifier at the end of the field type (`uuid!`). See the [required field](#required-field) for more details. + 3. The field `author` is **nullable** because of the `?` modifier at the end of the field type (`str?`). See the [nullable field](#nullable-field) for more details. + 4. The field `description` has a **default value** because of the `default` property (`default: "Here is a description"`). See the [default value](#default-value) for more details. + +=== "Json" + ```json + "resources": [ + { + "name": "Book", + "fields": { + "title": "str!", // (1)! + "identifier!": "uuid!", // (2)! + "author": "str?", // (3)! + "description": { // (4)! + "type": "str", + "default": "Here is a description" + } + } + } + ] + ``` + + 1. The field `title` is **required** because of the `!` modifier at the end of the field type (`str!`). See the [required field](#required-field) for more details. + 2. The field `ìdentifier` is **unique** because of the `!` modifier at the end of the field name (`identifier!`). See the [unique field](#unique-field) for more details.

+ The field `identifier` is **required** because of the `!` modifier at the end of the field type (`uuid!`). See the [required field](#required-field) for more details. + 3. The field `author` is **nullable** because of the `?` modifier at the end of the field type (`str?`). See the [nullable field](#nullable-field) for more details. + 4. The field `description` has a **default value** because of the `default` property (`"default": "Here is a description"`). See the [default value](#default-value) for more details. + +=== "Yaml (explicit)" + ```yaml + resources: + - name: Book + fields: + title: # (1)! + type: str + required: true + identifier: # (2)! + type: uuid + unique: true + author: # (3)! + type: str + nullable: true + description: # (4)! + type: str + default: "Here is a description" + ``` + + 1. The field `title` is **required** because of the `required` propertry (`required: true`). See the [required field](#required-field) for more details. + 2. The field `ìdentifier` is **unique** because of the `unique` property at the end of the field name (`unique: true`). See the [unique field](#unique-field) for more details.

+ The field `identifier` is **required** because of the `required` property (`required: true`). See the [required field](#required-field) for more details. + 3. The field `author` is **nullable** because of the `nullable` property (`nullable: true`). See the [nullable field](#nullable-field) for more details. + 4. The field `description` has a **default value** because of the `default` property (`default: "Here is a description"`). See the [default value](#default-value) for more details. + + +=== "Json (explicit)" + ```json + "resources": [ + { + "name": "Book", + "fields": { + "title": { // (1)! + "type": "str", + "required": true + }, + "identifier": { // (2)! + "type": "uuid", + "unique": true + }, + "author": { // (3)! + "type": "str", + "nullable": true + }, + "description": { // (4)! + "type": "str", + "default": "Here is a description" + } + } + } + ] + ``` + + 1. The field `title` is **required** because of the `required` propertry (`"required": true`). See the [required field](#required-field) for more details. + 2. The field `ìdentifier` is **unique** because of the `unique` property at the end of the field name (`"unique": true`). See the [unique field](#unique-field) for more details.

+ The field `identifier` is **required** because of the `required` property (`"required": true`). See the [required field](#required-field) for more details. + 3. The field `author` is **nullable** because of the `nullable` property (`"nullable": true`). See the [nullable field](#nullable-field) for more details. + 4. The field `description` has a **default value** because of the `default` property (`"default": "Here is a description"`). See the [default value](#default-value) for more details. + + + + + +### Unique field + +You can specify if a field is **unique** by adding a `!` at the end of the field name or by setting the `unique` property to `true`. + +=== "Yaml" + ```yaml + fields: + identifier!: uuid + ``` + +=== "Json" + ```json + "fields": { + "identifier!": "uuid" + } + ``` + +=== "Yaml (explicit)" + ```yaml + fields: + identifier: + type: uuid + unique: true + ``` + +=== "Json (explicit)" + ```json + "fields": { + "identifier": { + "type": "uuid", + "unique": true + } + } + ``` + +### Nullable field + +You can specify if a field is **nullable** by adding a `?` at the end of the field type or by setting the `nullable` property to `true`. + +=== "Yaml" + ```yaml + fields: + author: str? + ``` +=== "Json" + ```json + "fields": { + "author": "str?" + } + ``` +=== "Yaml (explicit)" + ```yaml + fields: + author: + type: str + nullable: true + ``` +=== "Json (explicit)" + ```json + "fields": { + "author": { + "type": "str", + "nullable": true + } + } + ``` + +The default value will be set to `null` if the field is nullable. If you want to specify another default value, you can use the [`default`](#default) property. + +### Required field + +You can specify if a field is **required** by adding a `!` at the end of the field type or by setting the `required` property to `true`. + +=== "Yaml" + ```yaml + fields: + title: str! + ``` +=== "Json" + ```json + "fields": { + "title": "str!" + } + ``` +=== "Yaml (explicit)" + ```yaml + fields: + title: + type: str + required: true + ``` +=== "Json (explicit)" + ```json + "fields": { + "title": { + "type": "str", + "required": true + } + } + ``` + +### Default value + +??? example "No shortcut yet" + There is no shortcut yet for the `default`property. + +You can specify a **default value** for a field by setting the `default` property to the value you want. + +=== "Yaml" + ```yaml + fields: + description: + type: str + default: "Here is a description" + ``` + +=== "Json" + ```json + "fields": { + "description": { + "type": "str", + "default": "Here is a description" + } + } + ``` \ No newline at end of file diff --git a/docs/cli/create.md b/docs/cli/create.md new file mode 100644 index 0000000..9038a7a --- /dev/null +++ b/docs/cli/create.md @@ -0,0 +1,25 @@ +The `blitz create` command is used to create a new blitz app. It will ask you for the name of your app, the description of your app and the format of the blitz file. + +The default format is `yaml`. You can also use `json` format. + + + + +
+ +```console +$ blitz create your-blitz-app +Enter the description of your blitz app (): +// this is my first blitz app +Choose the format of the blitz file [json/yaml] (yaml): +// yaml + +your-blitz-app created successfully ! +To start your app, you can use: + blitz start your-blitz-app +``` + +
+ +!!! note + Use `blitz create --help` to see all available options. diff --git a/docs/cli/index.md b/docs/cli/index.md new file mode 100644 index 0000000..1d0e683 --- /dev/null +++ b/docs/cli/index.md @@ -0,0 +1,6 @@ +# Installation + +## Using [pipx](https://pipx.pypa.io/stable/installation/) (recommanded) +```bash +pipx install git+https://github.com/Paperz-org/blitz.git@0.1.0 +``` \ No newline at end of file diff --git a/docs/cli/list.md b/docs/cli/list.md new file mode 100644 index 0000000..e322203 --- /dev/null +++ b/docs/cli/list.md @@ -0,0 +1,18 @@ + + +
+ +```console +$ blitz list +┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓ +┃ Blitz app name ┃ Version ┃ +┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩ +│ another-blitz-app │ 0.0.0 │ +│ random-blitz-app │ 0.1.0 │ +└───────────────────┴─────────┘ +``` + +
+ +!!! note + Use `blitz list --help` to see all available options. diff --git a/docs/cli/references.md b/docs/cli/references.md new file mode 100644 index 0000000..09f228f --- /dev/null +++ b/docs/cli/references.md @@ -0,0 +1,3 @@ +::: mkdocs-typer + :module: blitz.cli.app + :command: app diff --git a/docs/cli/release.md b/docs/cli/release.md new file mode 100644 index 0000000..5eba8c2 --- /dev/null +++ b/docs/cli/release.md @@ -0,0 +1,15 @@ + + +
+ +```console +$ blitz release random-blitz-app minor +Blitz app random-blitz-app released at version 0.1.0 +You can now start your versioned blitz app by running: + blitz start random-blitz-app --version 0.1.0 +``` + +
+ +!!! note + Use `blitz release --help` to see all available options. diff --git a/docs/cli/start.md b/docs/cli/start.md new file mode 100644 index 0000000..f11355f --- /dev/null +++ b/docs/cli/start.md @@ -0,0 +1,26 @@ +The `blitz start` command is used to start an existing blitz app. It will start the blitz API, the blitz admin and the blitz UI. + + + +
+ +```console +$ blitz start your-blitz-app + +This is still an alpha. Please do not use in production. +Please report any issues on https://github.com/Paperz-org/blitz + +Blitz app deployed. + - Blitz UI : http://localhost:8100 + - Blitz admin : http://localhost:8100/admin + - Swagger UI : http://localhost:8100/api/docs + +INFO random-blitz-app Started server process [21292026] +INFO random-blitz-app Waiting for application startup. +INFO random-blitz-app Application startup complete. +``` + +
+ +!!! note + Use `blitz create --help` to see all available options. diff --git a/docs/css/colors.css b/docs/css/colors.css new file mode 100644 index 0000000..e69de29 diff --git a/docs/css/custom.css b/docs/css/custom.css new file mode 100644 index 0000000..bdeaae8 --- /dev/null +++ b/docs/css/custom.css @@ -0,0 +1,178 @@ +.termynal-comment { + color: #4a968f; + font-style: italic; + display: block; +} + +.termy { + /* For right to left languages */ + direction: ltr; +} + +.termy [data-termynal] { + white-space: pre-wrap; +} + +a.external-link { + /* For right to left languages */ + direction: ltr; + display: inline-block; +} + +a.external-link::after { + /* \00A0 is a non-breaking space + to make the mark be on the same line as the link + */ + content: "\00A0[↪]"; +} + +a.internal-link::after { + /* \00A0 is a non-breaking space + to make the mark be on the same line as the link + */ + content: "\00A0↪"; +} + +.shadow { + box-shadow: 5px 5px 10px #999; +} + +/* Give space to lower icons so Gitter chat doesn't get on top of them */ +.md-footer-meta { + padding-bottom: 2em; +} + +.user-list { + display: flex; + flex-wrap: wrap; + margin-bottom: 2rem; +} + +.user-list-center { + justify-content: space-evenly; +} + +.user { + margin: 1em; + min-width: 7em; +} + +.user .avatar-wrapper { + width: 80px; + height: 80px; + margin: 10px auto; + overflow: hidden; + border-radius: 50%; + position: relative; +} + +.user .avatar-wrapper img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.user .title { + text-align: center; +} + +.user .count { + font-size: 80%; + text-align: center; +} + +a.announce-link:link, +a.announce-link:visited { + color: #fff; +} + +a.announce-link:hover { + color: var(--md-accent-fg-color); +} + +.announce-wrapper { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: center; +} + +.announce-wrapper div.item { + display: none; +} + +.announce-wrapper .sponsor-badge { + display: block; + position: absolute; + top: -10px; + right: 0; + font-size: 0.5rem; + color: #999; + background-color: #666; + border-radius: 10px; + padding: 0 10px; + z-index: 10; +} + +.announce-wrapper .sponsor-image { + display: block; + border-radius: 20px; +} + +.announce-wrapper > div { + min-height: 40px; + display: flex; + align-items: center; +} + +.twitter { + color: #00acee; +} + +/* Right to left languages */ +code { + direction: ltr; + display: inline-block; +} + +.illustration { + margin-top: 2em; + margin-bottom: 2em; +} + +/* Screenshots */ +/* +Simulate a browser window frame. +Inspired by Termynal's CSS tricks with modifications +*/ + +.screenshot { + display: block; + background-color: #d3e0de; + border-radius: 4px; + padding: 45px 5px 5px; + position: relative; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.screenshot img { + display: block; + border-radius: 2px; +} + +.screenshot:before { + content: ""; + position: absolute; + top: 15px; + left: 15px; + display: inline-block; + width: 15px; + height: 15px; + border-radius: 50%; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; + box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; +} diff --git a/docs/css/termynal.css b/docs/css/termynal.css new file mode 100644 index 0000000..332af87 --- /dev/null +++ b/docs/css/termynal.css @@ -0,0 +1,109 @@ +/** + * termynal.js + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + +:root { + --color-bg: #252a33; + --color-text: #eee; + --color-text-subtle: #a2a2a2; +} + +[data-termynal] { + width: 750px; + max-width: 100%; + background: var(--color-bg); + color: var(--color-text); + /* font-size: 18px; */ + font-size: 15px; + /* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */ + font-family: "Roboto Mono", "Fira Mono", Consolas, Menlo, Monaco, + "Courier New", Courier, monospace; + border-radius: 4px; + padding: 75px 45px 35px; + position: relative; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +[data-termynal]:before { + content: ""; + position: absolute; + top: 15px; + left: 15px; + display: inline-block; + width: 15px; + height: 15px; + border-radius: 50%; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; + box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; +} + +[data-termynal]:after { + content: "bash"; + position: absolute; + color: var(--color-text-subtle); + top: 5px; + left: 0; + width: 100%; + text-align: center; +} + +a[data-terminal-control] { + text-align: right; + display: block; + color: #aebbff; +} + +[data-ty] { + display: block; + line-height: 2; +} + +[data-ty]:before { + /* Set up defaults and ensure empty lines are displayed. */ + content: ""; + display: inline-block; + vertical-align: middle; +} + +[data-ty="input"]:before, +[data-ty-prompt]:before { + margin-right: 0.75em; + color: var(--color-text-subtle); +} + +[data-ty="input"]:before { + content: "$"; +} + +[data-ty][data-ty-prompt]:before { + content: attr(data-ty-prompt); +} + +[data-ty-cursor]:after { + content: attr(data-ty-cursor); + font-family: monospace; + margin-left: 0.5em; + -webkit-animation: blink 1s infinite; + animation: blink 1s infinite; +} + +/* Cursor animation */ + +@-webkit-keyframes blink { + 50% { + opacity: 0; + } +} + +@keyframes blink { + 50% { + opacity: 0; + } +} diff --git a/docs/dashboard.md b/docs/dashboard.md new file mode 100644 index 0000000..a1e865a --- /dev/null +++ b/docs/dashboard.md @@ -0,0 +1,2 @@ +!!! warning + **WORK IN PROGRESS** \ No newline at end of file diff --git a/docs/features.md b/docs/features.md new file mode 100644 index 0000000..4cf0f59 --- /dev/null +++ b/docs/features.md @@ -0,0 +1,19 @@ +# + +> *Powered by [FastAPI](https://fastapi.tiangolo.com/), [Pydantic](https://pydantic-docs.helpmanual.io/) and [SQLModel](https://sqlmodel.tiangolo.com/).* + +## CRUD API + +Get a CRUD API from your data description in the Blitz file. + +## Automatic swagger + +Get a swagger UI for all you routes with automatic documentation. + +## Database management + +Internally manages database schema and generates data migration to keep your database up to date with your Blitz file. + +## Dashboard + +Use the intuitive dashboard to build your Blitz app, manage your data and test your API. \ No newline at end of file diff --git a/docs/images/blitz_banner.png b/docs/images/blitz_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..ba2a19f87839ffe5532deda3ed4c53706d27fefb GIT binary patch literal 42907 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

D(-J&y>Z?Uu!*|6^8zf|x4=&hDuKY z!%76LU2Ya%+5Mo|i|D#|RjH!R>_`9&H>8Q6^x`Zy7*OOmuYemtvT68g6OuHI!s55d zhvJzTRibmrR$Wl2Wz4tCsjZRDma70u|vdm+Lp`b2gNtfRW*mq<&{5Bv{$?6yPXOnhutIRtG->$@B2<=df2$k zo<=rCpVodp;osX7?iAgNi7Uv(M3@v_=UzT={nk49nOoq(v83`_jZXXAlI<%3DS63) z6B#4S-Fg@B*-3vzTUHYu5Rgy~aFuI8>6EwP?J!C;3!MqckKa7ud~23`yNT^F`@|Tg zQlZpVL&F^VKC>I08yJ;>tR&T}?RxmMYWsZ(wP8*!Gb{CZ z(n1hTTiad4)J35C%DdaY5qMdDgzoD0YLZ+ZA5dgugIM7C#Uj8q(`RuV^`i-~5Ydlg z4Z>URr{M(7FlYW2QrZA%81B0t3{2jK1nE*eMnBe&fp`Vjo{?FsFQ{V!b?3nYjZ}I| zgtAqiN@Pq|>Fq)JZH%wlDsdhf8vmAGpvZF8q+q&cl+%Y9hcBB?!-FYQZ%k5PhA%eb zcM-BM2TifE2h9%L+h1Skh8}oueNnb9A8<+u@|s>I`_IxvPE1%9PCubVY0QA`a3jC= z6b+Ed7^!gu_`>s5_}81fdH*2dIi3FR!8J;6$ul**AI^rP9s zV&HM41JIs4)k;GzycUdlgOr|};`jukpCI2j0}>B*AtRxjL>u};FUPL8((9#zVt0@K zJGe__Y3~L7ERS__r0x5q&<8vBgRc z(pc!~FVLuFV)bXEzI>Cn@vD&)9|UY_BVE7K%wYIY)ep`Y^}hhlG44^k088Zl$#gMl zyriXj2-y&A{FU}om|>Thd<&513y;6IU&i}?G+kv>lx^32Bvnd4=}=Ono1vAKQt9q) zhHgZ9XlVvex~02osG+;1ySu)7eAjpXa4q@6#TBRaKKp3W>SkL2;HqGmQJ7dd9-?ze zSgzLdd$C*&XT}f*&}Uk0BfjRD&r4r`E99P33{+Xd-fp?$ETlVMKR6{zO&HZCJY_Ts z;MDH(?+HA4PgB6{w^Eb?3bSKrHEN6kwq$ttcxL$CJv)ugz5C^!BDcu(BKf)(Dj13% z`(89H8YM+ESTv+PvK^*>{G*)x)Q^^sf=a7~`{(Dv50l!?!QkOPSGsmj4z}@ypJ}C3 zoQF#)habGtx2Bp&b`QPb8de9@myOG=8$Aiz_ct{5^wAI{3}>P)*tBZn{o|<&+@_12 z@){VO{K9t>l321RLR3_ryr~a7Gb*ZTHmpH*2;tO+5l}$?6mWIuev#TxRj?R^ijC5{ z40CLg{c64C3rw7#_w9e1+@aYhljjmwO8|>IAKPVdW>RUS<1g+CyK7!~D3bL$8A0F9 zpH$GMgoy4)5|xQ7P{kOjL`4zOMtL{1KJucoT(z|x`<;2WrB2y?z9x#`j@;Cxx-jAU z_q1jO)gBF+?4QB>CohCW`8)8Ju@?rP?;QebGS)*HQX!QW=Sft5CD6MKedJi2q4oG$ zcBVL|zGpgCuVqnHJ5nW@xq0VM%HVHA;XWe!nEByGdW($S=UgV-vN~>Uns6c3!j{gy z78K#|LDLFusd5rODV#y>q;cC8_?IwiTtsXviGJp|?9F0e!G0O-pp6*#)gyq#(aR?piNJ9*S6pf_?)oG9xB@yDu{VgL zo@RbW+~bBsJ#yoy^py~}q4w|)Ww6V9#f^EPDQ1y@h}PsC`pl9>LBniW;Khgvr-N>8 z#608D$mt`e>Q96*dqhXYt)I#rAs?T_g#yw_w1D#(t9uUvF*{H|4FLd^h+2Gx(Bn!iw*O zO|duW&OS3238(QpZIX4THu55)o*)6KroUq4E68TpXD}t4Urg{97iA|dUn}M#cFI$I z`HBv`W+6C8&0i@G%Y1vh3dkdZ@qOFgb)!6A@6bY$!rd)oi1 z&Urxr4($w}pbU$lf4s%dVoknJ&N!w~-hZ~q7VF@_`Fj0za@7u?t`TC5$IuCZqXunQ zHSRqONEwhMnN;OC0HhB5FU3mYbdg5o9csg4luSzJ@NZ5yN^i^@WGyfFrE~wxYMIv% zOnpxqzSrBmB^HW2^KljCQ{Vi>d!NQ!u&PkniZRslnpJ^wDWtsZ+QccLymwbph%1^o z8mX+dO-EEoi5-`CRdZNpm<_QC0-GR*PE8bkWI$N{1=sm3K(*&Sn}Z&)iOGtuYhk^K z#NmIvg*~=Mo)bd8Ks`YR+tCMA+0okA(WlNyQm|k+-gd7Ude6*FYov)B$Lje^id552 z7}77-F87>OLTWWv+#%CguAMt|XX>%1UEkPmK|NcKzw&hLJ;yd#4HsHm@IQe`afvs& z)&5Zdh76v~bhEA0*QK|*Dd$+#aunAVA=*f^r@6bWT);!4A9Tc9x`|f5yy=QxJNH!l zsw&Hkfr=(Qr*0(Bckh!@;!g68Ub}^UYYxYm6uXfxPw?~&6{Tm+_q0^Wlt1GuEtn@G5Z=~;0KO0m`rl!?ib?U8lgaBtyEN-k!q+ab}@!K zFFd*#s8k|!{gI!M%uAcv{hHOytXJKh9DdrWek!x&Wu%5%xVG%Vy(!$UiXM}Ne$zF& zSGk^cyt92`uh*s@tC$PBZ7H5E(7j|Y`CPR!5?8Bwa#7LS@(sK3 z%ZJ4@KHt=4kl4)5;ru1Q$c;rCCmM2?V;$zI#Y?^}7#n940aA-(eR+M;gS!USUsFTC zTW5p7STYgQr!+E5%68HuvTMZDyU=yeWP^8@C=2zX$B}*zOtk>ai}0kBS&4y;93yS{ zfyoZGRB$p(jd}GM0P`hYwakqlU@eU-z*CF+cYAKJ-TQ1iag`?cr6l#nYJkLBG(?u@Q1(qS+hvCSt*B8W> zu5@fe%S95rq@?Q@Q5=K$SeQAvh}Y+@C3%METkJ)ay{1piftKVG7RAojcd-P^HvWy6 z6%HS?imro!=N$s;nn79^WUH*K)opcZMuwsd{;yF~oQGYiI#HbGf@tLnRz82;Hmi_i z>+XuPhju64AF|YjKx7c^K%Ff{ehA8@o}(`O*>&S>Ks&Kv z2^w2~7h&K1nYn^ZRt%2}lXl9%Cg#;p(R`itmj>_*^;Hk-iEyPjC+#Nk$+Dr#8qarw z1p=#GZOYL$RRl@aHwiZ_E*IQ-Ioih#x2)=@T6a0*5zHvA+%el@>@_t<0QwJ!{&8SnP(f~6hFMXTvbCL60Ej@EPBVQvLUwUrle8~9V zVBI2a{nWeizT(K4Bw-P>PkThlboK}ic0Xrr>iw;GusH_8Hf55pKCb)BVd}Z5s(UhN z*ygP#(6buBx3cwAesl>-Wm;u{$SKB$!mt{@kRJ9U+G>-XwmA7o_ikjR;zvQjh%Po` zPVoL;yeO)Q7Yz@Z^>a%c0r5uX==AxPgjm*wLqf(%^XA48W@sQ*h#j}5Mq8MG;Y$TM!>e$(H5csJX**U!S6ic3_MB+kU_G?LKv30vyNMSH+k)}63= z`-jZxkS4h~P*Palbam%#wBEg@mFrFBIqY59m3w!yN>r!aqw`+Ds;w~Plf!V+-$S@T zOP()8$l(oXB0)3HutsPMwXVHwR%B}Rti(zVky1)S2rMG?hxz|Po!?m2=rv?@z2k|k zol`kIa1S(UlJA%KOQ>{%|OQr-hr0ER1xHC^-0V?gjtPS_@ zMG>3e2}|Cx*5LUpz078tbocP}auHM7P3T9a`c{%-GheG&RY~tUU`lKT_nH8E3p(H} zA~ikK<&4kdOC|tvfjCbfU1#AR<{q|@WVVG2Fu}nvkUUeXUw)WkpfciSl4z>!(!Y8C z05=FbB^xceO>3o%9>mSPj2S-2f>uj^;uHCMdX96!q}KQyOhw>TI7Jhnxsx_`ky~~EjrhAzHkZr2cSLw1KA#z0TmIV1|nvu->S;fJRWUapW zdGpQj?DiF6BULQfDSpflFWfEs@)ha;CBYNwBGvp+TiYSx6qyyQgj2kLg7VZ=nzSlN zcQnUoFRkz`!SJX45`wz%puMY;)FSgoz&ZoVC?DViT$l5_g0Zr{0-^&8)^L`RURi-B zPA6NOx&6&$ctp?Vr#~S#2D+s5<{w}Ygtj?vzKt=Wz1byRXR^ok>~8+qw8i~2rjXzL zQgo6A>ljJjz~+FTV*F)*F-e7cWGzR_IrVZ?WtOlp$8cI_N&5^38E()1M-x&yCyPg# zioPVE9*BtjnA2Hw8d;_UMnJ&eMFcJjJai^(ieIfAD+@+WjlJ)U(96b^h!Q@T8y{hZhjW37(7B>)joQ-Zga)E>ZqlEb!+mQX12W~?;?DUFb|KaW9kUPEU7C#gfz zCNqSA&n7dn9g}y;BPXjRM%2O$c}&HCAl?|SgL|ZSBgcD!6m*D>pdZFmX5v@ zlVvS~#5J5lx;&bLtV#RMnb*e!%#G#82C`ld+Q2nZ`8wxZbcI|gB2im8)c=mFP@;l1 zzSk3+@%i@Q=^BjaLvryByV_q+96>i)6S30CE>47>6q^Bwo@od#^7z_yeh|>Gmzo~i z09;eL`5PhrUXCnIV8|wLJae>V2+L189#4)|^b_#d%pyIRngwcf^nTobrW9h6b+|~C z)_KTMS;B0-^*UA`{s}pILzS_|bk_c;5m|E@(Fch;xvD%{db?Jd-9FF0NnDn?6ggBNs&?N^{{ay6Q z?8m5ayE~Pl3HyyE=zLutk}o&SLjSGsb|VEi<=L@*>v{`ZLqR0uCLiay8`07ibBKoC z)N4iYDn;NRV4I^Tn?U$b0$8=uJOAMe&FzggTYdU}#B=RWfVZ}scON1@Dq~Ye7~3^W z!&=i-QPRV{`eQuJaRCcsX1q#SJ^$$&{4lbMFdWZrdc7N^ntVydL=1m4e;p#FwFyt= z?h4dTEuwi}?T_v5Tb!kQ27l=HV6fYgjIRO!H1P2R6R()+KO;&NHEVGBbOsE9M-(Oz z$Aa~D?8ayX1S{CU*xLG*cw|Z=#oqpyS(Kpaanm}avB;F{>?X)9JfUuF`B zOQC}?gCtkh%c@l-y49Uy^{)@;D~p#^tzsUK>c-q+apRV~EQG)CU<@XDofoS1{*u23 z8HZ*ZFd8txXqd|5RSpCz?UJk)+f!V@0B3VmlKyvJ>#@=T5-)qtENCK78w6=&w&z@P z>J$`(?a*UUL>@m2-uOz%(f6Ffox2Ca|8mC3d?*S~@nN|nAp>@WPBUOt7`j)%qfsVm z*1-k?1t9$kzrX2iVmH&GG4^hk2!3SelgQ2%c1Oid_~c1x;Yk|NB;P==evaXb>6>qq z+x6d8v4F2}jHljR*+G6vv36gE6-TOB6IY)*dC!9Sg+9Hikb=wbN%=;W;B{6;P5XPC ztM=MPsC&}R&3rP3B-mz%qIbP{q*I^DF>scMsIIXBf#%XF2N(p-lw&zr;sFnvdV^a~ zPlrrmcT}S&c19~(UHFsT4KCW`OWR*`&>8>#W_daWZMbq>qRp7c!Z~v-$=12vdaMtK z3qwx)6Q7g>vLzXZO?`MhJO9Y-F&j+}E9qi+4?TO(*BbD4UxE5w%qXjVPaA`G9{xBUAdRX`=q_yJ`e zq`CU7nfwpB^?8}O#=b4PUr?UsrfOu-yL@C&I!89_>k`AjtCmL{7jIY9h_L#MTR# z!w+-gH}T)B?{~up3%~1qNVs0iVFiB!mJ+WwyQ@So%We7*e&+qhX=|mOR`{yj?pwsI z{qkiLEUy+^OA9ng%qIZ=?9D{1w)sE>?%a9CITn` z>4K@Krr)c&`36>a2K@#{`{P)?#&-H+tzPQlL3wkIO(G*%!y|cX@?>|gxr-JrAoc#{ z`J2|KTVJ!@Ny81T8(cw}@un`wQF+@E`+fzgLhWK^10m@S*JhT;dQc^^%}IdizS+YE zet=ukMb;Kf>b$F)1su|ke&Qa2JiqR}8;QM`(PR!eb`?aWhNtJx&lvY+xW=?}jKh8k zcEFqdalJh7tq=bshi)GId#2zXh1mM}zAcw=X%0M2s>FkV9o>_B1ryH0?;Y#R-^)1z-9)hFp!dYNR3sgm`jCc^RRb2X1j&7Q~&s7T#9S2FYA4P@mt@hd5N5);=MtBd69wtzB@2yuudt zcg%zlM#dF*mN-4Wr!WRq4fluPlpZ;Eg-3$)T0%FO*yGO_)}*O7{sG*_UIOfTe)u?X zf4FWtO|fjLj$I&&5G|fOpa2b1f&4b@JU}~F1x$@xS~xOvI)30cB5*1=Dy+@jDh|(q zVeNQrirOU`-n95#GTcoQ-G zL@JPv#;CTpfw3=3+5|)}e`+Mjqe}H(-Mwy(^D20M4WU1m^oF57CNJ;zJV~z1+tl%H zxkZ?G9LtKA8e#%AE+&+_h8UXi9e7(2>bJY5$svM_=uK4E4a$tYMCS@$+`neM&HI?t zk-{4@2xxXLeWtdEP7*qEp8Ddn6|Lq~{^5E%hBfnTo_1Wpfma@F69G_mZ3u90|Mi#8 z*KM1RWJflPo*wY^nl5aGZ#dHq8~bF34{{&90Mg` z+|dd(ah`|w27ExhwcIUaX%{!lGDf{f4*puRQJUZ|b25oek)xygBb+3$2vz+wOr+GK zDbKOR!!kyNTeF^|^-&O~4Inl*4$X94+br9N8uZLkc1kX_s9_tF%qLa0*|3??S_K~= z;yB0ZJs~Vo#43vV*ji?OShZ5xHxonm2pkaB9}TUO)U-O(tx!7^*5l0EYxohkD`jBF z$1R7jy6@AbYVMS1pwvd0&C79XARqhjqt6|dbq<>rIvw4xvtM?7sJWQ1+^{rxp_;G| zT8=|)cKs|=zV3-d+4b9F3&5~x-UsK-_bClBTbp1=2Am9RIz^GO$Q}xK{R&w> z>HR^ot7)4jvSl?gn!1Z0VxXGl@gh1b1$s_GU?`vc(58uvw4+4L;J5o1KoaCAzqeF< z#Qk}9g1V0?>(JPtj^3=?F-h0K1$e$$XSJ_Mfcvs2S;;L$F(xZk^>_}HGZoPI=!G18 zM>n2?9)lOIyszd(BUDSfEyKM$!xMk}NF*_;<)uGl>J38=6V7<@L^b1CA!uhtv#V0wJ%0#gE&Z&ZY&nH-f7k?WQDyC-$#A##-$u3+kC#Sk6D|*9)AG95J{ruD8R2uR^O`aO>0Tl`;92>nx8OI z;dhdwk@thqcU&k;R!o}VB60>dsvQ$76$L$xiMW(^B$<;5m#bu0OkCWSrkh`a2h?lWgN!2dE?j&t2T3D_g{zcHnCcZFcVMGTiF*y7QN@(Px6eH8A* z;+8M&*bdpK9VpA*iQ&G)t%tLBv5yEN0!MuMwH=~0EDWdg;q9hUbA*JG^T`~v>=&Lb z)gC{Z8;#2_ySi7J?G>L&u}1VbhqZ^u&4O^s4cCrl^jWfz)KJpbznBZ44O+^Mx}(Xb ze$@$cU?SobNr?$M7IiKGRvG{@#c>+wO7ro!s@BTWX4_rnpBm~D$1Ot<$R zXIDpo5|`PdzgA0I5%aOCzSWSVD8NMKDEePt0!PWfWl}%T?+=($569z|l*Qke$a8AF zqCf6WZ=?D8jkLuwSbMO#gCiHlWEmZ%`807C0nALK?IwysqXf;V=(|5jsdgDS?{9(& z>%A!d&{ClozbSxN&|Y1=JoLQg%j5m)x5LF+*>5>u%yg$9iEgKiZK6*`!59 zfDe^WEgc5|Msk3LSdELPch{crQ{0SCRyN%UESX468k#gasXj)n4?hmzk4r6k4_rF- zktiM+3J`pVBKvUX^}z*nZTH7;0{tF_bDNgagu3QzWp#E!yrrD0CqCut^UDknfDxxt z?9nVfX%o_Ix+hojC0+O6;0Nndm|Oh@ESgdIe#!KWC6E_c9SBEu$68*zegG6ea1`+N zR10~MdrU85745QOxTM)xW@E?qKvlDIGL(=v86l{Ye3u$61q6(H8%swQvx@f-*Do<1 zO&47Lu3fd22!tmb2cEt*u@#LpK8zsD&53~rR9LMsBwpO+GIV9d*Nk$ zx~Q4@-Ccn&5OWg;J0nu~WUs?l7==q55?c&t-4;~kx=@Dokp=m=rO)YH(nBl)cehJz zTHT<{HyOpZO{~SoH%}YjtYPywd8c2zbCZ^C$%*$8tVyJuqFa8jUfEfqX%SJ z+vHiNu^x-pFQei3rnYp$n#PIfAS*KBeEW0=EoCX%z0dxcS=kLpOSLHeqRQ!~B()Ji z(nVNLQiS3g_({dO;;m3ZTLi9ZdireO8`R<6I(#FK1!2Z+YM=pAtOOw@C{FiPpUBEu zcki2_(C2A|9Wd~w00tex(TMq;;NCuDDOdNeLtf3zOxPG7K-UkL*Aui;A~rikcHNPO zL2K}4lZ-1C^1rLKE%ObQ*E@wg zuF$AJEk(5W2me|hP^HdGRe}^vS6_NMPI1C4M3<>E&R{?VUT;oqLfho^<3h>)AjhMZ zw0prUk?I@A&mYn)Yx!RC)q=d+b0!8aJiA znmt9y?Y-?0Q&drRf4(upyx2;P>0spQjzk(5CEY%cb&`daBh$@e>m}5?LF4I^Z-Q%a%V7bJX5LDECou0Ut`P;D6u6H3q2#-^#dI* z-b?JSI5z~^5_8qW$sJ{nCec;qH9pd=iDFfP7=uftC?KemyR6`+Q9XT$5>?67O-EG(@g+X9{5T>b+G-a za4u_?1M9#Erxqrsi22~s#Z<TBK8(2)>{-zVaoJKO&x$Rj(KZ_< zC_Nyhq5V80>%8H3<147XxmJ|Ncir0X#WVj{Lv zVKz_FcG=4YPV%?cNm$sQD}YWA94_7Yhe2Q)*0q>vW2?(ZRU1@25#>)e9g;n##36R2 zP~I5X#z3QgU}jG5cCYPF1)tJ$ET&}zz|0wWphxKc2$#wualI9WJ4D@&>Idp^ZM{o7 zoL{o}%B&`7!fxcuZ-6S@yTAIDbIqFAUEiTC;Nfr^8G0kAWD&rtz9J#)^%v2GT2a3l z`oH8x9%;}K`D#0DgMUm0SefKUVpOV&4N;XZ2-oKm`?$hYu1Y=^q>-lN**B-vcgAA@ zlV%y-3J&G(f6L5QuCHpp+R_=f{byl9yE+$#1 zvQ3j*pz-4doSljib%`9^smU-?l`*TvN}v|st&+BB1mcy}5Gc01QkNq**`F`z-L@&n zN#LgSylF7=V2xYaoC3hbfN%OkvA2zO<{7~2=79X+xp)L7lGdH1&^lX2Da06v982%B zj_U!kSX(Qa(UmMhAkmt5wkxmGWb&#pf}QyOZ+FL04bC?$0%nHmk9GZ0LXL-6Pr5ml zCg+c#H`W~81E2bVZjFf99f{9yW!em^@q1jJInk|*dojE2ShaPVr7(v$L>ZKaar|H7 zAQEcOys-j#U9TDtR2MORcP=4@$_L$nYyK^ah{eY$kt1ia!CJEuuarQxeeiT8%9ggsIPylpLmMy;QpEo12GK z_Ee&P_6S!5TP3=8)K7ySB$iyS8uv3bi>-fB`W3Se6n*M1V$1D4uApG6F$0y|PePY; zKs^DzW)o)X6Q zjfG-N`G6Mh0ogC2G%633EW%d+ZHi=G#?)neFeRIyl#OhX69#H?{~(DCoXCB=tAjMN zD$m%F=n3)*8whdF`3)_`LJH6IFPhcMK%R`-VY7SEgjj6Vo1UnWxrPISyX4j*c~NIw$W<=*1C4H)@sCVlEXiLR{?U}w1>1^TJBB~#BJk=RqrZ_{JOd8TGLU$=>AcyyZ zpbfa^`z1CHH7Svmmjp*;M>)J=Vxhhx?;i`_BEysji*QMGAa z9ADH-6JC(}k_v~9*ZgL_$OE~?D zq6-<1fHV5fn4gI*{cYPNj(nV+zn?iZ68!p+HPvuFGyCf5cG$*lc#1{SbYDv=AnHll z{c*MA49DX=BKZWq<&=^VS4SSUk%F;m#Qz=T)B9c)j3^UT}Q zTajDLK{VQs_b;EZp1@{l){ghj_+EYUQ0ZeX2@`8oy+&3fTRrK0`@sFazJnqo<3?)9 zW$S|A`YXg{Vk0?!pjSlC)8VCC80**6QMZ2o>&y= z1XZioTrBOGa`jAnl|a%kn5gdw6irTf#2e4wC;olA=+VIydvr$)3RQn06gds zTJsZdm2+j68jSt4J>YW|l61;UC+#0pMt^Omn~n&`sT94<6Eim$I>=T6+RTZQv3iMo z6Hf9}DRD-?TfYj|v)Vx(IfEQA5p2zVDsRf(!yPJdR(>PpR~r#7`|;*t=Ca(^{vd2D zA6{)t_187IAH96=T3;;4sQw{2X*SXnfgMvqkkpZ6`ptGzWPrX9qKI3+>o66BGX~sQ z=?B(5%u4<^tDAvol5Ok%z?fM@z&$YPD^UBR6h%Fd?IP~F&BDR=;M~xh_4B7&$@err z?#%ksY>=X*0qYQJJS zWV!-g)OcphbbVmi*4w=DYx=$zQ96>e@8v=Ur%9h@;x5e@@`9K?-dr^Njuo;v~DMsQHf zWY7{YSUSeJ<+oLaLNZEZcL;)h724kK5cXGjh@%q8SnGKSG@H}Yyvh`I@Ok`zKcUE3 zb-{gsI)mB63ntqV&9z;$+8;5s6uy@Bdzd2z_Qz{9x0%j^{XUGmNjtaVM`3E`t^?YE zj8Rwj72P=RvK$VUM7XvSCW2K`p!wp>8_70TQc zZR$xnR4ilI$JraFY3lIFA3Q?c8hX}JxUx?A7*U{I0tsYhrE)V?+madk%M|0!61Ig- zO1XmF#iC4J2>ig0yM{wL?|B4htcS}Y7JqCt>CNDCE97{)*eeSn6qUArJd*54cw!mU z;Cf_F8X56~3lJTW5Fx2{g%~XBrXVrbnD#OJbN=A>MLD+z>BcYQmKCO!B-3kUrY}1h zjTPY-Wwny50|tGJ!r$IB@zMw$7y24XO`4meVJ5ub8^&Sq6#GP>5`Ww;X7gf0gY4Kc zl*qAIKq6VeX!iBH3~HM}oL*KxE_#E%NV^4&Ai{O+Ont>iWxs4(YV#tt22#aByWxj#zg@d9mflD?O|46bL9N~8{}Bv=d4d@bz}C2{{-$^ z0pev8w0BHf*RetYbzsn!O9n!maV>YqNB79<1=nvxakEYsRtN8(vtpbXRF(FDsgDj8ug*q zkJu>n^#ME2){9Ad6K(IO-a+3r1raMORk0wAPsbIuQSy*g>Hpj)$-FL7e;!7|4HFE0 zg;u-9RM*Ct*^H^bA~%K(6>)-wDiL_(2f9!fbnbMH317 zBHAII8`0OizFWGhnKLj`tJI5L^xBNlpxQO9LbF6Knv<*C8Ux@AHE}Caqog}jHs&gl zJ1v6NX*14Yjk*^Ko^s5pyP4ILerqxTlYg1O-4;5prd8DEt7F z#S`6wLwxo#90~kAhkuz0>AC)X>_i_C`7|l=IS~2TZ7+kFEj@Hep4uih=;tfEPtS>h zW=-AqZ(iPce24|&ckhe)jNRYBOSo|MiGpjCa*Un=TZN_Xfq0*=>&jKS?+uC{Dujjl zsdX>&`OUUjfj~vGL?fCr*h}D7eSB4YU{iIV=^PC^X#xzv!)^Myi5)K9q7UDS{c&|6 zkmhm5niM2b5MfDV=~>4c*zQl9YcE?y!dEZ4+~9j@-T{zzS)Y)^(3kHstkk~*`9}1=iYwPHt5Yg*c}}h2s)#I{{+NdCc3hen%pTwP`%`oMfS!E zrlA_Gw7Y53YWmntd0AGg^!VC{^+h9jO72!XkI$Ea%&XV&&mPvg;ze;&)LQ~alBoMk zW#%ye79z@X0+vP@wmw%(77wDH>e@Wm%()!rzmfLe!2VVoVI>}L<_%)EA`;@FX z+1r@n#X-sXJK8Qh9EOBV8Umhnr_Iy7AgpD^p*8U;#1Mg)B0Rt3>av)`QX3@jzgBuc zD7zwg&WH?A7XH9cS(R5dnk#v}*LN>C6eLwh+C${o z2M5L_s2l?_8uL7h>FH3LpxT{|i`VHa&P9Fzi~_t0PHS}pR2-vOI3Lgg44=2!#^HBDzs^)KERUOC(fj|Y;$H)XmLR8`>}~`kHP#)U>1A$ikD!*{iW4Wd8K6) zhs>=vg(7K_z|hXxeO)_~q-YdN#0JVhczDkg_R`VU`0%br;{JAuuuFo93II5opNBn@ z<%o@zvmZSAJe?5!1l@F}+7kq$mSh6^#*5)ndiW?~t8>;e60rUOfJZ@9j>bJmY~ z(@7cvA=FshIX`-VA$pmXPSi+8ik5T=cwNTl*LkSkxfFS0^0QHBuwh?w`TElIJ=pVe zgeu*TB9lfGZREq8&y#YjqipP{Ch6hytY|x&1oG`m$x6AD3JboP8G{k!)$<~OAk-19 z`M!BASOs0^tY*y?TawU8H6M$10L#lh^CkKUmd>cg20$N88mfjTpXt3qQJdJhR)65* zP)!WA(Wm%FpyXcX7BVXt+mH;wJz`ZVCd*kC`uxW8;-zB{g3qEkFFmIP1AOo7G#@ZQ zYk?Z4H#Q1O^%~mfJJpg)z!+By{wYN|e=}L!rxw?iD%LMMIFl=Dj78*zxK z?;0?U`TkdHTw!Y}RR&c#${5`{tC(yM5LMZ$WB4hYqD-c634nIL6>O6X%M%%oBE@g218z`{2-;{nY9_%9 zNuv}&t60st{V6r?fHa}9Yr|qUyU`7Ba~#>%@OYW4HSaz9q_W3(RFMjkgx>FG4P2`N z%&RUCOlj8FlT-4C7~ovhEM`LPVoK|GaF zfO8=0H2f%+N~00ih4jmZ6kj_q{5zCTvr0(ELq}d4*kOQ!p)zz_#sko3A-Nv_&|Q4j zEwrjS^;4-jpsAfC)wHkVOi0WmBzbf{w8j5IN!^om=Ukqv6M)Z#lNhFXQO1Du*l~-x z?3VDQWB=y)p8EZT64~R8ga}V{aPU?uv>=||-N#74uB*Pp_q*z>2^?>8YO2JC8N*~2 zRy54%Tbd9$Id+_ZPQN3+_<096%*1eyZmb{`R(Z*$B|`HG?>n)<-`~EE`;*TX>;c8K z(h;k3GC$xJFRGyvck-=+TXOXVD4<|-gexyN>8~}VZ%Tey-G{YLL}4&O%_1V`FyQc#~Go=PuX=D93U@PVO_%i;=Fcqi!CC=x_w>LoP3$ z-R0%E%g2JXm_XRkT<+kpl}Ns~S(@|HXJhXE6I&?~M{MP;Kg<~txZZL7vGyNXQrOi8 zi1vKyQ*VDj^yA1*n>wn8f(T!!Arm6*c?0t~5uLUI=U*XyZbbyTo{S>Qq$aTajhQmX z_fpnL=o66mqsM^&7(Q4eA{zKCK zA1j7FF)RF)8qPP(Amt>$1J_n6_XG%6YJVQhPnn;x@ zSy&4+5c80eZu*-)Fs7y$jh-xVJamfzwwa;1SVIk4pV|6Q0fE=#f(m9$Hq!Tq*PZm^ zVObRJBF6)K;az#MykW3-Kv4Xi@K!m^yW#rMSGqYVWy6QF1y45CFmzfXFP^)e+qh{8 zPq*zj)WEEc5>jCAH6$t5#+Zr3daRq#PaY=WvDo}mBmC7jn5i_$xUoeX7qKp{mCXETIPu<0*H^lfzm--`FRQMxG=Qh(Yx(GG{)C}267q2?|fCui5_dB z^}$+P)62Nw{p=VX>A}*G&fvzANegVNwlFDST+jQaocm_yTn1ay>>J%YsLdeU~z;aQb8l^MHg#2X+-Z zNI?St8!;~QoFLY#IfuEQuSiDR)^*En?1rKhTQ6;Rz7)NwcM}ozCKJU?PYE{jIR^9WZ4@cQ8o+hRGOHj3PrVc z5vljz;QSFCBUj3>TEROar}kBUYfmmP9k`KH6{tjPoo?OG_0PWBmH}{zKYrf^-FGz>iVCusGl~sP8182NRDIISf+rV_J_Kf| zl6i|7s1zqK`dh1olLI?7Kp0)_PGHL#1`7JmuA34n58|jqkysgEk5v}aP2TXr@h4?# zAd;nV67zp1Qz@f-J6mY=R#&Vt2QDtb4DU%UASc0>-Z`lSE&&=O0S;4t{wf=+$!!|A8T3m>JWy9GwWh6XFU#ESsH_Te`EmH}oJU zO+nsIQX4fvn9K9oQh33&o|I%Sw%Hm zn$cltX(^1;=KY^Y>q_1kx!@OL<0*SE%uU8j$o+&6*g)-(|n63ZQ=?@%xY>6eTSSn0R`gt6cBY(i~fQ}fw^L96P6)eH7 z&$19W3!8WaA0Z>z>0KXSluR-v8w3dKjr_6>~aShT9uY-3?3WW1|mGm^}{l)*Xr3-}{yTs@lu7j*-n zr^+PqO1O7s@6mhn_cjO)fL2}Nbz=@`PZ*D{iZiG$WHPHolP!|+*qzFn*%JIljw zForQ~kz-&4xU%3&uY~b73%}Zf)5a@i$5!IAL&2!Fc6}!GmA5@e(W&e>;&0ov_;I}F zRUo1Pp2!!kmieTrkaz@?bw6$WXJIFz!LFE+{UiIWOvMQnsL$=<+10_TD)Us-*|0Jl zzyVsUy%97^6Vp8*NKqqoy7ZIC%vuACkdoucgis4d^}#%~E>=G8@V8Qtu6$iP4Op_+ z*4v$qi1lWuA|^eJoD15j(mk2!$<7-;D(S3 zjgT!3(B`YpX6x|$-G=HO+uoZOLxES^lQcH@WY1WC5l57XKHTL?Zsk{kK8?Lwm(A9Q ziZ-UX!7S+QYsmm<#3~TfLsb*^H{AOS@ZDKGct9LNo;O8XD(<3ZW~I{0jSFRWFbriqUpX-KReVCB$3E%rZ z6Z!729!$aW6kvBTymEhG8pp-cGy{S1$(rtSv$;wValSKJ!efebs&ueg+Sqfb`6m2X zN%(VsKdQA*PI_~or75Kaj~GepNwFd)QjpevsU0`zTWWf49Um|gHG*_k^8}H-gam0?l6Pa6S2x)kY^)*sys3Q{5^NJ_&Z-LW)+EYh%a ziXceG(%m85-Agx1=X>yfz2ElQ54-2gGtbODbaS7c=e$pz&tTL$}Blu}#52S-e|>6auq3Ko3X2QCAGXfggEn zX(vZjN0t=choUAlT)yj!H<5JgGc)lf`95Hrj6sYwjq$li?*@TNww|QiGg3|ykBc)e z$xGfV9fkS7d?q{mKrPD}QY>mA%aZ8Ha`%+A*H}Bn`qkl` zqL=f}KCrpJ3G?CF?gYgWNv1rGzB%WnKVv`|S)P>TTBDe1M&nZ^P5#K`iAzgrsC%O% z@Si-Q(i02HF{BI&jO7fJhuh@DqrEdO@NGN^=9hOkLkDg5>0iFC6w9z{&ZIvE$Z5qj zd-ciWX?ljFJ1i+-wQcdXu@DvnHtuc8-o80jYnkrsD&GhiHDTpP2pL=ec5#&IgMnXTCxfY++`&kh$N}S5pq8 zz(v?O52>iV5_YIjsyrvmYE|9QsxmjyRCuNL3L(;U6MNP~;`FK$an;c+x z?988cSuL!b1%ubnvs&rL%Ob0DKJmzHJQHb-Q{qxiM`T+B=}|deUsWxN^OdedmvjUz zl|UQp>|=SByzAo&UPR|^nwMfPUqpll4EcV`xF1Dcm=pAQj1lb&0F@#;5209$g6h;nd#}Tr%%H;mJ5qSf+1bzkXdRSN>gFF^3V~vCc zmy%5#(o|uVviObHBN#1;|LCKqDxUzP0RW2%!?3S9s}+ds09b0TbKeNiWLtjj*(UUu z-WxFGsee6+zb!p5!*N|?qv$2t-XVl}TPIT89du)Gp&?SN!9q6_SPk&4-n6SY#jZ6s zv}@vugK)M6k+L*z8dfUhyR4Xb#8`ehn~a1BwR~2oSl{91(%+aY;Bl{%{OF;zW!%1? zPBuC7F8MjbSri#}VZB_uTQ95qF`_%KD7^OL-EzV_)t`-~eSL`tuoHlL{%3vY=-5_? zc4EL4O10Oo+5y!Ov>s{s9bl$q4%(i75)uUyJ!ekv8WpFH^qQeOcy*#%a;XhqhCPKa9-3`pcSy|1e|>^q{W}V9fb1T1XZ*7@_(b8_ z0ET`V?JDQIyp7PL^{V_!%KfaJ{miX?SkBWRqJDO3HHihjF_Vlh&uTxi{IZ@SrZAfa zgsi6U4#;Lct2iNbI~%Xg)mjUHhiQO}1%>5FWZ5k1Ffs#Pc*=nZqF?eLVB}27<4q!m z)SJ;-Cn5uW1iI~wmPJ6!u;_kwn6`TF>ohquiFeLnxW8%Wdd}%911&)yz06KRzQBg9scX)|SJvcn26t(pTth=zJbIL+zC*(w71Y)N2tBOX0*0qXzHQd=+i^99ALcC)lxO z?=|@s_FjQ@PWtKajG_)}Og42)p=`XHyyUmqfbgNq@ia3D1E*91QI2a0KC4G>vpM^D zJzA5*c@PEXZLtZkWqqtm*CVo|>t$|}-YQW;4tXJ`F!D3TgvBq-eGlSH=x=1;3}uhG z>j)QptsugBd*E#C0@r+oauJH0)NJk?{4)_Er+bHt*S4pQb2rU?kr6kYB2{dNz?H50(P%y^OhIWiP z99g(#?xm*JIwUNbx{OQ}4?B5~Esj#|0Dh-xGma8Wz8O6eciS?7p0>~{k-jYmbnpR4 zneRQbZn%_K_CbbGg~PXeQN>fE`g24DRUNcvqd0d=mqEd)?Y9DZiV2(772hM^_z;Y5Z&+#DwtY z#;_H{YZ6QI+L18dIC^83AVEPH8?5+#qsB&t8C-31f7bn|z_+VJ-A9C_7Gi4&?7t5a z_IC5k>~tYYE|GtL6ru>(ut};cljaH9w%R2K(3_9@pDS#PLM<`|^VW%Wh!h`ivw+lF zpX`stid`WF9<2+M?LFF%MPi6f)HGw?L{-Hx|3T`{l{K2H(=Oo)ng=?aVvYAXe+e?m zkcU$N)o!;&%hhbH7zQR6d%IVIi%*((_J?;dl|J_YC`c5C)d<%5>@zbPt9X~cxfp&! zqmKWHYVvT_U$>Y+YB~j+QOmaL614emvj#0qvLjNJtY0t!`6EZYcm3 zO|gFqqXQNtwb?{hVd}4jPznERwoX&V{f2j}LvS@4Kr#u>aNgDc*C7$;r3&!{m9Ffx z{B1%~2(>c|36NtGDg9kD(jwHdmX5pVzIT}JLKU^)sf3SJrzfU)jmh~d^Bp37trgw! zZvwxc+TjWbcraXq{O#(S2g4kt85L5n`+K_u0|nbs@ODNlDCm>|vt_qvUZpJnPK`lc zMh@xFV`KDT=V?jDHFkKbz4{yhwgp)Y|HgpWH)n~Gc|Xn9@K zm7ETholi*^f@myNT27WH_hSWx#9YjH*~;#i*SM z4S7dM&C?v^F>B(R?mX63;d;4p@|cQO{d=^^+@Ijg?3xnm-4>!{XTLTJ8EvZx$F_k+ ztt5?qkNv(18|nyitdXpQe9PCSud;aE_38CFaotUiaH#15<4M$)4e|;HrcL+gtubD& z8vQjf7K6?7X0LjSS{mH>>;4^}H6xJOh$cs}%(=-{$)q{H3j~wcU9TNZvb^v6BN>E;|7qv|Al9MXCuZuK zOD13W#c1noNif22)NqNVU)P;$?avQb7CJSlM~~A3!PwY&`0Lb8Z7lu8GjL^tK6XOr zSG5J#IA>BPgru|I_Jn~M2g}tV8{%_RVrGXU82df~g5c3d9-lmkc#U{Y1ZnUUDG$1t zUKZyc^gZ0)FsESNtM@nT65|^EakM%k#yWCz3x*|V{bkdS_WWV=vg@^aL}iX2xowM0B!ln;sT12c_;)s_1k&o^o@~KqQ+t~&A^r0xGH}Qx-LUwG_+&gz6SMfd3hc63UV>^$V9qE*JECZBY zXgq$L@{?`YQ7aMcw|5W87nVKc-@pD!D6DnyYI{`iw4D5t0z1$Ad=u?g%xjt}FV-tN zhmKs6fvLqKkhNZs#(PB4g&R#3PYb!98`WvaAY$I`jpr}80G24Ihixt18FPwR?*#m| zQ1i$8ZxQ;Qme1_EGA3C%Jd%R_8HWjY1MbE<>Ewl_0F>vl(L0*TnG|mR(iJ6RvbOQ% z;U?r>7gqFN?5;u92W6NU5Fg}xctj(ZE;N9(4w-T1dA%@0Kjf@n^L5Xre=KZ@f&{kPzDVns8^Q}MihY{9kT?mhMQf@iF ze8Vcrg*dHhLTd>T@ET5Ag53F*jy>v%Zo354tb9-^`Z8|D-PZ0}^mH{Py{MM0iYfV$ z)zgx}4Z-)4)%uw^w8o~dr@ki0>pd4Z9$`|11igDek>?NPlM;271D{7h(fjJM<&}tu zXNF3M^-$ttedx-z$2U{m78a@VR+IWN9gYH>hajv#75z=rGl!r{r{-wB^sXC6e8*{s5#gSSg8yLI{T|v+~ z%E;Nz_!GCq?|l9VRNH>3ST&*`~vHPvp#I0p+u}~|aXXYl}&cfxW0Lgsnx^^l#NZa?Op`$?qYa+Se z3=!t}R6m?0qV+Cz+P(6}Kw2yu+9MgV4mY)ccA&;*2j=03aV&HrW3Cn8qRpzRBKSgl zNsn+P)S#?HGJg$-D;$#)@;sUx@oJUh3-rt?98y)UzSc`B;g&O6AIqF9;@6>n!nu6D z*GumIA{Db?Wf0thX)kW&pQ%$6ELYz^jchJoE>IlEFw{a*96fSzJKzmyr4UGXE3lsP zefLtglbC}-{DVe1-BWDP(81KlA&nPW%LA8VU^Ec^AKA!J6h!?Ssi1WvgA?YP6LM}G zbhlsRft>5WVkLqT+-iC6oI5d&sc+7LfN{+6e=NsD_kA^)%<~qme$_o+HchArGOF42;Slr zRtj(B%%ovcyEu=iHp-XnIKVGIpwpgZY8Lne9vYq+gS4 z(+*!V+HEV#!}lTpkq3V)0U0!wGC=M|AP;V6mDh(I%&U z_%a=Saw>Tfzlg0Js~S6?ktzx1-8^EA{;jy5%{jLFeNF~Z_=A|n*KdKChFP4O-$mH#6Oa|4!@w!rH zAGIi(dt7U#G03}5D_^s=)sfWeJq4!DyDUXb?~+Vy&%M+*w1&l>6luTNU15Rf1ve@L z!JTxyd+$OHP$6<$CVwv+8=UQi@#XoHF9zo#*)grm+!@XgCU9cWM zfIu&7@qqS{;*a$SXVcd9BdH!HtDdw3JBey|nO6M0*%b$dW&zt#GFOJNESq4nuAAU} z*Ih?t71VK+as?yYUROA^G{@SUG>$m@qmgKX(NDg2e5^n8-2!?+`kX(K!_XK6!aK4w z`!pD4Uy_-c`DW@X7++;zk7>v=JN^rIid%zr$9Vc-sJZ8?w5PZJfr?T$?2*NxN)6Z& z30%AVL=knVol5AoUHZ@ehKPSun5*~rqo3$8ATeK`(9D=JWnq$d;Mlh@P zUmH@v9+Ga&=b6^qAvU+P=ggbEew_CnM}#hwAE=5{+%BRvc(TjdxC(h>Wm;ll4Y7=p z(T4i=4}XZ2(Nvs^10@NfB;tQaoBi-sBXF@iTzG%<$ur3L?8n06R*H#bs;oGmi>&mc zPN?Ld>64WDq=xFyhD65dzKY!VgI=sbRp`=j4`$Jd0yZ$bib#Rn%@v{k_md#?_KoQL z{JKKsPuQszu9$v$ju)oV5UOYY^iu}1r-Ul0qe0j!#|9$fo57U39V6t)&Jo=Bt;B`X z@)lSctT8X(3>Hey$N?e>*TfmmrGgfHp^h%c%78U1~y-_2&VZ(fpwF|6K z3ze>8fF^VbpD=^kcZ~&2>)HV zN7a7GRbOxeOqq>>{}C3m2!#q6V_GMZ~MAD9Z7HG!53<#dZTZ!g;*k~ zj)NXP;a!g9tY+&J0>rghIDa10JFzd2vM3KtyBP%-u{UGb0_c(F|a6id(|jIkwHax zklq(rao1_!5#JXJJ=Q+xl#A1Dod3eRfR^Hc4SAU?SsgM*ifoZ*3uxImQ);KKqph4- zXSB?3e;`o?)7F`qb&JY=kv?vThzE(=m@hRB9SW9z*vg=nsCd86c=OVuAuM>)si6=a z0B}|{d3uF3FhAX-dPl3a z3?+f8$5_*5R6jAPzMT0zinLDD$Cx{d#9r+c(dSk^PcO~rtd{O^a>Pb}$V~gJS~(dF zk8>IQb}vRE%n27d=7#jwHE7k$chUb;R7TG~AN#zYk%zSgu2Qms@tp^&E&Fp^un1wM zaH!_yADPHe_dsI;VEc?QR{RjmRIi+YKD(0vk$!K2tl4yTIJ%+|hY0-7quJ#A^ARcM z-E)-{v9=06q!DH9UtyN^5spYfv&N70lDudNKi#N-W~1^#Dd8Emz0t1mt{mQ@o+;yY zXg;6#Ms&EqZJ{LK%OMAM9p&LK)j?L`gty-EgZu4HR1`&JC7vv4gLEYpGE}E8!2X+P zgwqySdKbM#)^%w`pQ*8^b}Ai;1h+^q3Dk6hzT=Z}2Q7F5@Zoickg&Y48C;}fk1X8W z&$e;qv8iM9f5xk+OyeLUs}xBtT1Au`;(=7fD7a9Ww0a-8Z#mLSl{qa&quyuU!^HDU zr};|}FjO0`c(hc2x44T3%=|XPbsp_N)vv=lJeDUu7ElQlJNt1oQsRTX$gScM2XD+` z_}g^0BkE2c{e{z{f+?)`pCS{lzUzFRRY^r#L>X|m8xkb*t=4CZ7$h_&P#X%@oaw3R z+#6Kb9SD`EKF-$ii)Aitzfi0|q6*CymYEB1=jP+HSBN zoo++A?IJzgR9I5U5Ha{BmEe2O!+30A6l)<_&8Q{9voE0RF zJkUSji%-wt2&0D9mh42Da@EU#mAuSE90iqNe5|GdC~diA+cL4prnq&Y)8 zTJpWn-+PC@mbKnILNIOXbK&wCvF8@h@x7QRcp93>hM^!qS2BT3>avvYJ+-SO8*uhH z0~bx6UL-@lJJ+?2Z@3r?+ul?4``;Z3xgOp3>fbq)*bn%6;Li6;8xjR@ zCb&R=H26p>-dYsgGs+pLceDGu{QXnrffR z=J{j#pj2zN-{DQCGj4b&cySAkf6vf`y@P+d0A+p< zCc`W<4*H0>k#aGyXF&zbCJ|Y1{Ii{!i)Ryt!~A2sj|m%rjT7!Bz^0_?bZ}=-29%BgHH2Ll-|J7K8z$k!3q3iC zmdJug$*%loDS>TwBI;-WZX!DeWuL3o)4hu%6ds;a;P>^jO@@gc40ShG zI@anKj?rg?-~sHV)y?|`v#LN@i72}JR?A|uCLt270d1)fDMKS?UQ>jD3{tb5PaQbk zaZabq|NKlSDe{>^;97`R)q6HgDHjS*k*WZr;?{p5_Zygao*_oLr0tJ#;`*PQwj3xa zs|Qwybuy!PJ4?+Nb46I`*> z83#UpMRAO}L(Bi~1;|hLDz?l($#UXNF((_?Yb$3@8tfJ*S@ZrPsBg2J_n0Hd{{2sA zU!;es!y~mD&k7{IDk}2m{GJ#5FjJ^>j~Y)Fdc%bljN*Ej z#ZEFuDBRMo`81Nk%zzps@TgWGxZ)s(1CBk10b~hzckclka{v3M9ySG$wsTJ2>VUEDlg>5yqLo@sDAeu(4bHe{x6ne*}KpmH;8|u z5&ji}B{qeb3=foZUKN-Mi%&Xa+y;6A=VV9p7*bpj19FPE+EDwAGN!?~NW-m4UZfD{^w~m1cYNMsKp` zF?hlA*bHDGE_?0n2`*6ois3%P%+JU5c^KkSlw2Uk@nYdo7BT;mh1r@k_ryaQ_nOmA zmdoF>wXo~%KdT;n@dbFp_35SuNA9HNF+@y#6CO7PF4pb{k_je>X2s_;7)vSn* z3D0~dCAc@PHS=eL3c;-kdQpdERT=ERYBmU7! z=>>dQkA|*omSXA*e0k4sL8nQjSPRfNfzcO0{G3pl80*bvMdWyqBDExjOy0w5WisBD~0mKvY z;SKQ(i~1c;Y=DWn!*nri_;4rKj&^^a?vPzIJ3+g+>URKdkQ1wn_y%9I!a#1*{sa7T z<>O>e(LPku20ctG=vYi)!!G3vdcL<@P(}w90tNH=;s}P7!CHKNn#cr=wCYxhTswVg z$$@K?$#J$<%5U<_Yd+4>Z_c7jqwla>^=VQ#Un4+zPd`wb0Mw3yIs&E3i57V|I8X72 zI55YpWXVq>RRwnUDYW3vL&O5F+MOSJAw6$b&0e0bS#K&7C?nwd$LStv%1sC6kA3w3 zuB%h1L%T%;;Y}NQu}QS{x-IQd;`7kdc7}_QPLmVsoBB6mP~&_d$cB+;V2g9SF=p$G zN$o&=_x+AXCrTIt=*$7sv$oJ{8bza~?MH$pPZk_Z<(NMWtclw9&a>HEn{47;TO-`1 zJ?oN}xs&~~8+Sgzw=HUP&I!O`+?UX4Hhdxa!5k5STI9W!1N5I2*gmN~gnK^m;X-2O zCl|t@`dsbzWYa_dn{TXucAE_f8S*Xvm8unl(Z}ZRG{nvvrJ#Ylk38f+}mK+<+IuLUO{sVrh#?Ckj%7$nQD| zvM88~0H<(d@-Z-rPRXVT$cDSfr=pw>g=U@gh_mKyp0$3{?POwjrK*Dr)pszh4Hc8q z6*Y6$}fkL#Qw7rDgRH0Oz&naqzelM`kl_P~s~vSW*jbLVG|5g*e8EpU{O4+{q0 z(`-BrA|~i}DoucNx#$cGE*%3Y1ge?`oN2X<&uJmXl-AqUN@zheSH^``l_v}!-*%2! zIXf=k1?TcB&V4Id-|*j_N(2q)y6VahW0oqO zUsPz7eImH}CgAlWFc_H@Ch&gYdl`ud{uUR$1ohL5|Fw*f{EL)L^E)vBL|+Q@=Dq&R zI>)z6BCK^txP5!(EP^y8O&2^G?IJ2Xo|G*lu4RtD^%uBJ`gd0Q{kIY=O!%TLxhRYA zHwo8_DN~@0IzsnM^3Yz<>J1Ty;^_KytEwf%M)&W|?*=w(k?FTRrs#&=NFwo*g~Qdf zjECl)-P9pIJb)De?~MqTKK8t67i$-B*Ds+Tk>;NN9W_u0>i}&nXL~TODv{a&)+=wn60oF>nXHk_Mlex3jMNdX&@=~$DB@EmG zG!p_vp)Y&P3L=;-?Nm=9Zl5ngjx#ooM&C6B9OG&FBsC57*A zbf}ajaX2#Vk2XBm#mt|V*r0o%EEC+vENK^U)f@~oq_zySPMcvZ8T-%qiM^c)*Y}$r z;`nx>RavWdZD*_LInHr<3!J}c!M}8sV`andzPCcIGf~zbIw?T5D#aj^3LgS9_>b!C z87NKs;j4Z<<&n8}M%!zLU2ZK@Rx4QHE!$*Qym%R$?#hj=vnf6!&WFIfP_P$3{1em+ z={jTy#|+uMTCn_1^TICVMSyjL0I^n!py``xtv2>o$RK`MkB!n1+$&h!kZ&#m2d1<0 zt=X}@2yOlf+{|+5FqP%o_0bJ9` z0bnh<=wDT>M{RjF*9l1bbp!q5e1F$($gLNZ_sxJ*w}R0I#%O2C768`R$RjI74-PAM z5WGJ@l;X7x-+VRt9k_Q@{{w2SMA0l~622pJu+l>i`*jx!_)2A>CC}v``S6oDn(gkv z8V7@(zAPeM(0H<7GRVDBmZng^-PaBD5EuN=0^Kj)g?Y_AIAx~KUUo>F)Kec|DgBY{ z7dXPEDrc8i9`1BcC$BbSJ<)1r;!Hml3Qwyps9zcT-#kUi>qpAM=UPH? zp|HFLLp>S8Z&lC-eQH`lt*#~V>oVl%(hq2Rabn?90CaGK{(C;ie-+A`@oV^s(p1H& z#o|4G9$v)(-Le|w&IGW5J?2C97)E7M$0|EzrS``PPQ%99I(CK=h~NY8gu!2Mnt8SN zR=X4OeA&;8KEW--_}MaZ!q*I*1kb+=6Y=#^zC?vfqnmW{`@MYoo!Kv#*x5%-y!-WoLy;6f``a(%`RBPg{V zSRKwg=NEYA&HO1(*q2P+_zr|o;?;@ci|TG~lMaAu>f0UxWYK};x4|c+Pt=920h_Tu zpX;P!r{KzLn{HHkjN6x)ko12u*(7MrQ;uY+kzj_rtXK+TU zJ5djPl%rL%M-SQ&1`aUx)U*)x5=ENjhHNk-^78%IQ8f2aocZblGRUB!yX!(+4)0Xr z)Xf`m%t^q6<%<}MH1?wGde^lEE!w#tTUPewf2>7|=B^WZcR>&@iY8q7-fc3K{x#{- z1HPA2D0rIkYg4jAhEjbuQYAu(sL^(cqykqM^RZ!WXz#aNIWyLT5kq*h^m*;9m|YJ| zKHSzXnK2%1nJ=!IV_DZ7lf)l+w^-jqAjWWo@Bl`^N92n$D2Vv7j?JvEuQ;r&e6PyJ z!vuK2gIi10i_MyyV~moZamw63LAk-=mLud`&z@@RF(x%e0L{c{49r^Yt4Qm)SD{iJ zLMwxf1Hns6?tT}(`vQUh=L~QZLxD4m=#dR{*$rK&nEqk$;RZrAtxSX4IU8#MisBEE z2{w1N?yT)Da`hb*hE+w4G&ZFG#vHZOjFSZ(Chr<35hA!>%G#}%q+`$=I|f*;ziw}p z-vKvD2WaERo1{r)D^w5nn)i-<>&P)tR>I_OSRoK|^yFC`j9XgnmuR7AGy#O&!(&v@ z<-${ci9=fR{a8zL*LGCkkMV%Hz4$n<*U5a=(7mED=#FbBMEiUl-Y|>`@B=G+T{&s~ zQqO30_bcvkBFHrKgUh2s2Ur!WDs z>{r6ZQ9jw4tNo&J+7mr}wCE8|(0E{8R3d-_sDJGw|I(W4CUnO81l~|MgP0(74=0CL zAjRLiZLZ{Oh_$S#Se0^|YMhAdT;-3{m?G{rbv_l+aXVGI5LTk4k=KkzU1l zwF_y=EdSG@eNBU9dAH~pg67aW+7&bKtzit(EA@&rz7`+X7@<{o#n6?T9vX#IURtf^ zN(Z4@BRKnJ3C7?KHJSCURCN-N?dBlCDT#fM6 z+`Gg^f3JfUcjdvy{wMsLaX}Wr3>%r-8+iBSn8;FZ@**uDScHzqkql`HksU?R$@PkZ zZCMXasYXyLN}Ozjd#{})rB`0ww0jk(h5BJ!q=l08XpQtTzPGHOoI`SyeaeI1JhWa3 zc$&Fhpp6f24exChehP5z-v=w=xjo`LFhGSWMP6w}kmTvEwe&$F9;n>rxf(+3Q+@W+ z%8EC92dPXa@^+VB6n;ENq^=SP&9O>b=q} z%Y2~U+|y>md?1)--Mk{be4H}0?*ll&kV|ewjTb_jgM0t z!N^1+up&g1gb$dp%HmuTsfl5T?SqQB1LwVtBx}qefUdNI;jJVI@--oGvSrg}H{r2G z&&IoM@z4KpN=+2yt6iwyiHlYrcz;k&)3e%lIuWbde=9JlW~RW>fyqVW4=kM7{9+hes-CA(1av>g@VW8M^V!ZR>Z?XX#Ab zuH1%OgC=hr%zcv{?9NaEs`skPWNSD)>2czbsf4vOCO9O?lW?^-gy@dz`$KWSaFsb2 zzR=2%cfD8XRvVe2yj%a>1q5J-p5JbCH_ofd3^V+j{*=RK&TZlR_P} zp??W0CJ`GN>#qqy>R28t8J&+Nvq-#e9qmo z_ZTV%D$(wx6i1k$-r|G`G&ft=XEg+f#f!_2Vu<8KBzIUJlWSHo*Zf$b;;MKPARm%G zfA&(xfg;zBT%%mf!X>p6w@nv2UD?8b#oNSohL1GYOa$EcK`kMDKj#Hzps10kuTYsnjT<6P{Qew-WVNMM> zuiq3$$M@J7dl!(?1WoHg`N8_d4QZkttIMmx0ZOiP+~=@lLCo4beEwtrTnS4;?5%ngvtPZPSuN0nC!PEujnRN7mn;_G|jf}i1XXk z1?#dNQG}(v9YkjmQXYFElD`8u#hIwsN1P{gtgC;vEy`E82lKee`zt;AK7$U;t0tjN zpZ@GZC5SX$kthUW{A_xhf0jWM;5T|Z);7kE!1}yW2qDaqdcA*Y=5c0 z_DRCWr~1Tn985>N$=UM^;$O@#%qWiX^1DHsx;4yJk_XfheP zjjw5HlTJccQrWT&u3%zAoHMolV5X7hGhoH^S}x;2mQ@>Lc6+meJYY~>MDG=ANq5cj zU>JWo#-(6&!5s~z;qt*h;R#jJKKD-Vk)naEDLT9QOJ%)G9!-3lh4MKqRXrRRTM1yy zw@h-DVPg&>u3GHg6(3(-7Y`!C#aB_2D*L{2s&sOW3YnzqNF}7B71Da81xK5mj+{@c zR6jAS?XNaCotqpJk$b$Tj_6;J(QH?ucESFegf-(~Zb*$azmpFMtO+wYiyiVZ3wb+Z{MQR01ji7Ls}}B3^llnHYP(E2CGEmiZKZuIXERE}&fSIW+s^l}lM%c_KY9TlR~`G;mT>IxNu)9e%u# zKTyM9+K}1U;FJ12P?$dte91y;Cf2HPqL4 zB)%Jh0)m9T>|_;@`(h(x$F*ibmNJ5G1Dp!LFe+&%2e03IQ?P|D)(GSxPQ*$gHfGz- zv!(g)C;Ze2?3K-@AkLSb5IN)#wPMn( zISvs|ZQI;W7cboRfA}1t5a4QTFWl;`=`{dAI+~~3ZuRO=ERuOBy$_j%B(dG2>g0uy z>d(E7*Hh#JDe*mA*@>FobbAw4KZpUfeNjHr+dpPNg1NwdfMm{ml)uBs4l!U49Lk_& zcgoiIQ$67QJ(tdv5Ow}SRqsgg@Bg~vduHFa=KLC4)pl3n^Y)YT7ClQ@%8&m8_56cW z42&|F5uHq?w_=OhwBhb6W$k7qM1k955B7m?YBUW+r^4>`pNfC!KVH^5JjHA14eH8s zj@c@HrE!R`Nq^y}Z%1Cz;!Z5nqO7nR03-6Ovx%jDQk?@0oRkHQPidd;qNcbKc$-3t z^G-zyU_c@I5J6H?If>!JI^%EZXFAws&41ep0$j~9xR111q@5dtGKzb#OOhqZu9m`cvSO6~dK z(l9Ci05&eYh1svSfbJd8ormeSKJ6$&?pW9uAm}76Z61M3-$B|MX82?e!5~iEgOzGE z=!(W_{|eDSYRYu@&mLl2Pq%?fG{-`&&O(($IbTdY(poivhaVsLJ$Y5 zz~LOG6RpaWx$+kChmGQ6CLxJC{zLc9^~_Edwv+#ok5dsh|4DdxR;sSqK3Wnp%~?Lf zIJLyB@pYiL7=gJ6+x-TK!5BTk=c>y5l<%ZxlsTnB-L@OY#JP8v+4ZwBP0;Cyv}Zal zRNX{7C9yI%EB~X2e?sNR#kY;VfyAe;j>a3>BTa3ZzH*kfG+v1sl%-x7r^^mPsOt|? zka1Q%otBC}0nD1T4H~G?d;V;OYRK7L`kCm9l;vz-8-`ltkeRP1i5u(st?FUxF)8N! z9lo8&JaO)&d}u=ymXf0mGSqI5Tr)Zk_zkk+YG`wWd=4-=Pb6fKu+rP_BwRH@`n>;D z3SAe!|69qt5*KKYKA*&7!2s38wfY3H%U7d3bh^n|No$U%7x0dAR_Xp9w#;TPy8Q&N zEttrL>@SIaM%dW)>zpoVpIgwhKtvfAeTU}m3S53bIx;S78O4CxH~3r`%N8yKFZ$Le zm6D*_#lr=*`3ACZ$}05mvbB$rz!JLnn9)5;X$u;{e*wCI5U6dc7&eH4Z^NDzXKnZP zqDSV=F;M0B*AqYLBxR=uaaw-fqt9$-kD=TjF-1Ee<;q~}!gpy5VnG#>chYM+LWx*m zc=gsLYCPjtKNzcs4L7$cCKo;JDKHtTL&nIWeDqu*e-vieUt@$J6;R-y;a8xx8p(N1 zxp#deaW*tm`IBZf5B0y>tLB`28{iF?MurAjtH{$;oi8bA*J{a-FbZ)`WS@_+R{_P* zN&o?JWxuOfz{^_H;jgUEB)vbL^^ojR zd{ZM3>NJL4OvZQJfV<}5{W|DUzbtmD`AK%$dSlCW7TmCjeJKv@X2fqdb+X!Fp zvZqhR?osuTi&CtOw|f$(c`AkntaE|Wsh%?RFCK?Ef@;n!yD1MHi8 zTx+#1rj%!Ov#)Ie-GxwC@;2a~d-p#Nq^&7AF5W3EnRbOrEhn|$_**d5Hrb!Vq$;Q4 zeQKgr2#nZ18kghp_G%N<&$#NKD>wiU`|y%-e<1$6*crk^NJ~^Pd07l$POF|Cb}8 zD;G(gOZ%Wa1sWDlst=)5?kjdPAx!^5%Gv|E*`(u`!sXu+wCS6Co6GMbOeo9o+U4Hk ztDX#a^!V!OAjUA`wW&5~=kG5X*ZDM|-vrR6jQU$iM65n8Ctfo^&%iaiL?3~}ReSk{ z3JM%bJn!6O{=ZlPY7iE8D0=LFszsQ?uNo`z$Fu&=E}s`_LieED8F5pU~j^q?zL zfF!m`0Jc8X5k+!>udPqW>PPPS%??}OD`aenN8502>mnnWGj4APy1ds!{pR#nw8cBk;vL}9#Tfj`?oo#%8MNbR>43K7acB2RrH|62 zK~)|(yrOwRZRT}d(1JV8QLj!r$E}uf3KJ^6?*}DOLB}y$F!gp?*Tx%#KJ=AY2My0C zP0oy~L%>hDNZ+?ur=4MDk(|{BEDVrM=^(U8wVXCpe^R0@B{#>^Q=OcXiaQ;8HsE-z z%`_V;BtKpi*x`TkK0eGyI9u^6N4Ru4{&UXEvJ@i?6^~VxEAag*QMaq}j0P7Y>$!>h z8Kt4B2dd4^Fe|@J-LCMKh#&Z%eOx&rKpP+N81r16hcnHE^i|Wvb)Ua4>X#BOV9@>Q zUZ8oSMtStu_DHJGs-d~Veq9w~q5Dmrbj*3;^wH*v_;+P-Q3J#}$c{l$$5+pJOtsav z$(0URXtYJ04DtTVYq!;AfHh+zPGTYxtf(l?wd;?UvdgsdPekyS-wn@c|02nZ!vy1I+sgzUtXUlRK%TE=AzL`?>fp$0oRlg>fp%Ni!4a zStWW5Yf=z#8+PrEN5mNQ@&OCk`oR34;a4I48-|cP8-#XfKS>}iPBe;Eu%VHjaxcgm zKczJcjST3~Kw(HN5Iu>WUMbcHEm=Ba_w7iXHZVJi=qJFSk5gbZc-Z~$$m2~FxnE+U zP}}CR{zQM(JKfG7;$>WLVF@++aKN5$m8G9B#D1|AfkY9%Q&=1XL&~1&2ROU|sLi;Y zzMJdBAb%LD{p-Wx_d8<{Ci%k?52zUd0_IjjVh=r_eLF%Mx%pPZFjUFc9pxhP+EuCT zhW3mW&%TAgh5WQiO~*Q)Q#Ym8_+6>o*CALnxJR<1^eiJ8x)d~-x`=@u<|Ng%D~S+R z78TWT$5DfO(N2h>6jr((^?LeFc(%WYk8k>TxDHYoeT?*PuGUf-KjS5ZM8BNj_3ge9 z&7)BH=o~W!nYTKSml8LNCV>39AUF@>pt;;i5re1h`hhwxi3~&J_pu>COpi%sM68zP zy@S|~LGgk68nmCk9Uj$cvHCPCF8GIbRAQ7VGwCZ*gjx!g4|$>JpuKxkY@PegTK-Y0 z9|@kESi{5CSL6!HUAG*xx^AGF(46B};-U--OE4H6SHNmf)Abv3L2E2!f(~MJV?PN$3|yQCcmEXW;*h5ji*xNr zwFI2T)U8Uoc5Oxn%A+BFe@$H9gOy{wi$f1+^)7pY?jQ@+7tDT?5E1^>q;L6;FQxSB z{aA(*c|?i!ga=7lU)JG=$7WQohZF-g`PBSOyr{}xxJcrE;NHeAPfW66aT&hF8`#zQ!;wp56RMZ9K_wTIsq1=eGT*|R;=SvVHFD&C321!E zvxPOnp-`pvQaUmQYne~Mz=V7-x>&p?+|qPTzhFbP<2wx@0BhS@>my|O;)Bu?>XbBc@@prnQN># zK#3(MKeZIPlr7Vn+Lc?cpKEWgnCzTFA~);ei|C&nZa<5f_zkK6n+LB4^KunR0@!z7*-ZVM;jHP1j9sHH;TzGQDDMoi}#!HH*MMX zAG9A2Wpz_e(Xc1kA!o1-Eb-F@S9il$?hS{j#5oI-MkfO9Yj)lHm;)wZK6u`(3v*WU z4vEx>CgYp7IXv9U$m$LT?Y|6N zv|Ojl_`3}pOz}!X;~2YTB?-5oa|y#U9>bnKGy5%^9`djRuoCiK4|@T1Ab9%2NxB~; zcV%^T>f_!aN(sG1-vz~}1$Y)q(LVFzT`YM$F6^Gk=U{Az&bsr00hsqE(OeXyOjeZjwBz2Sq)GMoX^G`L9yWD9{!rGSdU;kOeW|AIuYze9 zNEXsnjrcplgPsI6bSk*yc!uDrD z@o89B(YZc7ZJy$BmOIs%PpPDxf_M1fG_gnvoxWN9DVDDHLXTHc1#j$yl4&2AR_O%} zpK%ZHHZ8tq$fl93peal;PD&gm5Gfb9VQH5rcMJV>2@_8(Ky-hwl{v9V=eVB9NWSig zKVxj6=MqZAWU)g#rTEDu(-s9l38~sJ9s4xS9yX4r?DLBP;OghL`MoN`)AYF9Ue-Lk z!%Xo94PTsZr{}IP`Tu_n71aH@Sxe8 zh=qps!OJ1z_zL@ZtfS(m5X9-ZBT9{w+fhNe(Yc{~e z0Dcpn1Q7_k8gJ2si$-iSG8B_AP(6`)@Z+VNLcK+E3cM?G7$|C-MJpFv#iz^;^8d10 zQ7tyG)gPak>zZUJ+hIY`n%1o4SZUetDmmQ^ zIam^{8=%=3;}=%MZE^vGaeAojOvXV+qA!lAv6bkwk|k=1HYl5Y*yQcMnYT`fK-%DA z4@a?5y59YboEN_x6sriT465u#n?jL<>;#h<`ulIw?n7q>y1f_IBDRxy5mMyM-eUp( ztQ~*i01B+}J&gw|A+5dT#=E|T&X>RWUS!OBDUwCqxH`S^^DljHY&*o2r`frl9FbO+ zuy-}?ztqPC;hQ(hLMCW11#TUj{hTK){ye_UP}=>m#@FL=CmChzV`5L5@(%!vcr1U} zL*@znhf9VKbnH4N@ENm(mX-@^fxCvJ&OU~vy!3C7(=K~I70?2bIi|jFJFS1Q)yNmS z@dI?&v$9*E8sL&yQy2CZ&BH69egk+?jIWtwII$Utd50YqoL|}0U7%<5W?&^*LUI*; zdm^91iN#D099E5Y-nk|%j1Mn=viZDtY#IEEXsxlk6`5Pjd(y9Iz~ zh_afSEqFvFV(!e*)d8I=o1r?BOzzL^lRe2hNC3(7hvabk5BAL*LqgkjVIRttq~4Jo zti2U1;6@y1n*Ui;7(`N$8b$``2f=lYr&VeAZ?LW$&D}F7kk}7t*wOW;zC21e!hHh8tI1qqDJo`1E?3)6u$nx^&M#S> zH6unE->WsW#Al}-iG14e5uT0Ye??lj6oHlm3ySVIA5o8|d)}8(9mCnaE>m01a>;YrRGUK*G)(S*LpOd@rc%pn`!Tso;yuP5foNF&E^A2X3dOo$};C3S@j?2Uc+=;EDv z`$JQGd>{?b;}kpD&Dc1eUbdEptKt{3ohR*=E`zqCoOOjvjkaAEKk_1U-p=uS65arb zyf!fh*mx>yev&ZEh9t=11)@WH<}so$5m#WA8oB? zofe!Q@u5e*d;8u3nLLscU&LtJpqOLl@5s)M@f}xd55i|3>)Q56$~0!OEFt z^~l~wo&mQ(Gu*uD5C^+g3X=}5*_nXJ(a7`AGiR3_wOVTlN-iwU3f^lCV7$=H9vj0E)Ky!5mQ^MlKTC?+)-3)tV#0dF*YPgqQJ^ zOU$B{+T%BUzl7_Q;8Fpn*CT&gVI5{M5iRojpA7JlEbs-13UNfEN|R5Iaghowbv zQB_Qz68o?rYLvJ`rp|C3u)WOGCakJGY+k0ewy#&KXgo}8?ezyf`?}Qj&TjEcN+NDF zf%&Mpv$V662AH{8VnWkxaF3%kVgKJ;KsOj%gw<#X(*-lr6KFNbqPK%nLDf1RIbDC%D z0v+04P9kFCuOABnNW$x6cO%Q;C^+l4i2o?@KDU!!C9T!2v)v@WLim`M638s{BmB>e zUV69e0-L;kVqq0yHUB(f3*M-OXR0i-POui6gdL-t&Q9!S5FY*M!i@MSKG!ebVc@=2 z`8+GwGPDA2EA{foR!}>)8c2wh0(A{I=7U*!cVf^>2Fi$_g|wqoY5!y%LS1YMP?+p? z7jB?@lm<~^^-Q)`Q>|5IWryVkXaEgpaaugjZ3ukZ!O4G^R9+wz$iI0!Adl6z=(`2= z24jKIT_l6EgUa68C6P$pf@3NlI~Jv;BP4fX@y&Q2TchAlKG@tmil5C3jgb07@lrT) zp)K;mhEIZg)BNpTr6AvFQzUDuEzGHAViqj(o9r{&dfLjdC`&50vN!n`as!(X04}`> zZwN_cfZ5CG>Pw?wAKpda?BKU@0zu8jaiG8RtnF@0bI+6|bEAhBU7af!ioHwsw`~|q z5Bf1@veRsG-Sb0~{GPHx~*HB<$R!!wjLgh>|V6gkW_kq$sN8>JM za1s`PmwO#y@&O$R)i|+>0X*Vk>b~dp&`|bb^?fc!{)SWl-(6FPW|jrA$pEiZWK18; znDRmEv71if*GNv4gKtIaQz#w%q~rKY!bS&4adi|Vlu)-=*PCzmphz9P#iX0VHtk(a zOch^1ypM{c|8y@7@4Uty!3^gom&lUp)IqdKD04K|cZL4r4G863fK^<1^|k<-7G*lR z;+iHTPgVqzes|4(1nJY@PLFlqQ^-I`y9D1)_c=|QgH1KR1!8@&a1ltK$Ys= zYB9MRh2_P@1v`FSzkd=X?uH!IsT1EvzwFPJ>~0jacaO$^##Z{ItU>ylQNyzPBu)Nf z7fUt14~U&pnk!f{hzk0CdhCFN-yp`eVQZXjqJ>2beIm2ujB$00BTt{wezgVVGM2-O zeuo#_Go|WYxgBjI*x7|LeP9 zVlLuYfi-d*#xEG^AJgZUah=8~1vr0iYzE^RHl&wp`hYRI(#-xie`hn!GER#}zW33wu zz>}1%3$hdlefM$C@v*khuL3&v2sX3)hb!+Kp1#kY>FxzEDyXK-!p)5+V_r!fzU`>8 zl?pr>@`+5Z%maOPtkq)gEYlX(Q{7;gAdr~@vS zh+pPh1}Z`Ct3c^f?KVVXWaiF8b>!%oWYt*?1<=tLgTe^-4uYl%YVdjdCSEmDddvY@3hZ}WiQ7`@u|@Y6QaqOC z0qV4wyG>Wy0f25MzNtCZ&5m7vIFhfgih%Et7ROHHedGJPzHq92)!O{isW(>)x#KH{ zbz+0tKEISxVxu2oz25K}{qMuWilL95iOWj&xUGS)tZD_3{jk#m_?i0H%1Y_Tco2h- zIZ5(t{J8$xC=I`nqM(a*pNmUBw=dZW+ybj)eL3?H@rVONQ{kl0B32o zaYx#?3=d@J75|k3^ zgl)#+=JcoRiOQ`31%2bt7aeFgpo|rv>eP_SAQptH;HV78;%RD-_vOnHz7c#B< z=6`ynJDBO1&q$fh!i9-xo(lN!g;BkYwPK5&Nwk$PlBY%aYWvlU`s8&M;wyUbwpK4e z$Um7qA!t*>)Dqb~nJ-g7emfsvaSf6wAxPqViHA!kYP6?6OpI#p%m|o2@^yFNaO2#N z7`Hg2d|I>`xvJ}pQRO_QCC(jqO5f3sb9xX^|A3*W@1;L;;dm{5Zdy9Y@-;H1@8NT$ zbEYd)n{=L--{i~tX$v+n#ws%m)04H_U*~h_>DT@Ndi;~E9Q&WMy|;zn(Of2$iH5vh zA4655Gx4uN$HKL>YZPLJjQ$`#!9d?vNeoecBZ28`d?B1;9BAknw$3xo08w&M-A@| zDOhGIHjy|^X-b09+_)FcYzPOZkG#c?m{@1>tW{h<$mM7d8Jt-7L`M?IDTc2SIH{p| zEEJK^&LGY!xU7txO!!0$S>sAMRBS{!>#v!YorvnO?;^af7$G%v>Efx=Y7aV(K<(`M zOpI{6IyB)#bLrm`?z)ZTp=UocF-yKI;5z5ziD4vS_omYHvTYSxXw>u z0FT#S`bRk@TIpGP)c1LW=j)1kK#XMOhyf5m)#J0+rWyuq-*|A3r6j-nkH-lAyV`Fp zTy6Cww(zfjxP@34`hEc%t+zr+%!si}s>=l&Is58obNTff`d!vA z;k1#DmCs2})HFt`rcOIEW)+(^6JmXRuf?TB;_jy-^KS@5RtFf(X$Z(?!cMl~J|Ku4 zy{C2WQl5Vn&=PXEUIY9w%O9q6Y|nw%J{kx%v0W&4tyF;0G4lY*HUMyr^NL(+r#BA@ zISq-=A6*mHOu`zUdLnt6dpX4SZ!N5800mq%Zyjx0o!T_G>5Cr#U}ioNTp&SQQE)+V z6iHjadd-d2A5DV6PI8UY?BkKke)2PBMth>UYOr50NPD7NXnUD|Ah;8#0;M#!>9zMb zXuO;Pu+LD+b&uSLINx1}fA~cgZi`L+tvTLqAI;!OkndH6-m?*Gr2xE3acRXvwynm- znRn@8F{;CQ(TVhmQPs`09U7$Wr{f71fh#)gtKk<0rpfF~$K8(hje9g1rWeah9S!z=vc4Kq**s%dSebz>0PbRjZSNAuF(UZvUI69~0 zaEwU#wyWt?uX%o<^-r<|z@b8VxF=7GCS{zaN53@{pO!{|18iz4>tt(R>vL%#-Swp8 zZJe2$M-sD%wuwg#LQ54WYiUgm*t5{Z66jh{oM9LQx`q~9HKOG??jx-SM@y`x1`FND zw&U#GtLC4BT7aJHs=Pg@c7z9U!|M!bi=+u}ZlJYJ!&wOI%*%bVfBIFL%U*2yWG9e45$Lk9pFPXb&1dG#fMsA*^w&`~ z{K+wE^^{nkia{4?D!Rw&3Vk3WsJ?n5%3E}|VMnJ_>%vevG&wR#= zx#r09@rqP`jL}P2>z};lzkGVm_kLYiSU+8Vrnw%(C*@WxOFwI|tE<|RlEL^B81r)R zZ6?n%L)@N8T7Aw)MrJE6rnm@f@=2j?rNAdbLY*)WOn}Qph_}NBO2xM}PX&3YxX<%@ zE&8Hmh@re`cT1|LE&UdXFX+SM#&&f^#bcla;?lX@T;i)+V(EH<=@=eCV0lA(PDpT= zDB7D7xXNfqedB6jWJcv&)xkxXj7{$%W6Pi`Obl6IZZsC({6Z{c%Slz~pkX@~482pur}rJ zdo?_qe6?o$kiD3DT?#rdof%XLgh`0p!7uCONr}X$5HS%*)BZv)xBxaVa+E&qKqpmv z{iJPjcG$Rj?($uz&_3M(s{i4L6vb009luHVkq4V2RvP>7p*L<$DcE|WUjZ;jyQ6&) z>K4o1>NS+d+yGyRUvR?2x$ai##660G#>6sM7=r|R&^QQd$?l%bbu|j!I zzGZ*4c#%c5b&}WVa*pJA*>X2`T;g^7dsOsS75)N@q|>_?q>RjKIfb+1Xyon=Isc#$ ztj^~c&avm)%_yrzA+I=H$}B;nulBJM%MmBsfd%vxXTR%jbj_Y?zv9Gi8`+LVII95c zDb0d2-1j|&Lo}6$K1{=4O-^K1ICF;|bE0@7&yC_isuRo0q<1N--PRmG`QS!-ai46I z{n(r`JrJqwh-MD#=m5%0*K1!76Zc>LE?TE_ZG1i0Y7SZ+3y%}ei(eA0eWg-4ZdJ6c z&qS^nbL~nbqX{ZA7->p1fg%0-N1BuvhlfJN^Wx_ljhX&jsuA+~{E0l>%WoR^ywhrX zLN(sR)dY;$Y;T>5w1*SIlm)xFVx(MmFHO&15N&>};j98wnSC?SV^uM0LJT7P^4S_S zJjn6fYcgpWwd0

%dQTV~k8Rn!+PL_Jnyx+)O@F>7wl6s5@!z1L;u%G`m{Y%fo+} z?j0jCa5Z3hL=_=o2-o;zgaX*i8w@B$dlHUDHx~j^QfpW*Y_Hva8@vCC4cM9O#;SOo zybIAXdbDlaO(`O}Qun$fLJ2X;D$QWhz{#CaSL+(0|2MdbH$|U!O0CIoLCs$L*WD~8 z30geo|Kyw@uPZ3>%L~j>woK7C-6aOeJazWlWyrf*A2O+ufSxmAwF&l0}?;yJiEuSiA)f?(FhJZ z&sgJ|%%s$$TJu%n%J!|^0lWouF-ZA4X1Qy5ocJe8 z^T5IhB_~J!L(zYSD7BV)KyQ>vZn$#GeP9H;Z05c5D9Mg2Mcg$gx?_0LzZudYR=H&L zaUdr`z&d`)pKa%mBYJr8&Z~WAseY?{S6c5nI`^3O=OM#`Js33UwK5-8V+gQM6$vDq&teJ#U$LJj zQjbgvUZ2d3G(4d+SPGxC`ux;9=TIrv{};n1gPH2E=w;Nyh+kMT^kg*UkTg*X zDXHaDEziC1fZ^0XYouFVIl@-&lYnkna%HiAl(weZzuR)2ITj^cB5^+Z1N|Yt@+0kp zT;O+4M%G%tQS>8q$e$Od?(utW;OC~1)L6)4L-CcE(&PrarFQQ`k(T;}n9aw^E3wyT z&#EBPS?C&<6Xe@fNe*3km3yEw8_9%@`lDiY&vZ z()-v;nwP=kj?HI(?f2XI>s^%R3SK|{EU@XsXz85++~)-8UM8e+ezy5JKR9Tc zChS4G$-VEw1o$Vh%=>iP`t_Jb_j*_3#&qkcnTJtCPM^KkKhL&@+eyR?75qaH?88g< zu4fy0#MqgP=pp=rpy;|cJ40!OhR!&3-#$+G&CQvdl?0F}+-(2Y(p{CodX^-k{9K?D zMX@U(Z{uhp6Z+|(_47si-3Lva$bxN15i|gPap(J9nZh^3T+%8|dYJK~}K zNUF3iZBni(r~LkxlnDIwGNaf&oSXSCDT5VG8eW!F5^)vZ-$`nJf0Fec4pPdthIj~Z zJS##%S)Ug4@{l8cuRkuqNgI)dou@EE#a@q@7H4joolvJTyJK63-#=@?SSFl&c~o1u zq}@12y6PYxyvo983CoioMDM7F9x@St;gTY`JEk1&1jg4`b-E(zuhY6#&}Ouz+|~1Y zEy=~^ZnU*Sn(+HEbGH3C8-DE`FZvm``3A!0E6UCNC0DHgg)A9m5en7d;ScJoO}^(kfiZL-?v*E-5ihlvVo1by`p0qP%)fZ}GwZv55oCE1=&_$n zXHG#IG|(Biz>iI7=u($8c7(a;Sc?4hy3Mbz{0dREbbn7v`1yvwtMw#$@*h5FV&4uA zbSaan96y*MEcApAW)Je;^&9Y(JSJRcbPBv^;UYLele+M77M!e@i9v?PP?$sT1jjNV zz;e%Mowq?wi{33WqM#bucsqz(-G4naWc7^s5siM%=KbcvF+cL5ll0TJJ(|&o76HZ5oj7cnW*G)OU)ymyZ(dGmwz2~ug!*M z#*Ei?amtG<492)W~-lF-P%Vk@Oc<*w8Q4#S->vbf%B?H$*HD8 z?SR@Xf#l=L+sTMf5q1t;U_9ba31H#dokT75Cwz25Am3{rIt; z_M^KAegnD`$gAmkFPA=N^DADSrC7ic#cw7>7|anY@)1O*{L_7RK+qisVToku zV~)V+IjTuIFM(MoJ0H(*+9iX^XH-d@@)Vk-Vk&8|iM~nx(QDtfNX@+YewP%tP+E%@(7S?i+8OW1v#g;4CB$%+V<0C2f$}_G7EaRlHmH zw+dPmKv}hFpg~eS!39xWCbGD^V7aZ9xIn)^oXfV0%Yd+}8X{tB0=eqi`kX69IQ>-O7zw?sYo>i#ndtkEv>d@}g4~60EHuIB;L0NxYp)CtOF>Xfi z#m0+kchbs^=9?Ghxq93vIH7oE6!FFZznK@~$==bH@c*#dFHBcA8xWlokE#(;OA=HW zXVaf$$yjD&UecaCsQj!N$ifLl-5J)i#wkiVWP(5?bkP|t{KeF!*YVG*)BM^l8E%^; z9w3OzMm+;!(_>2vDFvOR?E8>-I{zSc!9E|?v89)9U|89l+f(&&QSKeg-hB}J{1b2K z+CK5_wzz7<$o086w=%VnW3V-vnjK`Ixaje~I^USd%;Rrv&wl{B&^b(-QOf{v6mZ}- zyn1>LH7Zr)TT9L@LJAvk>0*`5nV^Gr9)!fnY-zPey#XmXdp*;=_K@i6CQ(v%Fkb{R zq96I3a8=Kq*>;w#z_GM7j+EVERlCqxxx`^KVrQPdxlnc-Uu2aS1s5a~yhKIlvsO3U zu%E(!WPCHYMBBD!C;iONgZom=@XrWIaR8PDAkA8qM3CMyjIkiB_?o2LKDGB#T zX**%?5^i-jm#*JX`Q_``k6-(HSy~3rC^T1}7x9bfPU->F?rZvW! zx*PD}lJu3BnPfeDjhWBazjF!^_`BOLZI<>7md#?aqGi~DmO+%QbviD5w=ZSJr*sPV z&(eavV+DM`-&ft$3H&PQzswteWE5!WZD~1D9Ds;wv#SWPpUipO42H z@mPAVZ^|HDWBt+ZVB2!xRH?9(Xmn0J7`iB7=8=!;^n%IIRQqLgTfJnj+zcZni_BFE z;jiJc{ukH%ne=S%g0VUHPn1yXmj;QO*0pTQPW%XDJ05FAfDPJGz(*T}N|%KYY?N#IW6#TY3f6aUs496l2CFrR}Z))IGd1-pw= z`m=fJ(3-(xTq;|8{7fY?&PatgWOPdP;*Y5Xg)Izqoc)R2Ez_{LCZ$TPJFRx5D0wlZ zU54*APNnd3hnQr8pJ+=Xow<9LPUY`=-=Zr%tqJA`!Kc(v&4wJn&r5sn=&uxGZeuYD zUEo~}2XTvse()R1=&9E3y|3|E2ATcXmzz{j#Z}T#A1&dL=+^FH=v1|M8piX4K1lNk zh7@(yJYui%@P7aBIy)P&TFeUKph1SExlqA4KFGqe2wqu)#ZdrAU~TNW1CLp+Nr%K5 zz(GX%3z)e2jHtwD>W6q$9@xc!F=gtc#CkeDJiZpJYY5;3N?rlhB&RCT7H9e!~qtFGIjY=p_d2U|lJMXj4oPTIb-`b-?=S}M(G+G_&k5e06B2RBh?R5a z5nN0SZJVUxhTM?lEwXGxa5S+eri-N*oB5H<^srUIMD>+_9!o8QiKQGXzAa+HhAFY& z->#dLmpss{-$G!oK>YG+P}!jK-#oW5fygRp>isJpre8C-uDHRI*D37mY9{2G+~;4; zWDJI$TazVabGh#;zj1oY??mI3a571FX&_*dV*!b9C3A6G2!VY4@;GVr^4Mi-_AwBYmlWSH?;3(H4)5t(GV&PQzXjbsuauS_L%c>9$Y<3l%fCsoV7YX?C{nNO z$R)U^<(;GkF|1ONX8r;JfhJ5bd>0Hc-4W$Z zy#LAxY+f^K4>XVB!6~m`a)Zy0n4G-!&E|&|g|!BTyln@8k|67(PogU3F%xuykSacf zv6;7v9TZ-gV4PkMA2(i?nJ>0dgHrkD=!MQ)bW(wyFbuPU=a#~1&{!gBt%5R+s)Ark zE=^VJKA%FQ`NKG70;-l3B>a8G(Gx;Ybz%icM(5=~l!a!-6pjCem?sVPSno=nuy2pV`Os26s^*zhK-^EzFiM%rT&YGaEB{(@Y z%7z^)WMRHzYsE#3tLi0k$ETZQRw}UCNIt#I8}Cl_M=hq==_csGI0i&YT(_8W z6WBjI`klX?DSm2nbyzfK2#g2;?~j`> zzKBa^^7os>LN!f+{-UEv>c5BqQiXIq&Ufe5FU%QutX(v}EhXk)Km8oXh8~~5@O&d8 zax$nuZA?1a?Uto#gGK-Eb3Vf~iOutVBNu#_!E=MI%uaBL7$N0b^oTxT@f>7Z_wqqO`B+0{u zy>O3Pt&>P=yjFG0iF{W)uuu?%r1tX=N3wfu+>yr|5E@IiD+FY$IohV(EIbq!n1MWQ zUSQk?_>`3J*N0eEmMSD!2=+~m#jsYk%Z!;8ypTv~)&EX)dj9^S-sg->NuZLDZ$FTH z(bUsj?crDS{w+jq3?Y**rq0Zg!K0M#+mk3}G>0}S44zyv-Dbmw<8pXww0Kfo$|NV|0{VbbpFF0+fPdF zL5=o->J^jcxpfhMoK}F8dqt_6!Dlk{oLzkj?lpAjFWyO4?7BeHZjtlJ6b920V;^al zKpXASlUG|+&_EF?bc{27_U>9)8uNmf9P_Far7;aATz5Pk2nq*p6PbSW9(sOJf>$coBXT z3oBlAx8$~E3TlQcaRt>2d6+)*(8&8718j4wG9Q!(Jw9lBI2V#4aVKvX9mZ&P%wiZU zal?n|bqR1C5};9_*xO5dcuEN?MH=bCk9M}6-040n9OiBr2L5AD!c5ONLW?P>t3X9mj)t=Y#SzTpu@q3fa=0+DagZ!%p3raZ1i)qVI~DU;`2 zn&jX;?bS+~-8^E^6hr#oP7Gq`d2T1+=P;8C!NGxX+xW5{RQz30O@>OTQEzD{i5s3A zCh(^JXnDH%!*O3Q-#XFHA;!M_cBl;tOTd@nHk@D5((PE+2=P^w%zS& z&!2DR_-&IC{nkVJ*Ul~G4YF{<&%J#~Y$UHu@LK3sX`jF7=kR1G&kOhtTqySrf~6%* z|4LSz$3pE0ZhzZPmGks5-vSvIMZhdcC)##^(l%dhgXlsn#UB2gTypTrcGAUpS_l5W*c3QnvfaW<3x%6xAV=O0q)z?h93}|geP9$H4slDJcp9_ z{s_Q9SZ3;(JPC$RDelAJ7b&T$3Jt7|(7!frwn=W4RP0lyO0Fp0UTKm}LYKFk>K5!Bb9G=pGuU&9d zty=p3d=8W`Hvrt;pLE7S=*@1`K$VaXim5WmWFIq5Irq97t*#;)vEp=ng{MA{D8PKT zd|dZZPTb!lm12MQyD~MW+ta;CQZ>aLp-&*U$?54OXLwyGzHRmpt+?pL%J3)uf5iKh zq4yN^SB@$Lfy>VNS2I(M#%HeMzclQ&oK3f8LM|%n$b1y+fJVzsa6zH8`eIH1AM!lo zM8r0PXFb4II`AWS)LI~)h}sBfwb%v^@zzb8od|ZM4sa}9?ENkUNNoMu>kmkG?wQ5| zRjSRH4^%nTACPtb!w#k62w&s!V$yWw*y;D}tO;zPm7X;y)T;&NGy}dTDJtPUJrY>` zC;H!!;6R44fIk{r#SGh$uLy{c5RhZCFuU#aCQm$DhajwmiWP24z(+|T!j_3{^*2d_ zEZXSdhv})ahqu7hRqiQz`a{%u)3PQ-V8tY0M^_+PF6ASjOBw-=yAX|{#$3lV_GPIe zL24{qnO2VOW*=1belqDBc|g!8Lz+I#O4Kgy zj>Hm=xA3qle=L?=hyAdk)oO8=ZB(n2Tf;hut5`!>@@KLz1%`7(+k&n1pG9-8uSgvu z@Dx5L=nXGZpAlB(a+Q3v4utZPgOiBt4xtsDs!SOCzwWL4T^7PvAz5lJd7XJ45Ukcd zYv(J4_LDD*^iCfY*7R->)EYt6&2v6F#Fs?g@V-o#ohVC5T`5-&Bzs6oB$ZX9WruN2 za(Adc{cCL!0xD?L}ol#r2&~!k>2P*$PT&@Tqvj3>y`-Ukqcvcach!G z96{GZEsvH{k<@sniWjJHhGH7 z9n|@;%bZL2IY?(K@$NPKCi3=fUe<{qdY54X_#&-aQq^4JXwoA(?75af-y}C*k*=kX zfsTRpq<(6gg@;%AHZHgBH!Z(rAXCOgz_&;fNp{{Z#8X*uOe*8(M^Dg=!cCXN=mWo#xJD?7Kl1Nm- z6W+8ZeN_v1c(iVMJLq_uD2@n$fdSw7j1@aoA8J-dZ!>(=D~XC{?!VcO3Gb4c?-w|4 zI>YMk2&Um#4c0!n{)0YjF*-lr3B8yjk-mT4^qxjF9)1cDT-~B%H+(~mjwKzlcq8@pM3ssvuyTgIi$#~lh>{qJBN(LDcR!qW znB+GE(V%V0H4H@EA-thR+*2FG3Txovn>Ym*p_2$56s3-E#3O6>e~%>q2~LWxjcr1Gaf~#4kk|2p3wTFqQmtkEG40qkCvzK1x>QW9T%ynRC_Y8)`F))eGk~6L%j5b)Kr8N zA#cD%7*OoDleJjxF5c&B0a9Cs|44||TGpknU)xj)34&`e;OK02k_jIYwCDq~-{Szr zwfeD&;`t{4*@2=;83hPP6Mf(9u_kKYT}mHYht$Z5x5WXd0zV#Xp5*^It1TTo+g0Vt zXnW({{{LElAG>>uurS$7!>dlbmI#VyaOSFQmD^kj)hITHxz+Iev1;4Sm&K}X zI}|r2OA-gB<=Po)?w16v+;9uWz>FaMk5XQZ0eM57gnJgBrqf;KZUVS)D8f>v47yS$ z#FDj8ANzQT43mkXE3%4we}LlYDrf2vts?#9o(J>9^)MyyZyyLLFz52k;IvE}9T!Kq zEm+4qX#y{awED@bo0PrUQ;Nw1p8fCr){)Te3kz_GmXC+Dq1+hbhOyZ!i*aY>DZW76 zGqAo*H4=7lU7LPyZTJp1fn?eH=zLxsnj`4Ln#dkjg0Q%QwxU?QCKjJun!Cf0vaUdi zMCj39n-}>st>eE%- z-~09qKhI^&icZ->i_{3jP!nR?}G@+&qD10R*M}x_vxo+aZ?; z5t=o))Hye$hLOs;Zr7Cp#ud#`@44dg%FPkXM^h!Nt3NmdXpwOpx{eIIY{aW%<8Bm+ z9#KKnw#Uzvh}Ivs-&N@%V?G4K^}nHHH8}%tq3^d>r8-cnGCjCOY$#pVGSfjYI31JK z9T}+%m1c8`p0j3j-V*p)5+01c+omiIBEAM23+1f@6 zy!)mVzB{UMR>uxWQggB8g}YS zCd2M&i{R>m%Y^vci_fX$smqrrh>DIdTUfMtL>WtI`KL@3tiyhUo{PIRgX#CqR(s*Y zGgYqyjYSE_bL1X_2RcknF1kaN7Z8-#%`!{+j>kPhDiD1%kiS(8v@OK=#jT5(s>1dG z9Zdg`D{y@iwYxsL{4O$25X5F=F5s$yvBYi(L|W!n3CO?qcoFRb6qDas-@%C_yT0z(`BXNfz3R_ z{o=EC9YbrKp6=g^E43wN`hxsL`R(Z;G>-}m09SSudi!0j0%%+`%b=?smMVN9X;J$NDOgU_+eqmpIpk-D zODgl^<_#0BLRZ_qsLmUNvr-jPeM)U%Wa3p{YBX_c*mYl3J2(q$yOhpWcS>cwVBe7h z?zvZvZcU+283r`C5|h1>TFQB!w&O~kX^L1MeA7C)j#v(O*g>omTS8XgC-O_{Pq?2H z2Kzew`*Va>#YtEq1uRO?*Cs$Ce6JmD%&$tlIo~w00>p_=OV9ongNeU-e(f(gz$zO& z7UU&HNh**{s_mq6R!=zF=pT}Db>;DqlBc?P$Nj<5Np}$WY*tTPR+%~@xcs}fe1}a| zC8MKTT6aL{?X59Yl{EC6bhX&Zh=`w??$*cdFmUR~bqDr^XN}J3>S(X-;I&al&rFQr zQfl77+^{HC#wkFRydTWrd_~p^JimWtsG>EV*|8pq>>p6!SDg<`Li9b41Xo8&{byHo z21o@vQ&kM+3=}0TCb>|J*xRQ3$6->2_X~=PL>`dxdtf{yXv+VURb8Tm19NPtLerqQ ze)rbWu6t3$4jr@V&cZ7Fxz*cTVK^?}$Z7=%{&$Ku5cFdQ1(|zuVsue-;qgrvCFC?sp+rmul%~GCK{lq<+bzzf7)fo-h?PF2scviNCA)_8V&$5ctGk zKYseh<-E#Ob|IEoNsY4Z#Lnt}ZOYksZoq9aGcy_lf97PbT*?iS$16EI4QNzglSyF} z+vKnDi=KEb`H$pRiCNm_w8~^;EdkxwAubn8#cc7k5{%(YwYlA@6q;pQju8Q*2 z$%nNaxh^vDhL=yE`w8z)o)^Jtt4f_4wo!EifT7k@r{HaWIIHxzn;2S-I@u-!!;SPY z(*looU6+eA{H2vG$7IHHwK*30yj?AI$XjN`7C-(l3B-aDJ@Af+hs5Sp6-Ab)NNNBQU-5C{;*9d=t4M~pIjN7T?#E&TE;yW|4#XID zw*=WAy4*MGo5O&IJVGuyy5rBr{^D^T$!m+Pjh*NZuH6XDz@v4bHG*=E#|<{Rc=y;d zc^y82m*kPKHPewrVnH8O#z7r)A^Z;91HhD=R?-|}Qbf6xph?W16|YbSbjIxGojR7V zzC<}xt<`Y{`fLk&?W<%~m%bZswSXNhBO~r(0$k9{cJuo=*YkANDJ{3v`H|c1cu$AV z(-i;5(^p4D`95z;i|95pUjB6%YIGB0`$pqOy4Pz4Q?2jOY?;F#Kqq?xs+*XT@xXC^9!Zxhow^l zdW6Vk%CQ*IJ$REh2L+tZfjvZ0~zwU$peZiDZjqzGTUQ{Z19Qb6Ldi~Tpx*`^lp+#>ir$@J` z890dF$!v?g$E`DDk7U&|P3;wz6Kah|0lGP;@Ksuw;pOtSpTirH>Xc1Bf z{VD`0baz;ttOl+ZUy!r)hDz(=61xq1L&C^M#XoC|sM8M!#dkxQUNq0`W#Rs=Q7OugFYNtfA3 z3jrM}S3Lt!KOIn}Z3`qvg~~_yV{vlrl5X&Xe!#W9qOOV4Ew<&Yd(y=S)GoigIx+AK z8OPMK#EeJI{g&l~&!=-@&Xag9Dr{c0DpCxq)cr-x~^F|jz)v@J}Kk%HvjnsAs2e6d|aAc2syY^P$m-B|KF z46J6n>m7q4uK}`w6O*#wihw1a|I0?iw?7aL)tfi5B|DX zf0yP=$_SBVyDgC2r~K1W8`KDU9afs2{oeTn*h3^N>xKgZ)N^c8DuZ$rQ}2 z$h`x4*2{S^e+ueV0M^De{t$zQoPyDJ=GO_`uEmbBZ|@{d0w+&~KMhdbbX=i|$q27n z2!v4IbpJzY&X{J7=pHFxYIZ_9N9l=eG!ckPa|i@p++q}@m4E*})o)>s|NWS` zgWLG3FqY2u?z|7;B3EHxb9_us?yY+hqo2v+oR`?#y_lt&pwEP^61}b|WM=L}8-+%r znn(&{-}||Vfhd*dZTA2553%8bD3Wis^?*oE8Puaz3j_r3cMAJM%I9XmoM!Y6Osu{q z6Mf@+eGVgksMSckDnHE&4(oB$Wk3?NSI#5*r~C2XMQr0`G29cxCAdr@ZJHyeHm7>s zLC>&pyL)v_HoAu&be?vtzQcj=d5L!`$gO9ES<>$MTOvm(ua`^Y9B`*BM+eoiL@dI! zPRVTY>5#dcAwMk9(Eb_VOsrF*t%ZVr^3-PvDHv(#fFTEQF2Bx%cHnovLO;A4A}~*t zh+{&(){@5KEj?A{JrKd6nQx3`n<}esBxuwz;d>k5vu+J8r$Wl`; zY{ByFH*u#giEU`YNj%_>DJdzJdl zj4&Zykh7h8!4QSvaD-;N05mJdYvND5C&e|x@kIc2nwtRz1W;RWdnfT0Rq2@E=$ZMN zp-fbTk+bwNRqZ`L#|M1CZ~VM+&{f%IIHdhFO~u~)J*V#I!~akZH1WIC_D~cFMDjJ% z^CMPdC?WZ}F%33{mF31ySY%J{ch1vaaG%!Z>}h7P-lscH+pP-gorATT(6h#bitd3V zQ}MU{kz-El@@GQV1sE>&Db@jYnly=I`LJIyav4-MJp<4jvo#Aiicgs*L#am0Gv z?n-X8R)=UdQ%D(6egS-t#37F3DWGB~EWDZ*R)dv#XIo(q=ambRIEf+Ri;e$R#w}7U za{?$nfstBubwgVF+1Pd(YX>=n93$VvCvy6N+7(u#K8=1@$>Xq(iF%RR<69rMdPM@T z#4wgbx3;jI!(5)NV`~N+?aFP#Jz_C{b5iF_QTJeHvciJUHIIy=O8}+Ua^VBdWlWOd z&ES9K&%)BwWSf>E+pCT zOndOoD?T?tKvu}=zjkp%r&&FXa|`zCvMT$F&ayJ{6p)L`j?K0_yD|h}Ee+RPKMCZP z-w;|}kJdY7{BV+_xG;*GGSk$>mh!JMs}C*i*fJF2i|#bUJd=nR-9nrBMi~v{g5brq zn{RXl{aY9E%U+n_d>@D*Ki5w&3ov zwn8M%vufY|Ymr)WT14u)g>4|CW_K6OCP;u$X}YpaBSdUT(?P|@SIjC50^hSO&!B!d z%f51rD>CX&i4TlPd){4#`vt%bsy|eC762lI?Csmq5a3zs58DE80uDW`qWbT8vXk$V ztR7itPisN0zal<=7|SU0eeXm*l=acDz%jNtf3$}Z%8`6B*X6aZWE9(T+fgCxkFIE2 zvi>jfSU5DS>M)!Zuk)wSndr=sP-jz11E5nHIv=8n8OhCRG^a(XkY2%k{jt8j1h_N#^gtCoM3R&FXIq7RKYK>(!@1JC zP%SnSEm>J?=9H_OkN`i=vwkt&ChiTT$HSr2!`h(eBr8{|eTO=ixgUhP zw`aB7Bv^;c?)OgM)2V<%yP408#=@1gv=$CfwBk;IfVD#WU%hxY3A-?W2g<8^K8RFN z+Q_RJs8;XXvl;|MDY8U+^4O}r9$RsQEmCxJwv1aLLvc|{GZ|cMRit*Egp(LqrfqG)9{Qko%tJLPmO%1 zm1~ohKLM0*8UwVfpPt|mtmhr+Krc9knnZ!Q&NwDZPTw);`MS&{7-cMdkn4|Dfw1}* z4HH)Cp$PjK%;H61vEK_TalxUr@{y-)AHU=vstr`vevCN-Uw-XXaRWjp5&W-63gEuU zS}93jXo4E;2EdvXE@xZS*l@R;k?W&wOd5ee)AMtYphkTkm2EsovQ)hn%>Dc39>+bn>=Em&x%RHYb`@DH>*8S-30wH3E6c zmpS6N4c1Yt7aRW^X*v4=#0Bz4F=5cA2#h@Rb(Oyc@*Z#ME3!>!2!dY7yU@0V<~x4( znS)PD+-7X~>Z)#9&FoMEnK7%c`(YCaFlVQtkYJ>tbM`efbt0n<3W$coDnFM0UNH%; z5F_>+r_=Xd#wg63W|sMEYJ7m1nvA-f^mDM3Fl{(hQe zMu3OT{jS)CmTY1zem&pL zFYCwmaVl19IOB3DmQ`kNB`rzaBIl~lXcNmxK2>B4S?l)S5GuKaZFbyVrg=imqRqXn<^l2)%3MN7mR-o11qG?Tk`u!89I|Km4WJoO}d+#4HVM7F*emo?dmS|v81Y!kS1JO%rTGfF8GGm47q(f9S zF#*;|7z-4&Z3K54Sl;LDK=G@ysO29;6nZk-+812lff-xEJ{Esg0EbDCRw@F>VmB{K zu-_q^##)ooH2v(QnyFdVF#H38A`F)G5-1yF3Sl2pKF04Q!)7b2@~s4MR^H71-F;by z2VWkK8LFFqn9CFW*sc$WWoPJFnUQ28L#kPWaHEyWuQ|@vnF%@+duBjWnDWPx#Qi-t18xO`Nc@H`LnQ# zgPzQ`tTnF9qTWg8pNq?-$HsK|NY#~3(8%D>$%V$fB83*-d7X=ET$sIrY~3U>i2>{d z&u(HjxC$xE#e_)ZFJL{pInQvP3HjC)Em(IMJBr8txgA}_fQ>f+RbH^ygx;B&4{=H` zc14Ke_TXsRib6{Q8ML`4qbi`XE^rdL`Zvju$KfJ(P5hJI`A&XSvCRa903A=QFugFL zQQ?+Rg*R(mf#&KH=J&&W>a3^fy}+8>wfeNPthtT8IeHCn`&&|qJo|J>Cn2f)@*zZC zC~29cNVKsy^l}*PzlJX8(TZJ~eg~{3FLyj!ZtGWLBQCAfd`l~_XG=NIuz}^V?c&U( zY$nEl!V8k#-B?909Hy`6cy-pL5rJWz>93)0MMn}m zCHMoJRtt_OF;($Ae+i{=A$fPp9kWc9^0TN9bvl7wu6zw0B=i2afFDG$xAv)h zMdwjjn#=vspb2A@5=*#)Krht3{-ZdR-!eLN;>FK}-_-o)4U0F25`2?}bJSo$g5{{3 z##UgcnDyoESs^1DNQ&B<_$y*@+oU`arD*`VAl#QqH5)N-#CV6HC4q%VT5{vL3jm9o z0i@#{>|h*+fdUN8pVyP2`#vr3%)T)VnKBegL1K23B_YG+>{LhZePAG+U%sq1jj(CKsBd0rMgVJ!G~`{(cU+ciQ&z=kkeOpSonY*QEtPaZs#4P)y! zEW)D=F20)PZCFA@eJK^1)<%x3f$z%oUP_nSs6bErqXP8k%6$93&>keKHs{2MAVStu zkK}^xC5Dj~0Ia%T&L0H?vXcpdvf$p#hOXdvFT=Su5i_3CBt4oN)Tz`aAw!q;u((Dt_o)TJ-9`G@sC) z-!ejF$0RG^T#xw}p|LQQF+PppA1#Xj2e^o~(Q%uzgLzGJr7Y#BICc$mQya@s$_3>O z{fQ$klQah1#WzZfiAds;$ZV*x_&JhOtcXvO(pA0R5cQDc`anr6>>x7-zjb+JZ4kh`D2IAf&iQx_ku2|q|-WfKFYJFg&?RA?8y5|X+sXL)Xc<3n? zo`TN`(APZSKu<*8FVRvw0iHqo$5NCOkeWLD=OIE1u$u#XQC68A0{MUK-nS{bejnh$ z#*iFB|4SY~{|?ShNlUDlpwoYc3%T;^-_miKpZLsZ;czZXjr)ylk0!92UDZmW`y!&hTDrAOlsudKl`C4d#4;l439!cjtpT6 zv3)zd`y{P)Qg)Kw!R)<6KphjRwXJ00NNtRUAtKkul-DcOAW0c>f`4vh5eeGVHi+E9? z^=<}2rD?JMzn+3!>X$ElB8oif{t_;JsAHNodvk559l#b31 z&Jepeq{L%4ou86;cPAgP!9q_6LN&fw{}E)VY;O7)EZp4F{Z~01a5d5@c(W2!byXEk z$wjlF3V-`&4zrlQHQ<{#AwC>t$+tlNYWk2~LiRO z8odv*E(>~1ZPDeZg9O^uwdA*a6Dnv617Q z<`aHn2kEv2@>f=@RP*izASvcn2qd?Kz1LY6gZ4Zvn(qR;6XHvXwX*ZDWSiPMJ|oTb=j zKdH)kUL!qmA3>k?BP^4S|4$3h^N#v-O<2$6K1mz=emMmmGrAE*V;7*Zo^F3p#~iI< zjH!3_4pFg{R!Q6K?ayEYrT!hSTFA4!kX{1DkwD)jUm_ABaLST?XNaEKCkItQarun0 zRO8c)r?e)ai0TdIqlPCh=P9zo(F%9v8ZGJPzNpXFLIO-NUy?uLBwd&#m7x5`WE)Dj zfaw@#Z_Vf(8(G-MIS>wXlnJ4h;v~#ri~nFCXT_Wphm1g0n$JMF`Il#pN;OCnSeb_l zaP^e4yTZ3@ZDKBIf(@5*4c=90Una)aJm1v0#>~D#(|->S;c(BTQnRJfX({VQ>4vba z%}1VkwK7}Yz8BR+I)Egwy|58F_inycnble8;Wcv_U)2vQS~nqfRVb2BK!efBy9n+4 z7Z-{_{re?Hd(F*?QH<5vxRjZ~xhk88C>j^Jcc6z)CLUs9)o_FPM`KOxQ;;#*w<)(u zaw8t`?U7ke2Y$0I@96S`vw)i(x6dL@b`Ltc&Vyu%8V)A1uA(OIG)6$bR9=Db-ZJ^j z=nWmH4A|xDlPvFMN)2zK+LX6q{otK+V+39|&>K+?<60GdHu%}P#&=~5v-CqE0E;{a zxYfh}&rGHeJ`M(!{19U`^2>|1M6j~2s=0-YW3$p|y2a_~YpGRzf562z8>h1=B2Qy_ z_f!}%LQ8XeU)knFJgd`oc&+QA9Yom0nzsA-WKGS=)wQ_r(-gmtS9Y#cJS53z(Ewn$ z=&DkgE%6vDY&x3DoAnp>f7NR5$m2A#iMmJ<2p%MM%~W=paRvZ^~&LQZw;PCeU+qS zmSv8wE~~_xmS*#hGK_tsOQe8XV8e886q|=tjh}ddBR(iasigPaRs__oL@-m|2&eB_ zJt<6yfMWUM@RA!g{9()UAZcaC)_~q@xk1{?*qc8-yb$ixdPDOKwPaI%aC5P5PJhFb z+0>KPrFr@&l5iC)HUvWTZYLm8};h&htnIq+8S18pIc=_QPiTc`!^~j9y(7VC5GzPBK?nLY=(yhMh z&H(=hQ@{-EC2JZ{Z3kusGT?_%i9u{-ee6S+#_7;mQ}+Gi}Wk^7Wj^Q)c89v+k`f3#Erk%RJR0 zS+O1twlu(!K5hNzXx-;x?~4C|zMn0e3!(ULw|rdSC$e9?KOjMkGMqmCg%!!|1$Lx? z5?sG|yXB%{Is;wk!w)GhVG$QwbypQfli|Z3$E?eJe`>tN(UbCH`??T0A)XvrXv}PJ zW-osoUGs2o+UO?Q97m$r-%{$&!Zfm8xH2aCLI7|pl7UN@{bwNHRiOZK{6!fu=dE2V zL^zNE=LTb+za;r}BkTr$Ugu$=C1u3h*DFXK#wRDX{u)w98{dZQKIZm!`!rE{b+$w` z$HGBy`8R(u4tsg1mGGuGH+hKA@7->ZaV(bYu!TU&elE69Lu>6VP@n51xHi2JFHuYWGFKSv=|U&1 z^s>UukW&Tvw~Ge+E9`qVXMLQy*lQv6@2lshZF{QYrf`!M8!D%n+dH82RGYX$6tO`rta1~6>9u=K;_quD5me@p`ND#Zmks0x(n68F5KwiR| zP?sC7TPl(tXKx7{z0Y$+cowX!i`TMg)?!gpCB8@~aO>Rs?sZu9Um*>u@&vS{o7K-K zk#QBRYfQ9J*stmmK%3#iUaiCik`Lm*_XHL#`rMxZ6g1!{O|5VL zTgnb5N8i!{B-X28Ht0yD3BCcAJj@o~yUBWX`eW-AZt;qPl;0FvD2}18k1M&ma>{UoQ8e)? zEroj~&y}+TRbK%PC~l!I9byThC|eAPt#w6W_=p8eV}-ueIYpocvReD0wuTDhluToF zXpeiGxS&E5&+~^SN>w1#tig_Z%@%L=wwO&zT!SoxOY+Ko(*J_3ki)x{H+4qL39Ph; zRuY}f6!-15IY(p!dt9$cN}I(zG@pd04etHXiXDs^tMmM~ENF=u-d-3M0BExT)L#k# zv)roEY{QUpm|R>C3?;$X9}P+L-)nP}H;doumpWd>247>3SNV@!WQ8gH^jmoE%{>Zu zk;Vax#?{g6Cpj9kqLxwF4iZ-|{QXF{u9oXV&Z`h9wtBteH^U9WaF*uQHJ=o4iT-!j z5n@}|g#%yc_f=#_su>f1vVE$@7y0S=ui>_|vCWK%kIx&dG=S*NnvB+8UX}8{@1;c0&T-droLtIUrv%_yy4H+AM9ziJT07)u0&lU@0NdEG-)i~3^cP_*cr)Qe+$L(Ht=w*=7ZT{}L;NN*}?`U0Ot0T>S|4OqShOh`wU@ zWgLS)$W?(J7y6PF9EcG*1qxyLNBPFVWB)W@?`b?|3cR=ZP{Pc&h2bj4*)arcvolxj zNeK!M;w!65CDc34PNa6JN;N>gy)wNSS^H+pom|vr#kw{{s)!-IJI}9Lte!<(!@P=+ zS_6--3*Ug`g&;{h{U+L+yc=SaNHFVKg!R&V0a1PM{km@kzoKYEyv@~1skh?8sPksg zp|)95=3eVD{og2O;P!_Mr)vW%-x`2Jt?TZ2sW~X<#J{eI2TFVyZRi}bd1f?{9Xm)7 zHR>mI-7jn?Jjgw4X6II-s!F`ED6|Xen0adZkO@Ed)f305_A)7_c}zL=0DC#g-vI$u zlsR&b&11CARRJz+7s++JD1Ac=%p3^DrU^))J;m!r4GLI4ukT^%&Fi#LARt{3ui*S- znK2@v?&NGO0F?>8AHsT!Udl+-Dro3$e-}?bu{KrKbH?^9vuD1z?YsS<-CzE`JF}~k zg|J+u`>U2cTe`zXwUr+b71^6H!62CWqdfGN?2wJlj4n_ydC%2YxcD|)Ry#JN^xBu3<64=sLt|2Y zZ?gp`#*Y6xrQdwpiauf`qSEWTLt1Bc`7SL{u4Xn6rI&e&qM<{oI3p0vDpb#ll$ zw~thQk6OlTVwJonH_n$AAc|K)G&fXt?MvqylcT3x6oTi~!at7R9lkOk&kFA%HCwAn zp%zeZgxinYD970^_^Iqa>PtNhZ(!pnBLn?Xr;&DSzGlyicvIgqZ@kLeajmVT&_;kU zS+RKkAf-|80~XLT!SzNZ;&u}jo@bpDy!sOIZ=a^Vi4Fj>>0i*lg}!f&HHDysMV`B? zc&hR3P$URNG@SH#{w~R@P+v)F>6F;F|7LxhGY!^(QhlRyDt>k3xCBz(Sd3FV)3ZIh z$opv{mK+&AS{=h8(Z2T_hDGnx1Y>@NxDi^#?^VMz26*rF1JKoIw{-wShA!}o5^XqB zkfspe#t+P1J6Tug$qdSzy!Z~5 zBZnPj_wdef@~zQ3v4Qu7Ie{-Wy;fb=5uPSs9sOX_A=0v8%BGGY2DFxZh$at$^~*@2 z`>VUt(vIh53vSvBH>n!)GpgFoYyeN+gtidj9{~d*)lk46+3Itj*eKKRm2tuCBdtE& z;gM0Fc;5F_Od(VtqB~TPjdDZjV%pL}rXyOEg-uk;7+^>iS2!rW%S&o#fEt-v*5@jc_gsk5^I4-}kQ}i^dF9tTRT;s)|t@ zpSjlFm}ydkkuWfc8FYsbmzc4QY^sveawVwz?LyM40UG~ca`*zWZlbwAhZ#B1_EEw) z^h(pc5iLQIEc&|0_<21BCY(KRJSbd6KurLN>jRgxc{nr)=fVXAsw;?farGzqNY0i)2nvtu2Me~rOa$L*%wMZbCbU&&Gd91d3f;Qyj6ROn>vVHgjHWF zg~AQ2(}#PIw@tX9ZAMz>zk+4;)%~$z;1KGhS(~POo1oNSN%_>Si4126}LLl(GD|f z6j4fiB#=TRX{+04@*jhA5zcVerxT3p*_O6?uftR4nUdo|`ZWe*4mvxWQO!mYAeENA z@XiK&&G4#2%IS5VS4@why0lhXh*Rh(Y?$yr_y`aU1P@%1c zeE}qJ3&rWpQ|lb@^+$qb^KR*W<*KSsg3m~~y{(FwqaJ^NLVzhzO!BL%XHCq!h5aAl zuk6Ba0daosc%E$-FFsiy4f9s#@GJ1udnq+%K(#r}DL&7TaN$N;q|p28BQ@RCCe<=z zqhnv$r6~1E7tV4oZG@>t{Dtdw!rfWj0fdl zKxjMON(Ym1Iv12BPmlw$f3Esp(z2MQ4+~@(Wo;bwkaw5Y&xU98Z?598`^>TABfI9#>DEX0((lmIl3P$g>a#$W?fwjn=%VtqaF`-eZ$V4Na%`l%BWHzOd-hF-TWQGK3vXJ&vz@3G)h1E}H96Le&Ex4+J; ztz9P6Gp;l&uhq!KZb!ugPl}#Ajs6hGy@z(?m~(xv%l+_hSMyMr{I+tQLer}IDk$c4 zk1MfB-Mr=u^`E*J1Z~CYi!7i(=AZziMxTZvCVuNx%JrXCMgM0`WLhtTqyo*SVw6}Z z8IxBe4vD~AU=;ZUVAKj%Cw!r6d(hojQLulR;<4lcFsOAB6r&Lx0~u!VxP;ITP46{&c?vG_NGaIJ*G6d zi$itszYn&u+M_QCTW$K&AqBTU6Bs}gc{|DG2CIh4G;)6teGpg@h|u_B{rv@z4YGaE^AR8c?SY-s;+cwql>tikgRBi!YC6xX(J@gu?q zRmM2|mYoXBUPivz|5)E7@hX-yowl+%Dm3j&CP>`SD-=|qUOk^b{N^W*_zUg zUrE#7mwTVog)FwL*9U0aSJKrc(yq1@dg$=}d0HQm`aG48upW7c1wkVLndCp9JSOiZ zvd3?tg)LB(B5(Y6#y#8@=qUuUvN)wc*xipt%di6DQBc{EppealL@P}?O661pVC8W? zW{R7(n41{5dIzx#`4p!`J{}Tju?H~3@yI==f1nf@Dtm!5g*N;+yKajjY=3sgsuHiO zcjR5o?<>!?Sw6b@R)9qFiwm{;+zMj|wa?Pt$r$T#m3I)#rFp0*IP_&LJ=yw~w%YJk zbXcW&1w+S>(vS~;pz%S3wC|bE7jF@{r2Q$9yBGB` z)BY+rd1-vXo^LV=kw!6o#?pviI+tPf2Uh29Hbr0 zyWn(i*f!5vl7tlBa55Ew|~k5!j^+FHWNCaK##eA_ni@mznCHgpEu?nFw$Dr)t2Pfg9j2j6Xc z#X(~hP}s;<=%i$0gCfM8!eKY+vHzFSDt@*3C4y8aBQ^?LjC}dw1-a-b1V}ynss@8Q^H}U5VfdnaFf;Vv)o=LB;*D>{1VE-7Y=i>ecqgvq0!wI2Tang}mUyEHTy7m_ zoDVni^2}ZBsS`sCefpR_t(jdQmf3N{LctU_jU!dN9FZt|CmGv2cIhim0KV9GM7O2 zUODPzy|zF+KyYiJk zdoe$SFrzhXZb7t^TtmYKBET)Kw|X0pYZf5x2l^I#Ieqq-xu-JuW7gxkV)cjAA!XMR z@dK{XABo@ISHdC0t*W7eL{#0ra!#|4Hyu^W0{CP&-2>5lHJa^ct+KjD=cI0bwofw% zBaZXj)_?IXBs><4T)>;_?`9Sk!9>VLQbA|3u5Y_{5D|Xmh!|Ne_$Re*uit z&$ap-fcQ_t@|Hv~|ko{=RpQBvrJ$0xLO!0vP)tYw&nynSCD zTgj_H9z{cC+OO~L7O@C*xh^GveKk9Xh!>k>#Cm&c#-~I0 z?OxVC`!5|LvjjrEr5B1e6goonXGTaJS^>g|BJw{e;z>5jB5vlKJU0<8_&lf8BXasf zMl|NC_G$CA>fF5d4rS(&Ru@GNpPhWqobq5PviZ!li{M!=oq*4bP^X5^ixA3#m6etQ zcoPwK>Wn$00*$?cRNpgOd;$ZXj5-i-`@mJXZ(W=6<))wUuzk(x#ux*WBc6WUwUm^B zR94!bbx5=^R#0z9ou#mM1$rp#i(q}6={)6pJTngb>)=hpFlV#tkPw@O?LmZCQ*SaB zMy;@EBS5u(KH@ZVIt)<25KxvB<>DO@5evC^pj-y#4V1SQ3?@8NpT7CnLhu3~)II2qmR{er+Z{Sj(RL@26oPeu+irzKLdP4{X6h z#3p6nx*!M_(ztR^yLZq`0Pmt%lP=tnSs^Wk^hs^-0 zads33H#>8fu&u^^_~Q+%D{x5C@eq{C@b$>gkNPbT26to@w{SU}y>$uQO>)_UJ9ej$+q|Wy7&GcZ1#Z zY=Xq9rhFXP_A`N=LARTv@~+zfm6<5<{xMAK$Z2i|3$|^BV&jusf`d6?Sy?-bT*AF> z-OsJC2htrqWWfi|pGe9x0yu<-yOq7)vLIF?KD|PM%<)j>fAuPnB4GNv%Sd-Hyh3t> z*$#!mpObXy6X}X9i^cfN1MHAdTM1K_qn3ZmQ&4C)^NDc6eGmI~qNsU3>9aorq3L2H zX@7v$^5kZO{nju$hpR1X?K&f#R?W&6i!dN;+)K*VVy{!COW{Zuu{>q}?{(!H1fF^h z)2VT2V_jeha`!L66rZVlh!%{`K=^BXG6GyzdS|mLHGXZ*_ zVEa2r;@Ei`KOOXcT7Z;@&R*S_dtawXqmj^>wXpA2V43zSt$w_O6Y)@@DxDefxZ=+7 z*w0RQX93o!BOdJ}%jf1k62lx#OEse#Zm4?Sy2D75Z%k3;aY_n+Iv)twR_ZPTh$mC? zu?1ukds6;N_yJmZt&eexI9T4fHRk}*Z-spuop@$_6Q@Qt%2K7`Q$997o zJ@^~1B=9&_Mi@N*4TQs!jczi7lYovj1f&R!M!SF>_%F~)3Jy!Evpz|y@wkdUhQ06Kh- zm)^Rw)eyU~8!=S`NI}VWt(&H@>=HeytiqhZ!lwhD<4NsT#=skCGkxgUa&7BO>#J%Q zO-oe(n_S3Vl)wBtlsZ8@D-=7kVXVV6pPyG31c#4hBNtDfXS!dcu9%;czpO>pluvPC zW($NRjRXU89L;zp5hr?&xu4BoVwE9{U?W0+aA(o~>PDdSh3q68fN?-oxsOiIu~$f@ zSGYu)6n}nH>x=Bdd6oJ1Sn=Vm%k$txGUT*|U7uObi|OpEJ1eiOrl0s$_DyJdKc_BD zbbAsZ2^YOaWvlBcKO20`&K{a_k8XKu46Hj{rJgqu8?jvAgtt|OX-VFKFacY>DIQcw z9dUCtY`EAR->x(z0p%`^)sf61hyGmw00E4FhKV*n%Fr5JY_I z$kU(A3-YIpHFb+HynNO)*YnOWmzFN{BSZv{K+MNY*KTZD;HGU2cEK9nALb=%iif0^rIs2}3|+n; zr#a_z%^#hE;lD8O88eX?Tbq@C9IR|H`gOm|P&55PI=XelAARPfE5m4dxUc)qn(C-`j=xtSvd&r7q$FYRypo?$0ypy&47UVHJCk+u2|eX*420O*CSP?u1^iNOZ0PG^+6Tw`8uq6O_uDIqC2=Ebk)lZ413yvz zg!7+@C|Bn>2^zM#gZ%%%8-j5HNSF^(F_o6Mxu)F?4t95^37iT5i9+>?0);mLf!siSPr>Ffn4WX zw{*H%N5sD^$Hh5q5Y#C=QYDsjh=vRxg2cr% za36t`=nML)Y5W8NZ+1BVZU7UOEere91Sx;K#;YeBOQWHqdNNvf}yM!)*hmX3b zg&v;kKkYE>omb$vJbLJVS$!ezhSE*cYU#+33rq$IlVhc3OV5x4MyHpt9}Ad_g1|N1 zGwj>2S(|2{z>k!g&Z_T$JE|@Qh^Ij!dL0-Qh}dsW^=2Oc(~8 z;t6t{wKEXh65bAXc1X=xncFDhB`N!U`#xUfm@7iZM!MsHVx~S^#8`04^Kh2+^}`K{ zbK{E7<6+I6wAHbL{54XjJh4l+`}dMuz(42BCOA51Wrfht(mr)+*++3fgoMkQyg9mZ zc$<%bHMFge|LQ|rlNFpIvaj+wo6O770olROYxY=S#F;nB+vfRTFjtl3qRz6yOA`!jl*JgyHe@}1|pE(A5@*W+x5e*NPSJG|<(5&@f z>PXjxa8F-{tMoF_PU#8*9?!F(BgSpPnuCAHxg_%bMA zy~*PAkme7`6d071sX5Pp>HAEgCVA`!rI`!#Z0C?Ob(<>VYlMgs%gAP8lZBr8puNdp zZ7U?oGDZ3>=2qI#te-A|SXa~p=kVc|$n?yc`(phIHoa0ddSEAO1(Tmf$q7~NTuiX) z1b+eUwl0vd-So7)3}T81g%zx0{Dq9Vq0Y*GAv6VYBWC4kAY0-57y)SHu#S`yWz6Hm z$7%huS|oG=hT)DdLh3r9qtm%9hVbU=h|k$pies=h(qB>>s2WdOsk02N~n836U*Pj%$$#AYi{ zBrW<(73D0!a<{M4J%qf-Ig&koQq*H;?wn0R6hHqkMoTR;Xc5v6MSI=p`uccPF=bo- z>H43xS0iutRe(PQs~vAQaeq`5@Q|b#qy+-^x)9ex%s2vHM4?QZ)f=YQa<=(!FWgbzSX^}DAv6#m^FikFG z6d$2`yBAkbBkCj;?^^3B@*S(OHL0UyoO{dat}7^ zmh1ixwT$Dek49|YHdp}()Xq!W8ZMZdOOBjHUWF*{YoAPQvn1%c{(8G<`<}P~vQg#M z)!y2l0TQ4poKaTcc3%{sHC-b1uvt?_C8Urf!&j}{IF3wWRG87tVPN$?)#aqS)7QY{ zyC0c^3wzo~f2VEF*{88YKY_(ur5}_L$y}}gdcsu25^Xtl0c}KQ0F(O-&sctWy=>{U zd(`x&@lp5^4A(WFn?A^hdhX-uO94BV#!^e_WmRceS->{Hs*Tu1Ps~>mJtT7`OSlxYYxBDV2nKeAYk5E|Ben6tk z0>s$6_aDcRuDQaI8<_SmO4L>mzVacq1i%DB299QZTe#x`48PQVU5TSePyauft}-gh z@9RoSiy|p(w)SHMNwaiUR7j;Yq`vQ{J;)_oszLTF_vlGEHP7}3{UOOK| zI&4NCR;fzPI&{tYyp20~gFmOZBw~EJ@?O2qtw_H~SYD1z9Na6(JTb}>bz}13g41Bg zr`Haa$9?Xk^$)bOB~Vix7$4D+#2yO0bY~eCW?w$pJ&V`aue%i;W`JxjtLkz#-&Dn*Q;e` zv5$wAfWEed%pD7 z=?qL(iybvzr%y-8H(FOYHe)zq+@j+jpN>xtOlvFiw5GV4eabo9RMRl0K5@FA*&)0K zVb!^MS2|DG+T~;zuU1j>B?#1!h)Ct0njsB5g1M-LdOOxfyR5$-NEgo z_S>Y*bIn%dGDO%+c_o+ zH;``Tur?$2Cte!l5MStalB*7<`9>H@7zD(`pKK7T*qResDJIje6%Pi=2ny{C!a}?^ zdfieB7p{4~!DE@O-)H~g6*r+l7V6$2gbtAJ6g@tDBF>|_+^4(zawe|dd_(T-qF67% z*t~$A%x>7HJ$aku@i~NmkiUQZSe^I<%UHTg2O{Se4{3W$zemgupK z1(^vnhlL6E(4xNex}Z=?+m^vAyz1M>vGyjkK-==`TKZ(FWkM_*RTjumGWEe@ zVHJ{aotwt!&&y`qDZQ)qv!{(C;r#iRTe$&mwV3j53i5nbyC>jxr1wmn(`NKu`Nwph z3<1m+X$<-wSR_M^#a#@eccnju5d02P>&OV{cG!87G2n6U8TK*;;VV?Bs}cyKNqSR% zR<+}u{pSRr{coaZ;JX0@6m~=gf9BcQAp7TprI}S3s+`5G`aUWyXt<5L9l<*O*AZcm zaVkja?e0pBGiKH{PiMHdeGJhQd{l~u%f(p!%lco;WZ$W_SB9hC<~_gqW2l7B+P(Rc zy92e!>k+@>2k?nC@eDO!VpaQk)d1l+!v*a?0@GDcy5Nz+TN1Lc7)uG=C&O8m&BZup zQo(3?);ATET^9!eiK@+f)8B+@%^z94B4Ct!#S_=>TLb%9F&Dk8YUhg@}g@S7zZ6`1}y`n48qBU6wC(ab%KX1-p=_=`&C`G z3es27=UjVN{YV5;eff5TSAQ$Nf$~HYi35Q|Ed5wkaYSP#+VlW!Ah|OwPAlGCkY{oq z3Nw%tP=pIR-rjHVrp$vL`g~uV3WHk}&&bS<+?i!-4>Z`D1LRmRrmJrS+{ERwbkCqx^0kZ+pNQ;tI?{kU=Z2lBai|X?o#R# z6Umt?3eOCH9kSi<$MFvi@O~{Z_7w~C%`miQx8px^L$wxl7wEG4=6xW7qSuQa5OszT z;1gvq9r&NJ27r;R}hT{AvF4Cf7hG3UZAgDLbMm(EEq19tv+es zZMYB+T=lUn)o_W;Uf8?}=x@kY!V{_R+k2P{Qd2RUNdaAU(5 z!oWWqDz<_+PXn0!v$q<6NU3|fU>B8X{$cw@eK-)qLH*?P+rtYH6KX2)v=?6dD)={4 zHLL>NLW9lZbIVv4t+#%>c?W5Z|>iTI)RN#Cw$t#Q|K1Gh&GWx1^!K$i&RD5FV;Y*?Q(!tHwtpvFg&H$YA-_^rb1ZL~*4cz8$b@hP{$5d}XxQI;uNvC4 z4HW$R33q5}2a=VvZcS77sR3zC#Pq@L(Aj+`BVEjs>P9sAlvi?lb>9V%R@;F11WwRg zDw8=Rm%I~`o+|JEm?ANf zPBJ!Ly4p1brQ6r{Rr(5;n2T>RsQ}F>m%wUDd*O`X+m17TDY-Shjfb9gtWX{TGXMF6 zhUp4vRy}+S3LteCTy!i_d-HS@$De~>N+$=b$j5@e*l3r6Rf)NhuP$EJEy~nYvc((E z=v=f9h`Db(nosg5Le+nF!cDhVTo$n*(7Ki>k)c^ad4~mMmG= zvJS8t1J9SSYsOx|j`3#+^&?*Hpt6b(F&7}~GF=v$|LkLK`0mM+gJKt`d|Op({jN68 z4=)|)>P~LL!fE}ROxm$vu;^D3O%@B=Sr9iO+s;CdF{?oz4q6y%NVN=s~5)0;|87JG@b+k~w zA9oJ`d2wZPa|ZoKLuE3ZxU23axH%k$%nhz-jy0;Sq^O|8L9b2M#eBE%MLV*rYddAs zpdo0m%v81|{6^szNZL;+SDVH7Jkj?il}CO^7xy;Z)2H3C>Go)uZB!|? z7jSRMowEgEfxhvHqz!a{-yCDcDwX8S%T+L<(bd3;K1*Nw2kMX1;OyyKZ#GE1y+Ku~ z63E-OI+bIW->!9jAz?f1{dyO8C$PKf(X2s87N&_Yw;q zlN4;qp*jU-7>_U=oL@^WeZ@&&X9DrYrlAFKOaZNQvUnlEoex76i^~nR7(C1)aSe3W*oc+MwJjT zn%)6_VvH`FGg%_rBf*M!yd{dGC*|bbV|gfA!DG5ezO37!;+rx;RL0(f*hAx6HfUV^ zJ%Flb-cTp93f>b5Hbw5EMJ-&5-puZ6F&%oJz8W$7^?d=?E@QrLV!=da@AalaH7F1< zWNvbK^3L7#DSX*IU8JjPPi)tdS<1z%Mcbb-RBzd0gr1BAt44y56!;#`9n;<0v}u5F zC-@c4wX#@45uEFY`fIK)iovtC22yXc(h(P^+D&T!&ohUkX37CPhN&qs%KdRZ4km3Q zE~Q*KH|PrrJ$?i+qvX+%{TH9x_TIgtOF@{|K2EsKAOp`!aX0u2x9@Y)vp}a~o1r#p zCg~$abl#!mH5!qZ_rVSqS1{GFR5rVoMy~A&gh)QuZ#4fcZK-eK=Mqjj#G?E1fdk}u z*nh5NAS$rn9KMPjpve{W3u$KE$5VM<_Vh!w(mz@!O_)~G@~hQ3G;h3TLFK_Sw}%%4 zMG7|qKlXvqqJQ`OGY*~ENJyPobKbN1!zq)eb!I*{hFV6*Lg!Dw$c*jzpkvDub|_DE zycFP>pNaQ+?~(Mj!;J|&haoKSJMqB!C0jlX1qdpf{6Z(%pn+wg3KC7hhKEn&ne03R zotfyZOa+>o2no998p^hg1ITYv_aU|TM+#Klx%~BvI^~;Qc3k1OuvH*Is6o32&;GhZ zf^ZvBahz16sWog%t6XjS3l9+V0(uJgZ&g(Q2EH4hc48fKeHsys0S~;E#_@Dp?R16r zc4)e()7H;uETV38q(xZ>!L84MQ0$h$oY(mKq}=C~0em0gO=Yj{ajxt|VfhKVe4*)Z zM;l4BRqXn^oYNDny=04c%J22W1`XdVrr2Z#|6s7myBP?Ogk=Vse1FvmU&mnic1LVx zfij`_R*I$%SjHN~5ru;}HyhPl&B_Ds6s&S$chWD|nqTYUQ5e!{zDbC!a9%h)95xuz zE$P)HwZJsA!D6Zz`?2Is(#wt3u1jO#^7g8T%W4pTr_dc8*`W^G0u-tsp61ItHx%}v4M$^f=(rqUN%2< zx(Bhw*@EPbyBv}-YUf@0&6QX*CQ`;Ly+&)iP~*^Z(c-m{%2-|4i<0E2;;GwbZ>M$L zT;or=KloMD4`~U@Zi%}(&rAj>{em<)GtD`FNPuWw!&ym|-21utr zQAr+P1hNSUgw_9yV0)hQc3ou{H7%%r7oMyMT3Ewng2gz`F+KEc)pvuWVAy+4xr~|! z|I;ae(>V%+hYjsz^ESmZrgN%=a2+soip$YE@9zqx>E)~5d(>ud1c}1mRy%GDh!@*(q~kP!tJ&Vb_6qTVuS5;PqSfUhA#PTUmnRuW|oJr4Y>2aE5ANG zZ7F;LB2Dw)JMc;=HkaG(kD1Y!w>OJK7boPu1XifDyv(NW!|ok+x)UR90+vvF(_Pi~)X#1Kw6w7< z4xO&GMYi)YWG8W)(+M5KaS33!#^H!C2be^<0Q}Zr>~W*3!TV4rL7CouD8~6|PqQqG zp`#9lXEc+c6T5f~?YD1QK}@WAvyPi~YL}Czl4fa*CPKHIhBkjHs~5V2)%!2u>(&_K zh>w-*X38^bjT?-M?&gTd9E~>N82I<^2tFMHY}C$R_LO(3#(iKY_J7AjM34c=`l=?V`nB zuXXudkk7M!tK;r3m%kQ53R@C*eI8l^qd!0j;`HaBDoN`f7?JVP$r!QOH=*j*K|KFB zV6fq&X0-i#1J}j7{|t|X5nZ`2Gr*9h9;l>#k}1$qy%LufO<`9E;p)^re7TarG$!+I z{%b!8FAqWqv5?qRVOqiU?#{C0!t7d3jrb5ZVAX%2p+;|ggEst$t_-vC)R%szRRuRP zsx{0I&wQOFv52|{?o>$Y;1ImzqHzQ#3VNJWW~lu0BADXmu~rhi9(E-6`7u35-kj3x zz5gcC19gU;rf0%9T5((&Yv=^2xpdis=1#YNad z3;4&;gHcWdtGUy?@4E=wODz#Z=+WN6ol3v2n`pO=~xOSDhwDK{jdhZ8N{ zQrT%{lXz;I4SI--zRchID83cK1!#Whqw*XEmXx$KZ$v z_WS(qy2l@hvKo*zyxx)Hiv5K=9waSr>veR|BRI3rK6I#%9*pCBE4Xsqu_jb!bjz<- z?Y1bXyW@!6HE~rxg!CLQqBh#N=7@Xrw=oHHysYPGZ zOLT_b1U9pb)!#Go_?(v-5wWk7W?zTA+}VqtYu@B^Z9S;^g;h}2HfE!P?9p7Ew?x<= zt@B-D-VV_~p`Xjns(%1}E6j#u3Retoj~ZgoY}1{*QwSX2)s-iWc88M6(xv|MBp@=7 zAKLEZw)hm%yjJO;sGIY)X^U~SJ}XIgHW z(gqi)nufxz^#ukR7B)T=CTY1SI-J8;+*aqrYQs6&!XA5S%>OHrptinN9P48ubCh^4 zl_)4=vp`0o^JTVdeJB(-0Si(6UMz&$^^B$R-<1aofk~Sm!9T#u) zhd{mRwQbBO;tlmj;bb}PZHSuL-t7f@X`C!wc#Es<&#;zgN7qBV(!qy=Ju`peHF>(N z;AM}`VINwBB{~Fs9fS8-8cE!|N7SlC?4NFYz)m(TPGx&xFc69U-;6q7CmTjOC2v^k ziZi_Zole4ewoaVKn&pV}=z)hTsxvP{QLFb&hr$R>t_bvK8ildIDVJv;06y$v*OWk zW@tTAr+eZMfF)sx^m?8Ymt67&B_ATX`=N+ZF1=Hd$ymC0{+ye~+Q5bQaH6tAv^Q}*mWwJRm3`0Xa?>h#%AJ`85)cnMRUp3%~ zbeq4-gG*Rlk&V`0tthpMzzrXbH}pacaWIQE#HXoKGaS`mNke!2Z)<(CD4oWGA*E+d zvA^{FE1bD8g;7!dP3o0X>(c0sl3dQ-o0FZ~G=FiphDy`RxnD-NhQ_ON_rQz{@O>%^ zd4{qY3{@r+^DDtzsaTj;^z`&zZW*XjTg%BCW;4xJEE82_IOH++vwxSq=-Ozp)PGZS zDiJO;9&uY}C`ohxNgMrSzb36JNVeoY+2q@$Hu#2#Xof-O5OW}`DGT9;4Z?_tJ z-$c}7Qzk9K@lr;e%8o9>a1Pdot5Qd0`+w1|u%idM>&WZ{^S?({emYb;T#njot@$`7 zu(N@DU6QOpAxSshKxsBVHv=Z7kdUMt1~a1UIa%5uOC(F&&(5DkR&LEmZFc9Yl(kJ{ zK2h8B!RQ6{0VKkF@JqHrbH+Cu2kx+>oQC8a(y|h28LkQKmvaCdH*R9&)-;Fl`-Hblaz!3KSE%al0*4C&XC?lpCTn(K5VkTEs!iqLcEc}Y5O9(fu( z0`Fq*(&ds=?nLW%xJd4-mh^{_Y3`Y-S;ZDcwnfQvj5>xUUEG=`fM9_W|gKHOBmw0MaT{MjV=lCn|qDRN4U~! zmKA}~#f1&Z@S@iS&;34#)lF4wE-onSsk>WtR?BNLm=*remmq3wE~|5!I>wWbF1wnPZ!-?F%=6FLORLCM^EezRhY#P0b{7b1 z%jHmB*d+9TFVB+Wgt4{Dzamz>ud#-~G!pAP7Up7yt@-UD19g&>f5)>xlxone`ef@# zTv9Ml-SRdg&oG?6kc6F8;DKhPo)%ue=dZ&&I>~vCG^DF)mG}I^Qt*9C>zc_YJ=Aij zbwKD0O~turA9CD!RQ8yu+2$EIh)#S8>ASCQ9snowWTRSpN0t|&$h5t|0ezzzzh+@0 zIP%NFMmk^+hSRYM4_qerN(UTz!Reu;;ulR~fe%b*w%j_=_c8QC~bzcaEtt zpGKI^nFQ#Gvx&tB*q4fYHW_l)8(FE`&Jz-}sTg_mQDfiN#vkYyMy-%Aag#t7_kZMd zdRgn%Z5Ms5o#>mvUoP~P&?D&GzU`A*`SXn}KyGfhX_Qym`Z9V-vc&VSb5S|5+C(0=1=;Us*I z;nsAz=}4Eh_;+`lUGGY#xx()e><|0$JpIbGIRe{?UocUdrijC&kas{Zo~X|EFZZmG zGga%Ik|by8F>UyzBd;n>($HDX0)Kdj;%{Z<{&o!{xbCkkQPA!Qm)`97E~bU^1`?3s zH0{SbL?~pZf2mnLuUnv;T+U8!qZU`&)zjU}{a2RjPZ`qz<IZ$Gne3K$tbs(0m z0+;oYG@5M*W)>7zzt$0S^PVyKfCRl(`r9rAFFV6S*l8QH!$T7GOPh(OFvYSDUVlB+ z;W+8O$Zk*bH_Ts}MokTcLb-Hq+(FuzE8Y~?DY}0DScitPFT@&^w@Cae5R+EL&^-|Q zQgewkoVv}p(`<2)_49%5QWA0!lO!7xh`3`_!3WZx4vJ@-aP_cXs7MTUw1qtO92~f~ z%_bfX(l!aW&{+z^X4Y~w5FuY1I{;Q3;1oPAepc38HMZDtJR8Ps@6NycXX8WQ?r!H_ zEdSr=t3Zt&FonBuWyQIlx0zQyH7Y(4x?}u+(D+PxzllgjL|q2IlgXkXSF#UC;m`*SMlIO{jtwNNU%^BCD36i z_X}ZdWrqp#v1+kFE2p-`h)H6dAUL!b85EG3?~SqngXF19LtEYi?hLQBl2HKQy0`9Q zq(I_$JZHUtxK*s@M?C_=kGxL?zE*t9hvC+|W+0s+w=iwz16$$Pf#vspwvey%8+P93 z5V!baY;>FZ#ra!IrWu>G2Lli7Ad5W%@`6iIi>`el1bUr1>VY=wEBh2S8$q@;8_z5p z!2k?Hc$)T{OBy)|OMpRpV7sP^JZC<>6GQd{T5UXzs2fIsC;0r=9wfIt&VH81ZXIPo zQ`tkq2dj&B&%^w{bN^;)NrduD!nA7TDu;1VHHepJj^B~aP18#IX1e?W$!%ZVZb9Zq z6kryRfoDjcB1;7ud32znJ9oWq1!5nw?f%77OXzKhJ zw%D|EkeZvFC$!0Y`zk zkB@7o&#u}wl4`bo2}z83h$45nlfG$Zg@h!yp1dOmzuH}wd=myPp?J=%+Tmi^r<_YJ zYohTknkemn^qcCpIgHeCPkYuhb@yACgax^!_@v&mGezxoYHQ&*>k6sWpDz7LhOl{= z-JJ^w@=`hy0~;QtB^RlZpMuv>d2@#lzc5EG)g9b@naw^a`?;YsnLvE@6=;M>A?4aw z3aCyPoH!Q@fDUwgTe7Kp#W=3{q8WKooA?nCx{bHGix^_)VuZ!gs4ETXl(f7ZRRRa; z4@qtL@3&~*;dZukjB&8m%7d>eDj6Q+g~WDiO>(K?A>WeScic{snmUi9Tv>Rcd<#4MmMAS$4mSb%8xNdlVFv zo5w9RFC%?(wC7@&LGJVdc~IQZ=89}s|2d?Sw`aC}0mf~;6tXCfR+fpZyQl2`x(A=( zV|{SJAi?56wfontC!2HkL0@hYhr?qB0c3CQIrCEQ21+YO!qRJaaw>dLz-IUgtR?|{ zwwqy<{9d4jp*yIYlJ>Ao8Mb^)ly{@C9JY#kb(oX>DuHnrSKI%=eXuJK zhU!Oo?Pkt|YZHCgZ#Jj0J?U)zdDTCYi@4VTx5@5(T;ihGJ+*;E_SXxio4dtk-br%( zL2_@xO+)I(pbKWmH2)wiml9z&LK~vTB->DtJRpsco{U@T@ksM`bmLq+bd!j=V+e-+>w$>mVd@ypAZ2kbGZ4bBqe+wLnr%RX&Sg$HhMFFAkJ zG5|r_=|Od$mbrApYPwEkC`Wbt%{q%7mFHIhDbin`WU?77L}gjc9zonBkAwGEb}9Z% z3|)n72<53r{5mcXZG8f2mY}>`i9x>Y0IE|!Yz#s-7O^iTk4}rghN?%}(aC~or{ANmfJ%_bDlNQ;|CCkJP0WBW^#9H z^D&W~IJz9EO=3DJwOECop%?$XY_dB4tfR{me-oEM7&+oV=3V#FiBLq&NBi!jH9aRM z+wkdP?+NQ5jivairCX`!#oOAdh}BKF``wxVXI)60+f#_*dEC2Wi;X$Aw#Wq0`ROGZ z+UdEqRvTEchPi0#6|T|4i=!9e?t(}Q3Y&tRU6aIO&>l;!R+CBw*soD+fmoQcYQ88D z_z07^lgAr^uZssu+C{!9h=WcQDAZy#iiu;SfTmin3FIc9)l0A)>E!r74kSM0Sc9jJ zQ0wwsJarKG0M~?@`b@c|-_=P`5YrU75Lf}@5)N&#+jH*4I51MS6)Ywe_4 z*UOgvk#LOdn*U}QpY#&+*W5m4IVtRW(=4p&wZk%_(p!NJ!fkyJ9slI#`aFk16^veFe7bmE?qxpq#-%3!%jHKO6{H5% zHz{#{U0fMd5ObXS7OZQu!kr7wnKs??lz3XwRAF2Y9pM8E&ES7dGK;J`>glh?5;cG7 z4HxHm_~fpk{>dgy zwjEOTT))$8M>-OaZ zp@GZY9-v}B9yuA4Tv)PzS*lkU64HEPp0yqyqDZeCvDrIe2Z7WiHLk6*3}51H4DNVS zy5AF`5mIeIT{b9_iBi0+HBP#DL@~PwYj_rn|M!wLC7FqQ3oe^g0%ygStHW#dQH%He znI$LrZOOiYZeNZ$!-X&?z7EDzkO{@PBPe8%m0R0#7f6GP zUsi-wfdB!X=0ILtTgK?GnP|mtP(ZW!XJwu4KELx|#JlKRn#v8K^bJ=Li-z-66Wb+s z>l?QBpT4}_s?jLrbrb#X*|{e=GSBY*tZ_lX&pr^oLV3tkPLv&Ook4G<$xLr1>ytuvt+n@Xf*~HUbQZOkpXg-#AuHGwI;B4O!E2fhKxK_YxKhWqVCqr18lFG#ev%DZM#kWi41D0 zkgvZrm(pXG)SMFTIG)ceEA%p`>Rr8ZF9@PexKzWP4MXW%NW$8Tn-tSP2d=Zka37bX zquS!0%Y~KVhMHG3AN7bdJ9gN%#*%=ur|K=#>e&78q3d<>$3Vng$Ry!l?HA(IV}^EP z3&D$Lpc?`jd{vzdst9ZEIqaFc&D7OmaKzUW7i9DCi3Yp#nE;8Aw~0MP{Q$*S`vG2jYi!l~_P7G(;uw z+Nc+IpPMtp)7{>G($d3YoONM`07q>aa(2|Fnb~n>f2n`Wgt$eIp1c*Y2Q*z}JC%P{ z!*)l}RCekqSeQeyYT*(C)ahMyz`&Yg{&9nK_6Z*8mKa}CKvO_fK;p9^KpKMXtK_n7 z^;O6Mb)I-jpem25X4vE_qO-?xEq(c2ge#nbr10S5oF43p&-;N$o(W`&zDn=m44fQL%ee{&-tk1mO*#By8m0=Tmo@eayFmINAd~fD5tA`V6-`7hH-?WRRIK86 zML1fUOmJq;Nhyr456RuVd)KL{BH$&+V0H)k7m^zDgW3PBYgCpv>F@|t96f%c)yCq8 z)O`g}p)LG1IdwDOd?t)`o4Nrj4VYktsbs5v#clE#qGPi zNZ$7RW<|v4;Xeu@5-n4N&A36?7uh%qu{f8%yO|5-f~52QqP|^$!pt7MSoAB_pmR0f zE3vDt5)k9&w40=loaklka&r z!cKo0F(S8-&GhNV>h?Ay#}ccy3k77@Ga9PGBbvTn9JjCgS$-xfz3~w<1Ose6CYCiY z7mSe(pMyOg!Mu`=&j!*iePijoXYD=8+ok;ZY5yh)ZM+nm=r74+gRCLgxbkV1!C8>f zBEdG%R`>KxNMP^LLTX+aI30n7iLJI{w6C^5{~rPTyzi|OkoTt0Wh?{4K4i<>^IiGj z3NM9FfbQY*nuf}nc~%B9y@|Esd18|I%rd7jpPg}9)$P2zc!xL@C+mFp=U@89$d`rg zSAo8y+^fe%KiDV%@8`zgX07NU+-@ewMZ_Ne7dn=woLb-n>C&Y4y%(+>(v zZ5W=vpoPzbR0B^m@8_av?(P@3;ow82$TDL!@|&WJfCo*?ZOmMD`7GEIj^I zzdz7wFE=f_jGH&MoSRN$+S}22QItzI8s4XWYO~qxd4g>@z&8l!qzpymB%oSM*w@G{aZxvmO-lK0jW^*wqWj5MX}}Ob5cLLGsoQ#-`dCXA?886*|fer>|9#A?|8ed z{HaRo20;aHE)d`rYA}gCupMN~01X98|7hr#WR%Q4wKK-l#*y0r;+fdwVW6i~7|h~V zfm!4158lS0CCwVyf>hW;^-NEtS8keNyX8J-n1j+5r zKM5s@s#<(Y+pRk{v(TKkyH|k0PE^OEF|1%1r_bMM3{%0FNp;kU==9Gu?S24b&4fKl=zfgKAqbrEsr+-Mi z587}=t>j$;T!dzH+VV~6^44$$G-W}RIpqnPY#Mt|>uP9_>eoC8#rdCA$)5BV@gtbR z9Fi&4T1iee0s{;lw-?v+fBs(!@bC8-v%Asr!BCs#S?J&s;$Dq2-^69H_}T_~_`%=q z(v{v@iQT5Q4K_zrVr0?tiFz$jUY&4t;Cfh&t60Pg_}xVGS$~Ds0-Gf2Ur)Ok+lfx9 zS5E!u^N;MT0SOV%z~5*{rmTZBO^s0zmo2JE8xvipK#-N!ClA*lUd%n?9M-ISrAlon zwrXd8I-kO^C)ArscGK2XQOmqyTjcl|OZ92l@Y|Znuou3i+n-=!F_zv<;=kHd1eL<< zx>e}TZ$0U>bUMc=b`6F43%jeOL5e_TX*qeKB)4|7he3-@i}iGzCRib8N)D-t6L7VT@?)JxeyB2!*|}V2Nf_X%(przq{#EnbmWCd+@KiO+Z;# zwDUSgUjLP0dR{867pfv+zPB~5?}ie+Cqof$@SBB89W6qH zA7ztsDL__bA9k}_NlG|HgSiMB~z|(ar;! z8y({V?GY%=;)|k|w0`BvHeOmN0gW=?&~3BolXWcE^lXOvd1`YwEG42RCBj^ykek`q5!TpjUG(+fUS zk0@1Et{uvQ3OnAn`d}b?v-#cU0{_zUuocbwbfC@NYvZcyZtUwMCBJHQ2=OoRW-d8| zj7DFP%HHZm3?Tt-H*(Dg zb#i#>AGrpDs}_lFm<;4`ei7`MTk^gq6tL-bAIypYv6nKCy+iLxQJh059vYJTfU;vu zCh}+4L{f=4$BP%pRi$7qaSvj({tKf!qe)LvNEe|zf_(Cl8>$LMYHA#>n`}TtM+6pC zzt?jXRNb6vn=t%CX1W#eZ-;uhtIQ3lkvLXBiv06`USR)6hd90Y@>Xu`>x5!^{F-A< z%TCl~mel4o(XdK;db>`0`9Cf2wkhQ~HcFbILQduT`}X?;U8)@>R!5rV&YkR;dYR11y#) zU2Bb!hi+9NOy>HJpbO>!F7N8}OIEAJ&9Z;o9VHNEYWp*2UQLwOO7!z*4XQoVRvr&T zporSo5j70}$nlitV4%sR1jPF{$^FC@)PrRSVnAH`9GzYLzZ~^%XldAoiH`<&<~lMH z)OoyBpH(L~-}c>Oh=IX9)#-G;dj-qlZ2qnuh}^6zbaQ1&#bwP`IDn%$f8sSHv>;0} z&shN+hj?6XNhb^lmyvEE6d1BM0DPfo7jOUEPWd$}1I0AQ2Cn&g1;GYRs-OKajkJ)9 z^!@e|gEJ`kSrPAPL}a`8wkmS7Adq7prr{@@gMj#Yzy|1%gscV( z62!~bF6+^q{8%s(?f^?B(b8RFEKGx3%_*CKKY=Iy0F@9r`PVRBrXVh2wXo9Fll$os zOVeRs&lsb-7m4=Xp)zJbAj1_?83)9jU%sg(BcSYhKv)(Sp_SI-V0R2_mVtJpzsPiCSEmW^z9l zmPqu+|4DB$F==r?ZMP77iEck+a(V%WW?Y7Yb#mdJ>fFxZ%D<%tXC?QO1}k|EmbG~$sG$p=D~JI7V{yv231Wjw z=KIY-%}D`uK;M=y2V4OGM;eG!puF_EDot$IgUA8>zjUX79VDkQj!Cf=A1aGO^^|J6 z=FSoRJ3NS*CLhR1DN|c`FiQ~+GjBao1vI$q!I_~ zP|ZwLP`w}1nXZ~6B$&u!e()qg)Mj~4FzQULMXu~E*c-ox%xEjuAx<+Q6BrCWqkf0|UBMA8N-5YcVB2lj)G`zQJ z8nGL|ome6+lJMKZc^~ZnixyiIJ7^3H9e_%)u)V#FL4u50IF(v?HmB-ptJ*a-$s$LG zW>-(X1Qw&a3>!~k?6!&#vAu|}&#m&Fr9s-NEd&*sa#!Wu0tKq0^pfE)4N zEwO*+F?2jl5FwHf)TWK>H-Gyu(f3{$Z?#vXiZOon{eT_)aWx|$@0Ni=i5pAJ1M=j6 z4^bWsoL5RiQ&Wfy+zVMr<@Mxb_v&xR5#3H5$G|>ZYBl+x7zDnInrCl%$-H-sy>N65 z@|kVtfkVQhQ=Ah65m3WbK;dxcJ%WjmM+DAQ~}OFji6 z)aaPxavz%Vm!mDPeHinFF7qa-yG_Be0W7rf-UWE>X?MFRS5?}3MU)MVj z^F7`q^1awMDm@!s3~u1X^nO0(?sgyX>9^MSRfceSzX$p%+kT1IzieV!PuJbp`!1d~ zvdxtBjGg*K#pif-(3<1~|B0Wk0fs(??BK6JO6FB&%~kJ*+DtAggfRHTp;i0SaNdWBk9%S{ycsCIKx*L=gRM@ zCFlY@51m|&oB5%8HkK;Z&f``Xb4CT1m7~v$WrxBAIZ$5%CWD`T0|Wd}*s#uLvXTIA z-}$4QqG?sR##u~&o6Q`y#sk)dpAG9ouq-(mGdN&B|Jq{+bn4#IHm@rxeWFb8270fp zRfkg+q?@Xui%Hdj(I|^>eb@>nDSwqb?sXMle!dS8Wa9N+ctk64aY5Aj?V!>m$cwUB zc&r}VtO3#@RT8#3>Ulr%adl;cXkIPc$19cU`#Ggoq+qZJU8fN7YL0h~ z=3n39L_jn<_Y@8h%<-RwDo*wQFB^vT+6KR*Y*4y0tquU=5(7ZKpH&QM<*~gjxf8YK zDMLRJs+ICChC%DWu`BLRZ|p2`DxoA@AOCI{w?&+}X~8RkG|o#Z(NFCe3XXKlUE=!E zOLAVfVuOYA2L#MNrpSrQxjVhhDu1DVf7n zN-J(iRuxf?vQ@<&Zc56x$2zN5efKWyrN<+Ob9ZD^&M*4J_czIYUB}8pOEkyNVcM+| zy{!M{GFM(%svP`@kPO}RUQOV2|K9y%lTdO$aPf*?a)44_z7vZ=Ie+JcK_45%`;kW^ zu?JpT8ss6U{n`iEG+Ro+!08W5c9oFI$w-acJs5hK<{b(^J9DUsnr{=NxII(&)A3}7 zp_34bZ$J~B@+U&Hl5BDDstiZ#`x)H}?-WRx_5Rw!aKN12hTZOAn`cxAD>noPEMAt~ zb=I}Y9*f4{M6LGc|M22idB_`;`!fZBXNS7P5{KW!C7>gpca=_T2b%(52?II=STlG$ z|0S_>3`09&H(#8OJ=uBg@(~f*Bh!q z37!M<)GJ9L%YCi)EjK!mOjhw#tA?ej=kQi$_L3c3_JdcR$aB8sG_%>iKbbA}x4+Fg z?Are=^pwnd^w)oV-Fi}e;G}J6z!4nW{LNa?_G`Juos7CfvFZJa*xy>ZYP~>hRi({w zQatDdSZ@g*94Pc#Ui;4Tt_*RQ%366>v#d?n;24>1&#lv^PWF!rW}!HmqaoJ#M?AgC z|3}kRhE>@$UAjX+x=}z{xh^jdXhe>5}g5E@^~spXa?kfAYus z+GqBjwbrbexj+~S(2elCdl0W~tNa`CRMn%lqQ_3Zp`a>2u5*w%fUuwDY_lc@+I8C^#=zsk zTfw*O=e`RXo@`6zC7F*-%?7oA)XqZvTzjjOV7Xa1EF9 z=<_cOxL;f48yR>2KbZ+|Uz7pkHG&7i4x-c>DOge3u=S?fV8=}%r3|9+QDywwqNH#p zbFVFR1nn{Hm(VnKkEUU!(Z-I|mXxP9Wr|(ghX#oTHAX6mycL9#-bOUDqE2yF%)%tW zbjtR-?~F$ybm9+RW125nbG67fb%Jp51cI4S1qopTodlm95fa8ZRE0eBb%w~u;I?KZ z=E??)1dkycqd1_dplB5<0ytVCvEw!nCnubjpl|Ko)2E=m$@6AXw&)U%m~xYK?(L?z zh~?>M&He0Y^-^8W#>dW)DrmRXPPt`SroQI;qpVc{ZruTU-4IlLdny~oMMHDM_KTCH z)|7yv9$hFe(g><|iLl^*#isM>i99f-Ev|bQ)C8{m3nwYN!HcvW6{*L?zj}g{Me`r2 zcRSh0Nntb5+tz%$;D}Oh)+9DHt-y&x&Gx$DorlujnFB{oGL%*ox%j2RUOm zB?8zjuN@v< z-mb`A_#hnN(CHzzrnoLP5`N#v^}BW0q*(i3h9-zxuWwUX$*OeKjVTFGGiW(*$Mtrq z<+!eyLy1;#Rt-#;ZU|pS~{9c3TdZ70#PnoMN;*%BDb=k|5tPez0bjG4dZ0Qp@ zMhB%xS0fNb0)Y}Ox7&V18Ifg5HSY`c&#l*pp_8<2lPh-^&HoL$jCHcPEX$)dkpc{ zhG&6ESL5Z+4-&gs75nr+KbHOXgppNDu~|w<@#&hh#%1Hf+l+0UZx!ySeV$~V4|g1| zFUS3!f-S^0DcSRS-tHkuWodD}vLad|njKpn{iPgpacMkjMzl6T~ zy^S)p4U9+vQQC^#=tu@UeW{?9>QM4~?}!y^$RHy`5JV6)_lEr&WDeUX$$FJV@6{=Z~ zSKxG_uo(`8l-l3$(PKTd=f=h}S>@1~#O!#OoC0q>0E;0mpN7fY;lP z56&I0!vr7zW=oe15Du6@kV?A)Iz&XuucUD5lE?VgbrL|w66QYFwiyP-*SXr4VB>qI zXw;;tnSZtDAK4jlx-v(98sv5mJJIArKUEiLevni#4UcH;2KY7|>qq#q=5S`)@>=pg z{o9bI*R~79KWJC(#Xr9-axQ)w3HRA(O@Xg@2W0k-V4h@iVVsq#m>kv2TyAw8reeT| z%Pevk>Ilm8|2$68dGkY>BH!rkW8y52TzHs&KjW=>MzDLl;cT_kRLb2Ue*7<`HSu62 z^Dv0gjFPefhj;nxsm5bR!X;xTbLW?;<$L$b-~<}EKz{nOsQ+!e7@UN4DP!|}X9KnguB87f(kRewe{47cpdy)tw?%$U97PMSWP!q-RY(_1z; zniUC2G3^;CF69*)EzG1138(+4Dt;#*{Kw=?{OTB=~9FQ z6#5g7^?=qHu8ct=HcyM#RM(r2VR`PMzv+>!-x2Po7f0HgzNDa~7_Y8dra8+(p*m?1 zJvFYpBo8E`#BH>k_38;?Og1vrX%bUxWFU;Y7t?Vk#h~J@#ol;IC!JnX)LgppK_M`f% zjp*x0z))duOx(2rR_c6K-vJ|G9lYLeB}-L<>4?wMWpTTIfCGZxOz%4VA{SMHtW7AX7eGlxT@#K(vHdOQ`6{msC83n%Q}t+ zBa`am_J@PpiYhS+LyJi2^2k$Hk`qLRfd}T$6H8Z^_#Hmf*;;ZFD%WoTluig<=oEc- z&UhU%7q30#YSQtWxsdujuv=?Q|G{R91<{$IkdxhrZaDc>&q5|uPX)b>2j%4*nT=%| zrVCM#Ih+6W>l4aR9xKnYxfUG)sOlucjYtpMo3<}I`r&4kik`3cog61u&u#>2+8ln* z`2Nuzay3-j+E@m@JS2;@JaQ^z*kCp-dz)8u8X9b?UZAbY!DgPzU7qt*ZjEPjtd;w+ zLe`XE1(Sm%`bf`DyV z->}Pyb(1K2v_+9OkL@=>RU)6~AK}L#i$i%mo?p+d+Z9d=7Mgk_eVNf333Y-PSr2#( zzukdnxm1Yp(&$?zorc(8ji50cox8j<_^n=RPE0TVoH}7p{oGDSG9jc777u;pn4!vK zTqyf2w6(bhC)QQB6RM9Y7lF@-F7q=E`yI>WGHN#DC(fV9(Z(5JD!Y>(TznmctgDtL zQG``ZJNxfSB`px;-LW~i2cJB4@r>^5S&!T`sqW~-@$6Rh5F8p}V?G$@_P7^p{qn56 z0Wl4thdj%)L?~u2mUFA z7y3eaKq(J8=<{S^FQ2v`ReS-N|D6CY0nhMofYwu)!^b7j9k@nSVy$FhP0hc41CP*i zHW}`m$bLwH*@M>Uyq$m&GkmfhCqRGf{(|aW)KAwv_jxA8{QqY8 zN-rCrdPcR{9T~lu%RnY5!VE8L2|N05&W~h-F#oZ}0ZgJG@*ZcU-{z{WmD*kp+~h=g z?Jc;rD`fMbF2jeRA}5Y@ozgn!q+idj8lpNmyj-VlZFZa-;S993c4~Oi!-K!q3;Hcm`@3X)pBV zr8ei0=Y%gG{7_ya&^Sl$Or(n6?=c>>`|?_uVp3z-F5^~R!i6<$gnq1J zq&wFt{h14G@Fy-Puva(KfPImEhzO-O`Kiizn~;<{$m&>KO4X6}(^3~}$+hweHFagn)^7LhuypR<@LjMb1P1>{<{U|I277>rbOu?H#&lAaX+OF}Fr7U2Eey z1@GIPh`J_FFPJD$vk~UP>~AA)JBi~CBW3)w`j0DGjhP>jf{0WCdf!&- zoFaeKs2>}(rf=L%{S1lHk)_<|sT#N@IHd}z%U{w|+_C{*6wWs@R<0`@4v7+igOCdp z9lzqUa3eC{FLk9peOVPDatfXluH6ZF&Gh`|6y|siXK`!nY6!V(_BaHqB{&?;ntg)JpyWHsA6~;z2 ztDmo=(JB*%gWDrnR7P7={@t{r-x6mK{>)lwUO;kkQ8k106Sv(UqcbUo43po}KKJ3` zUE(DKGlH>wb6A5f-PuZQi;=T}{pd~|26n-}rmFnMQXo4xxXYda5QRfp6#|)9IDuyf zNNWZMl;_F)K~#yFoxO`c2EVtrAEFh>H}|UJCh6UQZ4t_c6BYTDC-~io)H3HUADwa4 zMIv6X%-n8vY<#m^m+0%|teBiv2i#f9p)>qM zg$gXNj-wNj$r`?8y%o#UaAG#pN6?(u26ZV9xCJ1RVnlxcOph@gMIV8VMInR!g1nn8zJAyw! zqowE3XD=k6jyh0El9_nzM5ZPBxpU)0&|XcaVE{8qzHMc1LjdCq_IfPyR{v@_cnO^I z?AZfGsh0>_!4o7}$7;BzcR^CneHZ&0_L@cQIEgVSltN2%p8fr_@WRh#=<1R2>LyQ0 z=vT-mpRX^)l(q>5h?6h!mbnvTAXE9RrxB>-Q!$p4Jx$}xkP!s2=${pnwle>ve+;3c zF~xE^joHBoky9)$nZm1WR&)!uWa;bS0HRZ#Q!vYRKr0ex4x542|5$v{(l)npG9=C`;Yd6Kbjti9ZRib{u=9luf+ zCp-TmenF1jG%V@RHLH}>uiGOW!r$fwGQUPf*ac~}SQ`!O=}IZ#^NPLrVDdCsE9kB$ z2*3y=$X?qcX9>XoBeE2vfAd&Jh=pyX)}fS(gAin%)}E5~(po}g3XYjzb{C~HN9Ik; z;PjmsR%7E^E^s1NUwLdZ77vO=A|qor#5VG4J7&mSAscE5xyC=Px8kxM;(rm27NXtI za@VVkYq(%Ifk*WDN5jogvEngoeQ6BOy)dEND zHZTNywoJ=Ej8OE_R>?xb=I`YqH0t>>e)rTri!S?aI(;H*eL zg!#HEw%aMt{>8!VejKBhOY8VO&5rnEBDJxP=#1yh9?hmJNxFYks2G-kg&nxOCura$ywz?GI|IPk!cd|ORcTos(}>o z$3YRE^Y^xYn@RmH5!>sxnH?(L-A0l&cnnTy4R~(VJrFN(f{WxWjBNNA+&28{4Y<}! zom+OvBHQN_f8M1eMsUF^ezch<3Lx&||1BCw1s@UGx5`!So&RyiJb7KXSAKk>@yAeS z8Nw8L;64dq&GPV>Pg`%iqO*FC`3H{7TStO!S*DFFCN15NC_7WjLyUILmIxmi-_~m| z24lFvMan*q8ng5v6xkr=KaaLcwAYF?bhwpZv^*p1ZYPL+z~rwElZ|^zGLq$XRvqGMdR_} z;ML*AHLJ*9$6|$+*y@%leis_g@MeV@djsBUD^i41J%e z1HLBnq!iQJI~k7b@IE-j04X32UA)mZ)DQ#TQCw`TPvh6Mif1D3eGg{;qkIl1=Tn4l z#3E+HZ@;6KSYeC)9tB_2{m)m4eE>uGos{%Fa>OMa{u5jSf;J)nOl!r9d%sR=oxq1f(CdoazxVgq^v}4uFH@W) zqPQ*J z@EI{hCwNo`>VcR(HdqO+c$Yvqh?dJXL9NhFp?#W4flW7K)Y@K>V-aA$T)CiW~w7Nx3TnvCDfxnHnmv+9?n7GK&>FxXHt zL`Sb1v_MhtV?40dva#oWk%YdC{*Z&b7~qUsD75tqVZ1*)};V&b)!D`G#r z>>Shs`8sHtp$G_2DxA$h(d3Lqjem|doBpMp3NAow8MJ!dQLhA}FG%x!(6%p>M$D{# z&y0u48unoRa_Q6i_i^xM%D@`_7uA=CD$;b(cZ$L!?w`T?A$U)5w7E%mVRdV?c6{^- zEDsP(iPIih1nG&iSaCqnB3uDbvw3LgrX%IyR4W)QgW}#%L7wsVlH%`8qw=(n0{&y5um7FaGl0-stE8Rzkg4fR$#Jfm-o8a5(4 zeIEQSwaFoTXtyLiNmMclUZxqdY)asAtLQUk&gv&vP#afggCRk^X`6s|Ak+Yjp5MX^ z2jxF5|J>RlkRLf|kXoTsNZYXWcdC z%SnInS5t@S9*H&%juH($*v48*dq*jr*0hX&ZGKuNn7*wgrS6`U>^J^2w@kbL3S*Y2n#FeF(P`9Ob*wIfuj zS9KYfVwpq+u>PT!RoQe*;(A(*bVTLY-XZ;^Jn883As;<4vzCaP^c|y(xfLP1C?izC zle92 ze9fxpG%UD2?Tc?5ORv_5LcSttZys;MftblyjiL2$;_mgjiC1w_P;Ps$Ve;?tM15@6 zl)OXAbAY2JX7xxnNo~xG<0y`M!^qiAgt3 z&R8wz0mrR5QQ$rfrzW%GpPI(^%d9jTl;s}as)8YvD#HY@m-i;VUYCD8KHCFlMfarx z)l2zk!ksZqcf=2$Me7tYtF-O)l4uII?z2B7%O&HCSyR)Eq~%i_f4go?b#Gj;XeFBV zJPNn{_Ow3HX2>J{_ty-%Au}i+@emA_Jb|wWSw5Zvf?ajElC8isS)sR^cj3mCOf@8Tz zl{2eul&Efu8CkE9e!IVc*~I77Tc+6Lb4>rZ;3#VA`tRd!ww zKu?;EG;R+Y>cM*S$bHYTB{pGkU>p zjZwR1-4fY5k$UfknU1(}k-g6GYhj_l!`aIsG6sp(L&vD%Q+47_$QmKo4HOqYLaF-s zpX=&)+AvN&-Vgj<3>M5B*yWN`@PmnCY`e~!#1)geY}49 z#Cm&|*gd_V_Ut7JqQ)s%40E2^(;mkEDJC5TFh0A3*AJ!Psoi%#zU0Rg!4Zk97DSEa z5<*o1Jc!7%O4x~b3bx+mvwqRRx6kr|At$V{Lnm|&CyW=?5)3EqcIRX^F9_bXSlIfw zF;_0$9&$rAUXA_S*{l7O#ND^o;WPR}(d(7%g-5ODRm@M7%7wGj6E9cN6g{Xow#~yR z(jwM7CR>;tMvn93zVP#Ds&>IPvob262UcOYtr!pjPY0XkYg>L@LvX3zXig*_&hB5w zolM<|LdpKST!__IM`CiXhA+OjXl+oqPz}6}XDH+XhTk9gfUz~^yh8}1ppkHAiZTe41v{o_SKeKtuX?X)z*t*o zpZ*1vL3qq|-*~?1=9V7Xi*)oE!`|7x&3?O)a}le->rEwMoIehfbkQ;E12-gt2qIOn z^*633H!TX8hT^|g;*A<|>%+#JGROmCagpAOIl%MZRig-wO(=oUO7}b#x5UkCmwu+J z?iAAI!5kOD0kZzUx!M658vWDK>g{^9ei6^&K;U#Ds$qi1Yohklne@qOZx))AwPYNE zZdU=WaJ=ARle)_gZ958Xja(3)tVXZcm$vKS z_`yFhv{v5Gmze^*V`MHjZqeAN++3S2Ao%sdxxYsWPKzE>MnH>l1H4nH{1q10*<#c8 zG>p($<;9OZ9C}cDOFOv0aYLf_B>)3@x7i7piRJctIe&|e2`yW+&p|$fqe8k;RX+Ha zEJ0X=i82G&jS228LyIb61guq$^h;f(Hhyf`v_c=jOSWn^^qq;oj8ocoGo~QSS$CHn z{?P?xpdjgnJ5qe-zD5|HHo_-PI&4ZpEnO`ox1Qv$>5_bmvB|77@|E{nMq0i?ecXo= zqx=GS3Zp5MDF>lZ+%(u9)2s6s$3-cNOebxg?||t89DPBV1KSiPAjqA7&N}~dN?f*G zdxve4-tH2h43PM1Y()*3x&ydQoU9A=_3CI)M`WtPSclOasP#uAlF2sHjAK^#id*9-?Cv=*>VfrIT5gngW)kZjrP^Jl!=|eMq;=A1B$&ZW8 z4~wu$#@1lGNWoJv7?I1LUT72KkV#%mlieKxLmSxK5NozDUD86D%DVs6#DMxBmI?&-aN!6CZMTrfep$5AYM^SzzR{yfFb|r}MnrLulaqUoz=vUTN zQBn~yrA%z*<08r#e|vUW8ug z`Yp~I6w=?6)guV<7c}bkaMsq;vO>|Gyo+ybf&$Ip3Bg9UfNVCX;Fn(FWH+(2Fu6N={aq!nv1rwe(%U@M7EeQr)rwM_= zm*H>+yb1X!1_%@kaGS!4ts^|_E-T?;5Kj==HG7Rgn0VBxT6JhklD4}?zO;9{-e!fv zq@|#(@`rjuDvVBp-ujgo9G#`?zT`Hi7s1Bb_3U-XK6{4lckf!cp!x5kTx<%{V_xv0 z1N=&eGn3cbWDOKS_ak6Eavc$dn-EI}d77&s3Hkg>C1ZdY_zD~hH|!MH(gSR0{^mVw z?LnftmmOb^D*{CSRV-0ON}nUkr%9JdpIrzLsfOyVfwgV10T!1Gdu&axMw&K&1Gwyt-~p zJS{H6`;fx}QUZJehy&ydxhQH?H=cb!sUZ_uqBAI}3q8>5)J4SSw84cb8`)}J9OW6}XL-cvQ#<_E|vhh?LaOZ#44i#kz@W`1LdE)9S5%J0y zyo*KnPE{6&{K46S|1W8Kjof0|3!B3iD%(yLi_bcw*158jgdge@J*&n(Y-74kUu17q zWMAc)kvFyTb=ZG_;BS<`+2lji%2EUYLvw6*yCeQIauQKC-NZ=e;s6kGHqw={a(ewC zITyG`m0g>4B`e4fl2mD6&cb6_S#Kzub6}}6nZa&&He}T}Lg#G8q28<(8!3(ZA|0)l z!|Y|zSdCMm_+`3lR@Sl4T}D}H{~+eQM{YX4J~&&Q@j zfDjv-QUpY!FSZsge6@-AycmJf;W_@hf_OGV>+v_9mIg~qI-c4QbavhjuI zo|5%s@FvgL6&seHcH-et0bJfGEGRE$CshGIUjy3gTdG3{wNuRqSlG%$Xgt8jGCSu7 zswwFqVM6!)7#F+0CEVF0>@%v=3d_3a?Z@*;g)lh?i-t~+sa&D0X44iTe=;^s{LGf4 z|K`&AMNy;oHqn-Wj;d36%-J%*M!;u#c;=d2Rh32F4vONDszpFuH%T*V_M_MGkuRSC zwE{-47+3PHf$+DA|886dw1?%o`M722R2|f9KKA1qxF$C?#mp8W&t3LPH3pd2Vb}%$pu~0T} z1kT5@)pgF|yIos}RSX>+a+WQE=aK!ZAXkM01EM(YZfGfZjYq)UpQP_n3{VO4&jjr- zmr&GzW|*Kajgpwpsmr69M$tvM9Vd@=Ify39uZCUvr45TN^T0mfC7u1yGqxkTXe$NM z&A-bDI?(SXk*F+Y5c_LPk(q<+jpC;X{rPoo5pj}tH`bUpRFTdKB&$47k84=F5W?cF z%9CV@6|DHk4ebJDj9hR;1w(DL{Ji#5si;&ZzR|e@&w$EIXLLW`ADqEK1^McM9*xj; zLKHejTQxel#$amRp-3m@u0akW{B)t;TnRltASD%6+0bS+!7z)AH)?qfUgy30#p}slGu9`7SFl2!dm@7ole%*mKO$8= z*vwZ07=cxV-AI@U#{hF-X<%5e8kK$)x}QAq@9oBp_lzr(t9*Fh^K%~QgAV=f7OA~s zwPT9M4J)lZH6y45GJa#yGR{0%yUH?KK5KS;=pQ|<^+Q^1U*=nXTshM!uHr0nNe^Dc zLu&2aaXr$obol`aK5{2J>`P5%OxL#0biWCPUJn+$pyT>WQAItA(<;Dguk0T7>JJm+ zZzwl(2?(UiXp@s*m4b%nZ4mW|;?$-HG|$A!krb50tP=_@8ar!Q{P*=b6*5bZ|9$q~ z;4-L{UQDHRpk$D@>{qyxE8fFDj!s{s^q3usL4jBd=<}Kz=8yDtk!8PF)p}*sq-R(P zkTJKoh}Ycb8sfOgw;)@>MQoz$Unii7ynWZK zb@i3Kf4*!BPyEylk4PzB!SKTATLgG&6b41X?WArdy6TeaHGUR}Qo$d6duDH&GC(_o z|4aaCfTOCizLX(dPNa(9QrP_Tg8wywZ9oYujuonI-t%&J9bEigo9~sM50Nu0B@x!u zMP_i!;i}J4&=GYOx;7tj(!+HdoMJ!DU-FE4so$C6CM|d(xQ$OmYtdWDF?ZI^)9I`% z&{?U|hx&T?tx-k28^^c(PG-95!0V-B_xAySYQ;5t7B)m^SI#QpEoF}*NE~Bg1Ze|x zJD{+CaCW2=G$iFcSGfCH>D89LSVO4JpI+mfDj=k!m3UF#9_$3+elaz+-0t6a_?tUL z!Zz#U6@6Ni;cwksfPEazp(3O!TpKKV8h!&Lq7N;;qFK~=orUN(IUVLqGlom8bcT6= zouB&F9tQO$TiJSpD$(*I6l^rx@i*L**J~*(VAD$JL&tC%_{Igi&8Ysw{>jbYw^FD& z2B{O@_CfH(eF85-5n&PPYvzwle+&DeN`4fleQ;;pM zfj~z9&sL1#z!MeH;lmX2!JcaMKiu~SCkT!1GX4wxE`3*Q{t`L^a1boaKUs9lbO&OsI zsfr}J!-f|tN5@%20R&7bv*7cIUiopl`$2c2W(Te9N&fggwNf8iPIT@SiEC!Zy7guc z0A)@>JVC)M%h5q$z zGJh4MXYT1ZstBFfMAxkWCDutc7Y1aZErV#p6_j>l15`WM$RWA!DIMMz^i~z&BIcaB zwqJP+I|ZT})4tauc*&}?sz_>Bl_ueG)G5x6SRZXf!m$A2k)qmM z#D2Mt@5K#*Syx$EzaA7IGFu-nqo6O7^N%3I54vUtx(j`@BTCJ1BzxL@60B=g^I?bDd$bY1=MHBf>g z^YT_?a9-sUjDBY8-X@q%L9qLV(fWpcDNnm&Wa`KuWqrO^&hTA^Yzkjsl;d|TV<}!V zp9$uaHDOGzruk{#_?u@Hy~05iLy|KS{ap3=oYyyBj#N7(Imn$>#4jb(EbQ&E8}y)7 z0Snj_a5jmYeZ@*(H)ix6w0JN}R#oopU8~7p$a=B3z=j1PUL3(Zv`Hkp$r1}FhZW}*QT%FqO-<-4MNau2;e@Aip>QtaA$4*6%7@Qg#_+5Q~ zE=4elv#6A{L|S469?wwj4{-#HQpv07vT_@O8KW3~3gAk}(WVW1<=hX==jNvl5VEaY zEIIqvCFYM1Us_PSq@okK(Cu7eUsLt_5Yslg|r zIp)WU)B)LwR@NYZ`gdN1#bEyVMHQ%S_t&N5()}Hq&XQN+C}NwgPgb6&;^LxeJg=fh zmKQD)X{9;(^(Q@%KSt{&;$+oFitX$8d>fv>-ruN4DnfK+%RzZmLxWj@MXI$&@XRKO zuuz_{H^0rgfC2D(I!A3KqmnC!)rB`D>~RhFMVOlqC1rg~PrOEIPtvL1pnO4ho|<&{ zmZJPg`@5=W9^T%%(U0Aa&eeil>ScWLBwFb9NuwGd_*|tiE64R9VFF^|FIbjfGs5^3 zy`aMF88RYk8p+^yl=WRAk3Q&R_S2!RgRI$fLx$iw}-| zI%v-^NB+3b&p@_~eF65QXqFS=>5{ra`9M!pY_;GP>ST5+Q6)1M>mjC1qlkQC56re~Yc|w&DQo(@q0wz`7=;wJH3vx4Ra-acSFg_~ zpc6NjX44mHN5)Hg<<)V6Ll<2VP+Zf+KbcR-u6@kun$j2|#Cli3?C-grW1TM9DGP6m zj((yxJ~}%qp#M1fpyx;y+P7~FH;RA@S1H+VG?Ub>o})RkFj-3v*or7rbhBe*5c~yP zRGEY0?^f)_itVVG-GJ z9AkGTA7AHe-utoWC%4>60~c&_2S&{y5)~BiD#u>rz9}>)VgM$=Bj~+4Y$)yX6ZpWZJqpw1wGATc zi)YT$P{JSDh-kg&GSh09EMH39%W9qj+p;w^@U*0WZ4aJg%V+Um!Oq;~&zE$^+Gfl5 z)_hY8H%dAiDX%Mdz@4OdPgEHC_o5xr1L@7)@}Wa)X7`dZsd>Y~uw2zpfRZ2j7mQR3 zYyGk5n^cyB`CU|KE6{D_hk(kXR(I~w%E1pHWpuAGb@K5M&zkGfZgWExUs_Yruu12P zN?EY+eG;6CLuV!`8(BL>@k|Jwv1V(R%-{`Iuf9eQ$XTOoG59Usocc6q`nw_#t!L1Arn6Bho(mNw}|x( z#!+)Xnk~rbOhkqR`s??VrX*h6wsLiYLgEE6GM7ao5&35p37`6P-oZx$`j2n(A}s@Y z14072_HmljK%PPdw6DReR9pp2JSJMjSY>|K3FKxBN!&%nw-b{D=wp zl(?|8$vjkkI7yv>Ww&qo00~}u7y-TY%ClV#wTt9`MjIN^12!B^;?Gb5F$R7)UN3=BnQ2{LupsOqsfST!Pqv zWN{uMM?#B~4W8@z=s=l^l=Yj_*RrT?5BAtdt%fPd*9ZiO?$j`pylHx3THO}kZgECz~zcsxb zKSD|=EIFNsOdH<%82{ia{WG~>$xa_ZB>$u9x!H&3Z!Fk|qVaX8HnDWRLBCm`>-q$E z0{fdQqxEB9K6&nPmjp9pLgr?mvfZZU-^ZRnEAu10f}tDx(sSQP_f4PC6t0Mx$il$T z=WFq;cIvixN5 z{w4zY$W26VyJ$gn_af(iFWTmrZn$$M)^#7)`b0YU^X#BV#i(B{U*%&xf`m#;)AN-q z#w@=~6(5c*p9Nm%>v?vIY~xk2?DN&p<73s>i$U?t(mHwe%E$|O%o}!Y_6vIIz-Hgj zzS|*Q6(jBk>$wkfh_+q@mfw$4d~fR;22IlnOMv;+bu~N`Yb4Pe$Md--g}3pNEQ(?d zdu#+JVEP{sMiCYQy3zu}Lgmyghns1!`+t7A8KIN+DM(+^@lO~ndEFege_K)$*_2rUUyTlaDjTqwVQ)(*&qhndA$KKKVfr9i#7YH^r1~cTj zSpvt!yc{rbZc@0?s%D{Yi}qBMsT`JvtsVV-nz)W)RVDYkIX*CEe4Me*Vx%q| zSbiP{PYmmxfv0%auh*nAu$ve$&Gw;%*z;K`b}VPW3UPxWyD~z-tNe9RD^XlR!|!8v2?-_AiaFmg#XswN4yDeP=z7@i z@JLnAtI}H~Hzzjl-NFr?BMVvN^Yn2G@gt`D>#M_R411N}%}~B~GkS*Gh&7YN=s?M= zate;p8M|)ma+0<2=Hibq#46xs7PEFE*IbNk?hO`A5rGw6W$pY!3eCoCm^0aDK`W8; z*J7ma8Ydz>ObpgO-o!V61n!H<%xOSFSXsax~_(7Q!FVKku4%rsRB83g$Bp z+%VWo39Y?F&V{8`%JJKoz27wg)G5a=&-fIyRyxa6Z)N_hb!WFO5Z#T%{(6Y56yDgj zNmA8;hWM+WyVT{Ae=0Z#?o&H+bnz3|xqgdcO|_D#sQVKoKXY11_@9qa5E$HJN4NTR zRctlC*xI&K(VYHcjEXKN;5PnkV2T}%i4m+2;PTppWV{H${aBDkt=iF1ycy z$zkvHQBx+5Fsj^V$+=Iq7$UXRIJkv)Phu2nzl_B@On;HpZ28RTlwU|--q5^;|B}e5 z)o54AiATEF^oIZb0Q=tN$LD)nVf!hJw)@A;#;;$@VlLqbA1o z;!x3W=q{+GfbLM4!m?VKYe{$BTi?tR*d_rvaV94LXz$bp;0;1G-Tm9O%#-{uD<{YH zi8JYM?D+0BHz8CxLvrKl1i{NJGqH`}+J62A+T-R6>+}PwAere?cFdcXJr)+CCzpTU znLF(;CHsBHujLX6Hx48c9^)CjRuZ3khYhwuHsro-zg%jAN`Ty-l=r5vtjGa*SF*23jA>%I0^BDITKhV2UY!SlQIlNx~F`4n?HFN z>_-XsaS0l%21qx{jKV7;&lKDeEB__*+R6T!hnZisBbA(jf)@kMNF&n~+8)(oHS-d$ z|8C8AUWQ^t1zOo=+38$gO8#msZe9ovE#pC@K&E0;jn>OZ<1@6kcnfYp>6XALiP!D? zV1Vr(SJ>?&$Tb*ceSRq7v2%m9BBrt^Bn`09+3qX?$((e4dzPLKeHEtY7VH{qvu1X; zNgvJhJJAc_iFl$;MIpT)7t~4LOkX2e@GQGl_BzE}ZvFXFXoONCnEI#xwTT_PP2%NQ z{?+Dlri~+;TVk?KF4hDGzioG=%cYGOU3-WAg^(_A(Fk?<~F!Ma~28dBFulUM%o?79Dq#h>uX6`!7E#P z%B;QvS7A4H?1WF=mb`y6^?M4v-eVqeq3QRb_kN5>o0i0I6s9JEW~yZ*r5vDcmYo}P zC1_KgQkmV#nwwZz6lU%%3&g#eYp@<7W$S!6XP7H4$Rw#03I)wY%r7`}@6o_uiq>jD z3tqq@v@{7kqaW;}Sp2Wy++i&de|7e*_7ZC@Rx`U8u`?nt&TnREip-|anI)V8cJ!`) zMUv+Ylg9799x2>n(H3qF9{Bw}a#F@iRNixQ@QIk?GM6ppDGnFG(?e&?%AXppC+GFr zDW+gyctgy$&C0L_hghu^Y2jrhD^DU2*wcrY~ifnml=*AD2Ce+VMVsPP5 zpKm5kfnj`QY5%KyNJ0OBmALuP_iu`pfi#%Ktbe2@c(2gEmdjAAdTQA%P)5|boAj=i zBcEy-jbqbpPy^s+T@ks$&##`E2HsT=1v#;G+z>`aI_41|i5Sa!uBldi;z&RLb8<&h z^qSP0y&={ZdD*r{hiPz(DM&NVDW#eF@r~5GuNIFF1^0G(w0emtIdv9M-cp|mwjb%} z{!JrfA-Cg*fD#RxdsrD!Qbp4HDUi?7AIhT~<7pVEIncGb)~AV$Ye^~C2KCSc2ci(d;)HEYj}3D85DM$Ed7PoEQ%RRrTbN zr)1Z3F3S@^+z9mE!rCZF@QX`iWL9kT?yVHp{`m|RLfEy1>+kbt0ld|i707v6(9 z2B{O$4Fh<-Q3Kw=1`>#x8=VEYR3=h@iyb@@R-JEp*z}S1-Ly$AdGXh}3oJKpCsLpm zjCA_WA4%m^XjV{sH^CxbkaUL-T*k@EG;ev6k2v=sL_cRGuwWKW`21P|IlaU z&zophmOXo+L~r|6>sHKVTlQNTxb~}C*WWCz)9Ea1*U`bUc|DJetfA?5uyZZ01>+N1 z{2hzU%l`&)3FR|_s}Jkfqr?5QjAn;44O3jCH$}dYuAaX2N)RXMmf?6oVW`N4wsMCo zdD4-81KQ$$MSQxaDYhlr*%7P^QVWVxL}REl$>WmD*B4?x%W{M_KI5$X`-3v(DT_bb zGzq<;!GH9_B0{7_Cox$oLIzzacfE>1gNk`T7*@C4-e29|%(JJ@WRX^uis@{&ll?RW zC?%nNIZ7Q@h`8_z0fO#fe*+OR#}yeBW|wgdl#Mz+NyBVGqU!aM$y8l``*x60*7SNq z6Hu00Olz4ax_a32wMg^NlL2+lew!D88b)?6|AQ1zznL@aeYF)yi=)d)(3$cr6Y|;% zn*Y$h?woZq>sM7KyK#H&6nVn8@d+T@$gye*pNyd@yg0%}i!A3Sk%en%6nh)}2mIQ? zv_kw^;O8`nZZ$v3g?1EMw>dJjff0P;z)!jDp9?BlvH@POO(1_GZDx|M|5!ZZmm|9m zi-?D}CM;5VHrZ2z)S;iHw@u+jmKV_yws7CPWi!b0Nv3Mdw%DODZtN#^Bob{vK<|VT z>GfUW5%oRp^x^x2PGDM;x#2B6^@>zf)cvF(p%T~NBd>w3N2(CaDv^#mz}>rAOjql5 zJNE_0YJ}hC0?(j#K7^jleF!S`9|L~N zohQcjroj`95xu7(M~^b!<|_HAP4z|fG~T*7Q3%TnZIRu}RFH?BvfG5Q<2PGR9v(k) z9qjv{xSGIWsUWGa6zVe^tCf~tjMXww|DjdQrh8Rktn=y1i^HX;_${+7>`~1B zqv29PE1QwAHM7jk8Sz4q!q(Qn{LLcd+6j(w*x{;0*70Csb?o|nC1nGKb z{r%ssyXTylx%0YXX1eD+-A;>dx7!4L!sAWBBBsLf!o_?2BQ_pFM0JAYV-+@;nr!vl zFThV{#M+z-nG@w z+Z;avlm=?BE}~qBlU21nHb~@2FDkl~I%;e33;&A)k&30j%)$?7(3rK4yOmbHNP1DK zw0#I+AZsAK7MoFTDsKR!La|p6y&=4U`nWlOs7e8uI5OA$E z*ZID3t&$c<70kE35dbW}p03*}NC4lUHQWBP1DZ1wn;02pu&SbY^;;**r126>&F)Q@d|+{h`fpv+_nBb2`NR6Imc#AXOm6TR*kNMRS#s z+hcCA6hRwv7m<6oq)Bfe&@IM4Ih~ypvpptlv8^BIId1bzd{iSelBjMQ*rJ|q@Lkug z4?K2X)9D5mrzUTp_(xhwL}L2qOOXpb#&&V05kltS3^-pIrKq_A3|u<)*>9|D1`T~b zij`{an{6=Oq{nnK;9Nwt5fYYdvwPrLQHD=3dAq#EH#9t95LjV#J9#G%v3SGdRX|tD zQ37$^KVXm~35^bYIxeg+<-)`0>+)UH?8mKryrAfx`B;L^SztxFP3rtL9sR8RBh@;X6Mis+0nmHwD{bRQr+T|jLZw?W zT^yf&4F|j<$utb+0!#UN6wr_V&~ob&6Z^6To$^aG1)l(k4>_>_9 za*U3MGU}@#=2PXCm6KwQI`ank%JOjC6rJ~e5`NC|1U#jX4L-lfX|Ta3oRVMMg|PMg zGnsO$p5x+c>_6NETcv8SCcUpEsKI@ z#&cw#>z8KST`x*QOp~G}FPurYE&ARS;+XAdM2TEKRRJvhdjeC&%?S zK9*F>F>_?je!0&l&(vcqbGBD1hHlFZoy9h9WNr$`MESyW+mi-%DMgyL=O8?y z2H8-tn|ov}?9kB|7$@WajyYWk{o9?G#<5E4oT$L#=@Y5S>oH_nZ>apoOR84mWZkBt z4{%?WiPw~P?nqtn)n{_^qo57E42V0t7*scLU(K$F-$hM6_^tmmcaNR%1ZNtz`{y+; z6!nIBbDSyIqJD|9)3^Zfz!~xNNdJ3Hp|%puc{5c*!c5)=pWWN^?InW@-f_%@UC9Gq zKZ$NWn}GcdyAJPq7~_`Lu=6bEW<1Gi@HWT3Bi;*a=Hd>WEp_dTQy&L3<&XEvX>l7x z(MrdYE1djAS57kVDjr1Lu2`2Tn5fo-MH%6h&Xh z^E7HXN6l>n^-e~$B;@0rbsXwmVAI3ze`=Jc@;-jOh~L)m-ASnHiG8f5`o{1W6 zxTIQ@@Yyv750%}De&(MYw^@tng$`BR;PZ^EdJ@rz6uH)qiH--R_(WDGQ}u4#XBI17gYOt4Rmu9|GhyJJc}Kplv&1S zNwSdS(Bpffy``R`$vSes0g~b)=aS;bm|42FNqes>U{ta@_xk>Tg zGw)YI^4VO{mtREW^>5%NaAz4ku@iKVUA92m@a3Kk*TfAIzsD6>zKlQZhpg%-50v!r zhZ0XJCxwcKUC6dx9fZXvvF0`Ec?h^=Q#5%cm^y z-x$vn15#hj#+WrEUru}N&B%wx_2tLLj9}5?wgb{o8zA$N)xB#lum?dYn}7X8`TWYS z^n(77Eaf-bC5J2rMt)bg(f@6+^HKKi@>eRF>N1@_|LOiXQ9}P(;c(pWcgNM<`Ra&3 z;2g}ZL-bEZ_@WpY3EKx8RgUb z86CN*)Lylf17##uF88mx%3&igMdO*iHBtZ6iIP)e`ve6t-h4=HcfvG;gUTZRLzTRs zU^genTFAnH2J@N^{5p><)AA~U&EH>-0{Qv5b()g-#hbWXSW%%cX=wcA^<{ES75XZO z4yIT_QW1d;P3!m!E))uRwAQBv6IWsKprzax-k~a-|0ogh^2NIE&9M!&cDid&y5Fwc zTuJ!XpFi857Y7sK==-M*EhySeS83{hFSGcTx6J*^{^9OTaRi;^!v0azor%$_b96nhmI3z^v0I#b>mw!r~=8Jo@j+2JO_HToaqNHN9B7MuRaE*j{X z`9;g|V;s+)c2Mji_UkK_eUt<12=>b`aWVBb#xI*9v|ErI5kXv88Y(g-+|UmnNH1e# zS3>b5cT-CH$fOONh7Di8qWtEA7zavjie9g?0#MIqro^WtB990j6uh21y1~lB#gC+X zJ4`*&ty$tGA+C(iHxBtESM*Fmw`Qt_Zw0UKwXbcjnPd0&Eu)6}l-J{Li#*-cPOmW3 zTcyB}z;W(RxETgA`&(CPUi?nV z($(LPHxe{`IrXrSSuZMT=^OAec-6+)inqyRre|fnbjkgk#B)T^7ue90G+# z(!u#+9r&LEqD}YbLt4q-68K9!1i*-QF&O!SMnowjX}5LSIY2wB^2VMzV4b-zJkoc1 zN3_@fS=9uT*hr%MsvhZaBpqtMdyBG{Hn$TNar3S_0a~g{PWOUm{|U#BtbTs)^j(W4 z^D4pC2!UZHjZv3IWd4*z8IymwlIcrBSW)5zPEFdY+-2B9?=3bPChAdK6w;nFDx#X(c2|Rz0yaZYXYE{rzo1n3JH)$ zgrZja0B)66vaCN&bl~@8rO${0iD%|3&?gUIb{I|I$kS9v;(JMmg7WrQPFV7{C8>uV zN-rKo_L3KcC=ARDktZ1Ov5-mmc;KB1RK;lz^eNO9s(~LO967}L)61jub!{jufd<6_{ z7Vimlf7RPbNb2}IHzLh{ufyYusy}+*MbBwC-x0LjInh@+`rR_Ke3oBpNdqFS`_#y2 zD%t*AnU%=z8k_D~5^@R05+jo`_&D-%hEknOOpIh|t3ry(Z5JJ5?m-b3E_Iw?Eiz~J z3|6Ft!e8R_U^#I|n@5bL>XQJyXM*!kO4Se^r)AYv$p`?q@HpJAe)?VUyp%G1J4L@i z64!=k|H}P|yVb?1`f9UI{_GoH`{EbHmvh77?TpTAi~`2Ui1R6;a{4?}v-W<@qyU{9 zMwl%suvHz(Ip53pfal&7R1rctgBian4f{LTIziZnJCgV1{X;L667`Z<5|CpHe0j;6 z#sy+Y=c4q`Bc+6|mN}LonU;;ezE466y~+E(4(sz!=+rOJHqG%JB)or+CR$nvGQYN)2g7kAGL2Ws_ELHL(SqnG|=f49*t zS^~=aP?WeaDAR-}?8`pbbJ5O7!pnR6RrQzqhRdqd-{uCZM-*UeSa8(?rwEN%+9^KX@48jr{$ce6C0yIM694}9l-m2 zGR5cZN5bRnaWxa4OA>~&V8Xl4jZd~R&Vu{*G+;&dr}3BW0=%kw<60B1uMWh-nLNEV zjOvtTALmRjgt8A-#80!h=ALH%^*BhHbPpx6(&3#U2l>_f4Bqxm)je0;ylkM=20NI; zJ2SyZKKx#8`^56q`QG=G=R*lQYt7@#-3)r!cobNl^vIpMb3cR_N+m}P%0zUN?L6Yu zbiRjwhwN6kg;|pL_CgGqt7ZSe-Pl!FBfrpk83d{#37034#R;W870j$O_z#e0BD-o7 zI~-?0gDsGa!=pd|3L^>Roy_Bwxws48g+5fM6S7j{fZx?zQVko?5s~VOH&v53QuRuB z@T6CxGblLVMz7LxQz&^^>67#~9vE{3jh;N6H3PSR(H8s|#VReh=sM1Us%5)4w8~T- zE}qPZ-EMF$<%R0K1A#l?E_R+vQxC7QcE&qkQi6dDu>u+5iNIMc=^LEU{?!R&ZIxs& zc3IuWmi;HfFzb052-m+gG_G5g(1z^#XUTc;>Yt=&E~vR5U>%)9CLucklJgx>qa42` zE58^itvugD>NngpJ6Fyykso7VH{8)YN zA~oatQXQs0HNIzukO2KP0jxCSxEj+g_e9MKrxnx`@D_BIWM`39077*u@s9Tb*oo}Y z$f<6ABJ>2X@Qx@&iuUp&xhmM-=}EV>Q~UxJ5z9OK5oun&o!x)872*q*&}}LEX3&fg z2yZtt4Fy)&UV8P)TYC^hto)I^u{R)|yS-QOPG{gqWAxa{Rb$jN4tOb44t|%`62We( z1OJc=gqeT<&dfY)=#+M{6-so<=D7rXgGKeQc5$*)9TsI9Qb*uh7nUucagj`-RGJSB9=pa0wcg{(!(7^7G zEqo(dnIH7W_VXHr&H!ojaP5Mbh{?RwxP%^9xr|%{E$FhKm)uBkG6vbJ8G(%2FvdV8 zV^1~UOb|K2W}?+5S(PGBnnRWfHo^!iluGw_-gU*EPxvK>Ih6ABXTqBuA8R{Uu*rm_ zpBlN&8Ok3jtVUF89*hIRP`41jy|-oV_0j|WIU^h3L7vXI%OQ?xa`AxBPiw)H^p9z# zNX0G6fE_B$trp6t3?q?5xdmlc|FB8cCeQdEps-s}To=0vyDW)}`@jVaW{;}BznKv8 zuu?ZZbtbPwCLsOAI^^Bcb?)c7^G_c7$k?S#qty5yHd`+gUSTzu^!`|qrL60ly*caA z+$`xn68cqxlaC{Rt3a=*S*YcW4=IJ*7HhoVQJC{v?OShV)=z9Z#V#DhD-0c_6}h3z z-^NdVt?*0jaaciCe%>LcGxBx$4de&611B`LW9f7&Qsn>w-K(IoU#I!6XWykFS#K_j&jI;cZJx%`7(aM~M0WPZPv-Q`|QgT^Xw z|BxWk{C1$_;<4d@^6CZA{TOZZ!^{GUMWgX=+aO>+FS`svn}M_0(-2T2AD0=xt9wT* zyxn-RSgZuvGJLS2!B(7ow}`awqBIO6DES-uon7aLPgZ`)SV=?Qwq$IsU~gtHZ_wW; z#JvT!{qDi!CK*q}>T;#|w)`2xpQ&DX`F#B|TpD?tq4eE3j>@tx75oYm09bt}lI3?gAISy*Cfl-s&YY^K&~CJ>aMCRn|DgCZIrU`A+*cpaT-4(TJ!LwOUoQ^c z>-ZI+(!RWD_n#<^(zQmyt+o*dW5=$zcpYmftcVnO%OT1G_v9Dn9daokD5XaieqCe> zgtFRfq3SSS=+e$|5q||)Tm17y6VBr`^Al7<{j2Aj^qV4tOf2&%a#b&uaZQB1#r@C5 zPKR?ZdY*YM9xYJuU6w%MH++y#Q4qY|8~bXpTeyz=w7cs+HklKb%X~n2M0)Nk6&;{bRx?G`JAZU=3vI(0)pVj%8yYJF|K z>pGxIFFCK-$%xdT^!A;1ZSc8Mv57PiXNA1^r1%jm0UAkY&ly$e^t zDxvML{eLAM!E`>y<7E@%FrVYPeLi=ytTljKp+*NkJD7J*e*|-w?28QOzwi#f9r(Q~ zm)Rc}JK|wONoC9AOIL)(qj_NL$m5NN+}|vUFYd~A&WIZ_-EskH+_qKXq`8bR1{t26 zPD1wAL#cnFA*&fF2MruQ@=L_7@uTu_`05_3P-hM3#!)K}kP+l~X%%dIm}efa;|)?+ zGAMMQemP9aE}(Y)dDXkL-+Dw#frA^0TC-%%#mc*5HGJmMK-WeQ9|xC{7E@2cp~RlX z8Anvj)I5Xv78VB!I^eRjwr!@~&n=vnSD_E{_chUb10Y^@{ePd2KN+3q2vbo&q-g9u87+ER5uq(p5SsF;ei{HO9(6SL#A-nh4Rn6sh2Y$h+j9By`o)n1np}w zdnNZDsTGFfZd~Wvb%-mszI&-azL7j_xw@zsAy-QHM>@4rUB~vvt?( zlm5GwG@hrR)GQIt!E?r_@1Lf*to{LugXa;EEEKomWwq+#X+p zn()hfBH=CS_2lubT+u9SBD&IDj(2Ubn_t;npg)KA6Dc=6x6LvOCY`jcUSCPE5?q^L z-(C5pG1{BqSRkOt4}jNiynTo#`@Y?Ux61^uhqwHqru$hQ>fq8MhLMC&6c%V`izWJ+ z(Bc{A?~$4JA?swNa)+Bq0e~Or%?tvAUzLeSZQG|WulV8YSJCm@PGa6Z{;PwN-Fy2* z9s0y`8Nlnxg@wP=At&Y0pbje zz<(uZHS`+vYUT&Q{V&o#Fl;_JQ!E#e7%vqsEfVAVERsmBGpIKdI~hU5aFr+O#-8J9 zXvQEqYChXo%j&Wg;SKOgk+*YNvmS%AT&0GbC1C4q^rH}8Dv6%|uPCQ{rJ{%aMR8gaA2Unx%dpqleR5O;}F$VLWNw9hEu zBSj*FH`6yK;3vh4OlpRav3Frv+Tsd5UOMU+w9ytj_tkRK`J2z1L=t>C!N(xiH1#+E zKQ}EpS)r1_nt;I#kd4DHuS00v;%a$B3c_p;42|=Z0o(`VBN#xUNe+P*w5;u635BUo zm-+C>ci4h*%hGncfPd0h{NmVx2_|Q(2yy`6us7wZxq_dwU*iIP-_D6}9UPl$GU7V= zZ1mOI=jaRmAcsT5i~lqCh4pGnS%;WCvDBdSH({cxfsGW7n?g|Kl6}%M@7kENN=tv2xHhPER(h zku1FklXCfzZA4>4f}+SQARi;t2lnfCA7~U}i7Sg`j+=np zjK;-=i4J5@7grj#R)tA(J(sIr!Vzv_YPI*^i1md%-*j;K#Jl-9FE{5wX%35L^&+>j z`C{`3D5Wix>A#_Ae0+c!)v&Vi#?b)C=A)Wr)c!moD{9YHMalUcc9JMaD*1qB>26KS zUzcyQreP2Z{ohB{*P`$Sp>ZVrlPwVu{ere+-vjaTw2QJ5j670q_9`Pa09>N=R{tX6 zcTQ|GraoG~%gSnA_HI;2!Ijt)_~&?2yl}Pfk#j}#q67b5R(f8?QQj(080pqo8a*>P zfMG4srWH{ew6WC8o1ujK8GggV5@X#m-9W>uvck%Oa{Yy}=<(9$=k70E_J@K${0cVU zC;>*J{BZRpO(X8-wWM%@s_<2_cJY7pHV}zzVgWP&Qc_Q{tE>mboFj`}i;v)Vc{mPz z8Z+0N4>oGmP(*w-f9Bk~d|2(0CDoJhxb0&8Q@I^^m7p$sc%$|GYk_2M~)fo<2eVlKDg=B#qRh# zhdASX%UH6ppIdW3jUeu%@cJVFM>5q*lH|j%`P!j(Uwn}E<2tIdnBeoH`88a@HZsFL z<@ah|kK5@3SX{@ecNu46R#i-Ip1#cV(-^JS26j;X>blx8q$(%s`OSl?sv%IWMSBh4&u>^-0ZJ<#IWb12NpY zi8@e5yCMY9Mp2!oDUp!GbmJbJrquf#P`1Kp4l_wD$6c+qI*}D&M}kB%wUQU_rMt3% z-C-_7{1;#KB-b@tH?R7EWxTB-peXZz!N|Rg+ldMCF6W2lPZoEsZ13t zyutQ<(_ys^M>O|o5S)JIgfcrXsstZ?-}sB9ym7R(m#_gAabt_ILPw8uX?Ix?BqjB4 z)#2@A2en+14B9*0$GE9RpI`(Fq7(Q+s~1g5-)&L_kp<6!*)jP*?Bq0w@bJVA>P85Z zi&ts;(}o|C0-Ua^%Ymu=H@ylrEwL>#g=YC}WA#XLX9pZ0I{go=3r5!Tc;}3BSq%Xb z9>cNoxVtH@LL2DTSZOv;z$y%my2X-7lE@Ov5_D)>`zAu1Mbm|r=X&(YJ1I;qWEXdX z>I*HV899n{7d0MwMVh+9)QOfZvl^FpzHWX>)#wyI^q_mbb+DXv&0kxu=i`jeGqySj zcp>9X5r{Fehr@<%1JsI69Fw&-4*VjsqJ(fo5G7GzrwG6ck_%rPVJ^Ugiv^a(_L8_p z5&OtZHYGdujTw2DU+rbZ8Ar?DNEmglGiTie`J9R-LCOcp5y~IF^8s1rbj20I4oEv$ zmHm;Tmi0YSwN3LX9PSwD7}*~A1tIlB6{Z?ZYH^_GG%_X^5cBP<`8WCM{X@L+=@iXn zZNHIMj5)2TbuQ6=Z6o9uS=E%Q*l98gN7e>hhNCQV$o|g%T}%hiq>^o4dfyLdhXK%- ztPvo%I9IiY0{gf24bUpq^m`E+sC||rv#+TsN3RcgHio*DJs3$_Uflxe{qg2!Ic<4= zHt{||xLapJ*yXTO;{F&%C=$=TjLCK-SvmePEIX?C6W}1K51#=H();gkpV>z_bvExV z+df_krfBUA5=>B_u|##wkD!cF0V|4IzIU>bK-C`qmwp7bH4GzP3^D7!@X`*C+yqtY zay$LBzdzRpGAlFUeino)dJN-KO__i4^C}xzQ?Gs3q6Yw8*89D@T#?QEj z-)@xG0;J>rg40?;fI|KPxlZz{)hGAX9X#eD?g=7MmatP`o{V2}?nz`hVxQ zjv#(nS#kZ=pcbz*d|LrgV^P-HhUfnBpLWDOeHBVQY!p?JQ{_3wkqVC3De=t!sW5Iz z8Fp;2o^FtEEu`fF0hXDpRqlmPsB;R==C72w(m|nN+(=|LT$h_L-6q3j9lg z;Qrm9Pl%8xiS0pN3ppcSb(Yb+X|T-z>-6D1&hb`y(GPdn#{j zrR|Ih^p70uC=a6rJ3j~msf|5>0Vc}W@BOQ)-1_$O0`Xjf$M`Os1?HDP4eEenF zbipfE(tF%ii)YmzIH6y7A9&k1{%-28$N#BYxi)kM&ar(i#T+6(bb9*2B|{pjCK&P{ z+TOMJz6_$5)Xzse$fdGa@5 zdt>VqLC&pmyd9J)_XHUOUXBL87`Zqww12}hcW)~^3g0`8;V5a8!mzx|p0k!xEER1*H-Rvx5SWNA_{g&kbEbdZ#og&GOI4FLiC_!z5@F zql9{Xt4vA$P?^6v`-`Iqc9-Y(+0ZwFRy+IA4qStgI#PR zxOPcN5c0%9OKfAtpyd|+xi!YZc5pefj6jnPZ0tiv^9ffBpXS12`vcQWaE={EYtM-= z&A>^o#y2S^LHwMplGie!q2?YwN?qk)J9UpSqaN_z8*jI`V3_%$ zr`pI9wtz1?>lQms@n7Q^5b*n; z4MGLYjjjMe15-yGA5_`qH{}}BUuoY4HYQhBtxUC2>fY+&hjq!S#j4CO{u>k9>v)dW zUx8f&w`J}I)-p|-R52O7%KmHQ(q;-Q7<9fs!*XK}8=dOF-?5dVX7+^*j+!#Xv&8En z8^U7WyAcEdBZtS-+oRvZ@b_{T%y74^Tm@&f!iQQ9z2uHuKCpXR4oC3NgsMZiLM!8= zUv++74p@k_vHuNr&2+xg2H6>idpFxYEqV*_1sIyfSo1Mn_rmaQ{_rpI@~u?O&HwKOc>8VXj7Aj?8%9vrmhXF@T232M%Du6ge^|Zw z-5JDD(s^|4csu2EIl{0?UPa(+CVf8v2LSWeBj_NMRqHxk#XtD=0M_)HACM1-#L^FC zP&Ap5TFeh%$G^*Z8_HMKl1?gcpN((Op*sR+bcI%BI4KTQ)>(4*Xr(U)XdAD_809 zFbSBncj$@SD0iK^?sJn@i1CXt8CRJ^wzm7T306&*d;D9WKDt5=iM@>1MI?)x>t$S2 zg)tjx7_(s%S%ZCIGs6ol?taPi5nn}EDIj&}l6Q{ud%x{F`9d1CfV6~VO}|a)%_CWF+H5_{mis5oi||tai@PulM$+ zS&a>RymEWPW?x0|yI28sP2cJaR4QFP(NBINu(PYvs zc;N#!Y1kZ;gn{WiYs)#vY8!aNR41b2@k6d{R_VWiDFVjs|K=u+M43USS-IkWap$Ga z@@N|C*qy5Zd;S{fv$z1(I2-#$Nkn>JCFAUYJo0+2+I-1RDm9s(Wc#-s;A-MTFff7; zzsx*y7nN0+vD&twRHEha0}t+24N=gJ8IA1q)BpIQz%r+RIn2`VOBmum*JQbG^Yvmm zYj0e@+{v5C0x1JiLdDiARz8;$xv#v@b|wVlkapn9;w>m!BK?#GZOF{_ZKpx1#l>fmWH|5#h|!?ThH~h8K_T@Zd4-EK zt2dkr2j+%iBkMsRE;wHO;r_!>uji05{kV^pwx- z-K;J}u|J+Vo-6YF?0|~6e=^5)C!iyueA=l-+wHW01j^dZ-;LW0=M;wxjU_|x zT^A@YI7afK@96sZLZD_GD`AIImZ9Guv72}t5Gv9+Eyx5h00JP1nXyR?4i7IHql?rM0 zJ3>JzpkqOw&EB-vH2$KbI8QMmP}hd+LGkE_k=0G_1&Mwu1iE7LmJ;X_WM$9 zC#HLfEVd96%ffdxQ<|9?qpC)(7?T-x2#$+B@n-JrY<6(G%$5|(L=3!=0&L(-?n+z<%riMgU^|WK!`7s1_(c$8x8b8O@va62^0Zq zc>#Z`cyO1n*$8$CmmYv6rr01#~@9LXa_g?S*5+oi-W`T3BFL#J_bFuRa$Ac*2sh(xhrh!CO_~WzOAX> zTSmaew6kz+oDHJk9Dl{y4HnFlExs`Ybioc?5zAQ1cdZ&Z%dmh4!EtUYg z<*5DLr>6HOgHNtSZ6>uSW>b=Q19>A^Nb##Vb@%!~;(wi@;BrM;X7|G)L6zFpk9a%k zXR{n8?t9YcIe+B}t3|h-{mKw%upTPz^XP+HwQBcvq z1{j^CTfc-!(>j?ykq#q0`Xe{NZ!kFNvPE`0DPZm~tdUhf4!T{$WLL=RQBo?MP;+Tl>!E;i$B|%? zrVEeUZFyHj+r~cbK4&h+3TpX&Nfu2>I$|=@LrcPFKikP>= z6&j<=|B!)<&zd}`EMaI=$J~<4uwfr7bJ<(K+n1p6nF$R&pdr@5DY;Dth9D*`lvgS4 z%7;ue^E@a16w19m;XcuOGOFgP{{TIfv8`OW`>9nQ=0ADjuV+r@aCeZu+$gK~8?!Nx zNmSAnPEBgfN(W2er&*HQuT=O1qqWQMva3Al1L;9WA=}#kecwhoRTzcHu z_6kzu=6p_5j_K>MU@wyQlS@>$d-7(jJT&co^$A}eP2cCLfoQEMA?VgW5v5Znz-+>- zsXj6NR~FEBqkHv;FEI^4ix5NL?FanpMvbLrgyEYw$NJg|CGO&Q(a*ut{?>ofy58W7 zk+!*X;QKYL2Vc}1Apw1_m&zY&dvR`P7FHaWAb{d8jCj)$UVo>!`3x|!G6vzd@zRd=O3 zG<;7{l2$3*;a<>oDuO34(|{rPBi_Wf`?sklTXu_!Qikc>a3*SEmkE;lJg zlQQmB+GVUAce2#i_6u7Yvk!ehy`k9_cxDx;hBse-5J}@waS3mYxsHs<|DiebsX@he zCSE;J#>rUx7xKY0Glgv<7zfOg?x1|&nrCm7be^(pXbMQL8FAb-C{+x;{C6!R=iZ18z>#IAWa8Aty zO?x+?$vH`=eS*4PA*=`zm#f_M%hQH;w0oJ+`c@{ykuj3HZsqi`9OkZVaeNV}Td5oF`m=q->| z(R&9;`P?HM{5+Kx(RYbSc{CNh z%PCw0nIwRI(q`792}t6YABhiEtP}4byHa@a+VVyX3}i|y)lIaZ!sgv{o4zc!V>C-CSh<~I1t^Te!E18%w^>Kw*lmqDI*|etp7chf-S*%yO zEc%jj|F-p%P3i#1@i5Z>NP!pr*wX0w1)8p43$$Am`NdA!_}-hFs&dndT&?}Tca84h zI7ab+j!St8);%G%RDEyEEH)&Duc`ON(AWpThnZF>5a+L}VzJXgPs}2}dh+&Z5?I=7 zM0k1PJBlt~T!*hprV{cC!YHyNk~S_EwGRUJI8BA^(9}@-^)SR1qrW=pm_$%)JZUew zVqi?LYKbg%u71^1glZZu`$~7*8sm#m1Ol<3mvI-5jUb5$B(=Y>5Ta6~L+@#0v*XGW zUf%T-(e(qVg?a7zhdKH#IsQ$ySp|t(<`H-gzG9}(7)zjx6iP8dgnXDKX*!3+B}gz7 zarlFJBSAR!DK1(Bq4j99PYuYF8yzKww zb|5<`_-Hy1Z)D^GGEj*CGMFoDUsCKhBkcYW;lb2c#-50mdu{727y1V?nvtWF;%Tea zBJ_?vm>DD%si40j77?8w8=+hSU^3SaNKjwvicys7z6~LCPC7NEnIm0L)cB?U#)!&% zgwV{&k@{#`GzPKqC8?mFAS^(`1Z7UuD2Pjbtc_2hUISEl7r}p>XEAoCs@2kD_R$^FmnPr?dd`*PQdXed>iri^as^xp=f_~T2d;JsxKuR0BVe6Z zz>Xhk)|=uKlTp^Z1|r*x>ulkhInY!CUL_X5slld9$*L4vNmqTXSR$%)ZnF+W^By=X z2*D)QGa>HycJIdmNV3K5~}0Kj%gS%)?bh{Xs(2_@H4)INM; zxs7@aq$UYl0soQ<9S}u{iO0;m>h1H9Hqu@cU)2gP+^QEF(bqiSWoI=w1i*#8i|+3E z8Ydp-7)D=pF0kKW1}mKTR1VFK@fcrnUgA)JL?e!Z37#1xE&ISRNh)kM$6|jsHRHZJWnz40mL7abO*!;bWBI zSxb>U1UW$kt$#_Vl`#<`)YK0jzX9QcV2FAZ`3t;`1(I4t*p5*iku0?dRgf~x zH=k@pD*4P=4~E|`9Ah%k0M2{RpUQjkcuMRCH_%B_#6vv&qKd>Q*xz8!;D?d{HI)$F zPA^KV*I7S?FZR|p?D;azWXewX`e9NF5R0lq#7Uo#_Y!#r(95PToX-DASU@Zg0P~7p zCGgXbOE<566?Z$7tciIWg(V!EbRRR1kVPLI>1XE zpJWvAD{QKo*+LRw;uzf#DC^|+4%W|DJkfQr>>fSqmW4*ZYNq5#R@qlM9uOO;uWoub6J z+@NjN^PB&$V%~Pc7@?dMT^RX=&IP-p2@w{+T(oHtz+p>93fr={vbdqGHy2RgtvA#e zv)w;OT7EkvYHN>UNKzWm2O)UhjW4bBO+6`>_4tolj;_Jcmf40tkb0M7DPK+o#e z(7CmwReSOP$VRteY<9HJ6O7cr{3rDKf+Y6o(5wGCy`foOSY%+;Ga$KxwaSlp_-bxR-1TfZrgi}U5V?`J`kZJSHLM!oVouLnfmEjv;L2%{M{B>;V1m=$ymOC! z-w1Equ-Oh-C1I8WA&(VzRnk5{1B$(oNQAfpN(ggU&7Se1lcSPxMNS{YLaH2#jC=|1 zppr$&A7G5Ub2`Wr^(!N9utJwJa$({FIbbK^H))#^dpB<9u+)s}Uge1QOh)-W!Mm8K z3HqT7x1&eB@5~$&yl&G&SyqSdLUVe-S_S8I*a>$Q>gXTSQuwoJq zSI*w5N0M&SHDR1w3-#*?HV^asJWfT$z$N% z6qj}wpjVY454Z6{GesINEM?eC`UlJZ8>LMWLnH5{x3ETTptn&S2|FcG3K)?gSXEpP z23<3CFSU*Sg-ft%eU?Bvpay0`EC#Tqp+_@kKtwPqz%9JuwN_r>^GX>>YUE1rhQ19n zG=LrR7u!vj0(-JIiy7%YNF@`suUs(fG_oe_`JLU3cj5f&blVIM8$OmeF1UO4h~G7Z zd{&Kw#H3K&BTTpZc9>6iB4`w4uUqQbv)(WjvE!pnC)<)awRF-N;b*~sRT)93jO?zs z=HuY;yw%!*lhpPtwC#Zn55j}J=c7Z_?dyhLRKCcB0(>kiG|}9%tMak_vm1i|BB`hk z&N(z#Pv!?UxBqPBSKK@eYYzSxe(23^Jt#%72y2KIYH%3zLAx<4(0k)xVeK2<1~MuL zMoDOyz)5;%@3{UM4reb%4k@%?HEnXZO-=YZh3<^~Udv6qGfrfRg@u*W^aY5+7?D%} zKdEQqjxG+GG5Gzt_b>SfmxMaGin(f0grSHQXyrsMDN#vXG~dKWTzEHKUN2vRm$8z1 zYnmr_H={P$X}od1zt!eLzcn#|YbDkm@=xB(GCE$U`91QBthzS)!SZLG%c*2FO}G)f z#%d;H6rg|OakQLewfB@BZR|x&!0Ho!)>t*xAEa?)RjyDi2zBJCJ)*FECZ^S}N;SXi zWu0T%o2@zuR#_|Gp?}qKzNIR$F60M>&5nPFZZRGzF|m8Het$ATYlhhETl9>#&iY?7 z!iHrwMN%;0){w?zGBZF}Mkh6u$YWko&&pO=+@zdk5}BKm&GE$A@oQ`AinrH0kHw`v zV1qF@SlPUy&a z@BMet{3YS$S6b3iQGRNp#FZL@wTJM@^>T%(YMmKk%p>1>^ySRL+RwK(b0(vew5>a- z!CaAJiony0S`OG%!+8JQQSdkyrtozQYHgBrCEU$v?{rn#}M;@tyZ@PkS_NvaD zGxrkuy-*{7<-$JF!+6u=e&#cN_S!_y99$-ce-1->qV_ua) zJ3|$Nhlukuo;f?)Yyj&Qsc`=vaXk9-HpezYCK+hGaadvsXlEYKA8xE{Zf>T5C7c*K za&O~dCMMykb5zkQi0rQE%7^D72snP@iKheErki|Ku23Uy4o|E7N6n>Dxk6N4+jzViA-jsO#bQBdavYs zdYOnjjYm}&!QK4DH!cR!8FU^veBcb<+|& zmkOTKvJuYLu6R*)t#R~yl8#sg!;J#)DW#(?n>FPTw?GVUus*An+%nVSL9SERLL84%KeWxW`p`yZRdtZu|Qxz+l#fxY#|=v?q6HG zWd!LY|71kfi%Ng{=MtE4bLJ<0uY|Ups~#;^m{m9$8afiD6V7M?Y0vp5VHS(OH!s~j zG#qZbv~OZwsD*Z#%ISxdoZBANB&PUiIY$ly33GD+5_Yf|Ho0DrY_$GArduD*S}ab^ zd^=m++}(5rgfd~WAa(N(DYr5lF&vRl4G8U!R`}n9bH0C0IgBufFk3X*q4vhfd6%SZ zt%0!zehx=JHiaq_+jM_WA`CRGf(&|eMi8jvZck}+m~*BTA!ZTV;-D&L=l&}TyfpK z$v^ppzoG$G9oLNxkXA!lVEeLRQ)KdJvY!tlO9+BmL%CTZscz#iG4Mfr!1(*FO#YV3 zMA8aYi{@}sccXuEoGL7v8wZb>T={WrhuYfvHCY8kR$<8G3@l_rUCCkEWJyKF=Fb>7 z!a??QIQwJ&86_5$b#!)lRz<#1v!RtsOzuckCGzenb`vLq1tPQgtxkLSA+UZC<=3Tc zrE`VSn2A@?3K<0azs|nIsj2h(`vOvMgHpd11%+Cy)D1*s3j|zoWf2IG9i#}dD};SX zMQd9DTd|-5K|~BmfUpH5BoMV?EkXpmY$1V)5DWw;F(6CucP^dxA9y>{nRX^m?(;n7 zoX>L31>Af~mmAp4iI?Fqj{)kTn$LT@rXHYcx_&P2_$T2U>&(h2EwZ{{y?5q0mT&O2 z{7`_Ka)&poqwYfCbJ-;eGP@u#ivIH7IWO-cI1+A3A{oXjV5{-{dU90;(ky+^5|OU0 z^VxZl&j{7=r>1RD=J?NEz-VhnIl+-QSg}lB@Q^?GZNt!)xe-V+AmT;z6kMM^G0lz3 zz#S)HySDh^vE(1SC-e1a9R20Q@TyPtR~^VbmFuh=OO48HTon4~>Hh+lRRJ|&>-xE7 z!C#*5;6P4ue6xDmYR_m_yQEs;NN)~~iKS$B3}WB8#oa}ITJ9uAC26Ly(KgN1xV$@R zLxUS)l$Z2wTrZf4jEPGvV_QSEasKr^bkUv=+oO!|BJa|3b%l9QWW{Vo$E%(1;U@^6 zcp>pyzm{D(L9&xiwzRj~(kntHW>z6S5FC>GexDa42?mFT?HgCBO z3v2H>3K(bTx6JMOnwade{t_I|(<0wK`+&~4wE0Yq9QwIzVOa93U=#}|E1#>Ko zj1bYo7s>YthNfVch-sa@|0Mi6=Zz#ik z;WOrlL5a<(LwEH*lCVAfYi4?+eUXt?v0PzNH+#uDA35>UT1~P+*ydP@ZwlwAzxX=3 zny$h-XVtqF4(^9{XZVz+o>REU>rqEWZp;l)_*~29joPcS0fx?jS>ddAb*DEv1x3lrI;yEMFHevTne9-x4R87aq%GSf%x1bb< zcus#4(X#_V!oF~k|G)~)U?@CDbFii!&X!{2f@Bp1_9i5f!UHm-VqJgnB~iAL+5A(_ zO31prwkF9h5&^2s@I;~>hWx*G0T_nBDoJ;~80w8`P>$LH^;^**YUjHGBv5f(i~D&y zaKXBm#LMejmJl;j^3#YZad4ZVfl3y2UTkEGAsnxm{b(UuVhm4oM>VGSi0;^-au+DY zy4xx!Me3ep@l3V%4zeTCu53CV$UvnL?45V}51W_Ts~nbQUd|eNu`R zQsrK(9q(6JG5>y{uXiSCss}@`mm&s0bDFOrTHYm5RWjr)487apSKyvi zjb{Kn-;@laf#@qyJ*F(Oeo>$YP;Ye5?elrO6BmAX{=BW%U6rz@~3%wkEYwIB;c z60a#C_RS|i-shtAI>RB6j1?V1&>_oT1X}WNpn)9eMs(1uf$|&wiI%J!5MZ#8&rU+& zCPJg*C8S$ldjuIDxL^~`XpfAET~3hyD0!Dr4MqpCaGoXd&5pFEUAmSZS5emPgMD+W zswMCw+-13_Pu<$q2XJ4QWC@?Ii0+^M#bL$_8+XNV zIYp8m(zpgYA;+KTrg@NU@wsl{ocuMUUvno|FyM*x7dOZIc%+mqgvpB}w?n8anuHT! z>=sAxtyr#Fcm+P|yFjI0i&X`P?wkD+*3`sEc@U~kAi6cu!*^j~bXvcEP~B1+(v<0j zS&7))>v=8Tj;-o_kmE0YmFZnj7(OB8RN$4Z@~8HgM9Vm^C0wH#1q=QcxL%g9$-{DzZC*wn=8#3$g)vL*LN z7CC8eF%uFN7>Y)tbGpSL&2D%nDLAikNUN5S8C}2Z^AP$HcF{tz!33ucXRxvxa`~k= zc|6HeZjSaa3_;H>-uc3B7-%kRKg1p=!71e-q+n;vznEU}Y+alAZ>=w*$z1_IJfr8N zLvDLoV$K_totDcaJ((tZZV?M<6$}R_J@~NS+IadxgnSNdHk&-@v+;^@m=O-AWJVkL zUf`lT9BNBUsbfQW$L6gBDDMpgYTXm6b&yWkNB`O{`YYJP6~L||#d$IV^d)_ckV~*4 zsKGb)9-~BN&=qb0+Tw>M^jK%u#;G@}D^)QhkPJw+W}4I$hQ-8D9$}(}_l3Es+oxpa zg0sQc5<%VxvA0h^%#05k^1cSRqM9iKB`-fo3?f}*d1HElygoQi9u=S|9yEW}{&M2o zs$Lz4z31x-HqtU9+VX>{dYNX<;M9tG^h>|1Qyh}!meR2BQbI-7vMrSAG_Y@G-E|Cd z+YQET1B#+MKTKkI(#@pxd*TT~5g_h}Bo~CC;%}8omO4(Ut`bC33A;ioCbbN1`=MPN zl@ExHaY$&)<>iMa4`&%@9K#R*y7#`<1(mSNfM5(T}QR&?Y1E?aZSY?(uAukRq?XdLw-Tt+VXRMnn#lj?dAqDed}q2=O0U) zb2WCIGn`GNBV^p%Ke#Xd;nu*(1 z#ll%Zw{c0SgBu_C4}V0Q^x_cx(k6n!UM__Ds5z~|n=%+%HAM2vs^-?ROTap%qa^gh z%5`%NFEU=z^$GQ6SKAvQ4M>-jr;}FWl;V#9Rd|x@iW_CcsJ?k@JjJ`q|T zJ23W+!&(qaZlD_=1B8F8@WvrVL-t_1wxZuU>uG3;yjWo#TH7dwumi+zYs62azp%jqWO0>;T|>)B^WT zC=8vL=6th)i+;rbu=O2J=Sw6f(3)7-N-g%)7jqh|jDs^O6+g(IO8O=13Qu7>`DcQm zSDxAlWi6LXLX37p+EfiWZzczXG&IUGS|-~yO+g?xv-dS(M&7SDzF{E&a+iS?pxKZF zcuhL;^J^e=mG}88L}rNVlRh37?%6VPMKUFCiA)Scr&#j&=q^ zOMU_Q($l1Kq=#6U^4L{wc%tIr(SVStQaxX26A<)}EH%ja@n>KsJh_bvf6g?}aHc{m zq){AcxgN7gFgCR0Mk*w4AP?KWSq)zShTvdqTx#t?80ie@FdN(UP`rf`_q?!Ylgna> z}-AQh8O3U{GN7qQE1Fddx0#Jrr98uoiGxl!D2aem_(%YW` zt4{rboY(aFTBUMw&-3;TU>`I=(a#YhJ(mY8JYi23GmjzNT}eUE5J<_71J<6~t%Z#L z0(d|QH7Sfeh_hr$o#Mo8=saqKVHw%rB4$kpzz4aEDRVY%PV#P*A07y#a&qrz*DvUC zw2^*`pw9$qa>H0PzO|cf$Pnl>S~Pd{w$4xd#|h_|aH(PH0Iggci_Pv3&eJ4Y(S-j} z(>#Fg6B2VdmAddUq(dD)HwI7O0#8;J0qd+rOVCEfEjN8yL~zCvOv(5Zs-PQyD+j|s z@Vd+MjT{iOH4p>c_UcAitzDe>CEbzQh_$GEZn5mN#VSx(#su55P_Vkc!9mw!2Q_6| zMP7=DO)X_NXipYmz_3@x5?{IK)imc17M{epfjLzXGqs&+|;qc zr*uQiDp4tea%tk-QmPzL>>Yb_4&UCY7`1n9y`82e@ z0HOU{JY(Z1KHdaw{X%eYt86CZL`xs6sjR{vD_18V1T-^~U6aV^-~E1-Uk#QUANDp{ z#T{(v^YI1w_gqqtnZ=jdY=B$qB|nyoNS2|cz#17JMk#O}rSFve4n)(|@^Y%yS;rB? zrm?Zh=j6ZJ)r&u@`~gK_ASut%z<2=1 z#2vm4TZdjt%iaDPy4%D=2zVNSTZ{D(zD2%-6`{~2a-p{}^5{S^Uf!MsKHJ{AyA~h*R!mOwwDy@Qw+GP|p^}fZ z3v`sI8V*SOdZ3w4c-T@S_D@?E zv8%y-Rd)yz&XJs1ZQ|YVl;-Citmeduh2wH5*h5X-;?SN|`3Q7fepV%$`&+ip4nSQm z=J2f;XLNp~^3TJPRKZgdmTly!ym~@?(Am8RXQz?B(vUq|RCwlOdyVd*m919_T`Qha zwUjS+$71IScub2ZZ|YRH(64~M9Jba{X(%&#ehm`Y;s2vJ5L)G$gsJdrg+cQiz?t68 zSu^D}eWGpfs)9Ho*5RAosflnBjC_=a)K?V6CG-Wl7p3Yx6_-HM5$?CLWJ~bG0EY^N zinjdKA4DgTqLg`_h7b~iFq6VM^Vv9&SIPse*d}gOv+Re$W;jM(|FYfP`I~@Kb2

tJD!vz7e2+-bWYmw=7kbZ)RC@s;PKZ;)|%Wh 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 ZhHZ}x_@7lav_lZ&)NzMn6-WH8{vXr!AVUBE literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..c1ed9cf --- /dev/null +++ b/docs/index.md @@ -0,0 +1,82 @@ +# + +![image info](./images/blitz_banner.png) +

+ ⚡️ Lightspeed API builder ⚡️ +

+ +___ + + + +# **What is Blitz ?** +Blitz is a tool that build restfull API on the fly based on a simple and easy to maintain configuration file. + +Here is an example of how simple a Blitz file is: + +=== "Yaml" + + ```yaml + config: + name: Hello world + description: Here is a simple blitz configuration file. + version: 0.1.0 + models: + - name: TodoList + fields: + name: str + description: str + - name: Todo + fields: + name: str + due_date: str + todo_list_id: TodoList.id + ``` + +=== "Json" + + ```json + { + "config": { + "name": "Hello world", + "description": "Here is a simple blitz configuration file.", + "version": "0.1.0" + }, + "models": [ + { + "name": "TodoList", + "fields": { + "name": "str", + "description": "str" + } + }, + { + "name": "Todo", + "fields": { + "name": "str", + "due_date": "str", + "todo_list_id": "TodoList.id" + } + } + ] + } + ``` + +Just run: +``` +blitz start your-blitz-project +``` +*And yeah, that's it.* + +!!! note + Assuming a your-blitz-project directory created using the blitz create command + +___ + +You have now a fully functional API with two models and the corresponding database schema with all the modern feature you can expect from a modern app like: + +- Automatic Swagger UI for the API +- Data validation and error messages (thanks to Fastapi and SQLModel) +- Automatic database migration based on the changes of your blitz file +- Generated ERD diagram +- and more... \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..fc6552a --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,6 @@ +# + +## Using [pipx](https://pipx.pypa.io/stable/installation/) (recommanded) +```bash +pipx install git+https://github.com/Paperz-org/blitz.git@0.1.0 +``` \ No newline at end of file diff --git a/docs/js/custom.js b/docs/js/custom.js new file mode 100644 index 0000000..4351cb3 --- /dev/null +++ b/docs/js/custom.js @@ -0,0 +1,189 @@ +const div = document.querySelector(".github-topic-projects"); + +async function getDataBatch(page) { + const response = await fetch( + `https://api.github.com/search/repositories?q=topic:fastapi&per_page=100&page=${page}`, + { headers: { Accept: "application/vnd.github.mercy-preview+json" } } + ); + const data = await response.json(); + return data; +} + +async function getData() { + let page = 1; + let data = []; + let dataBatch = await getDataBatch(page); + data = data.concat(dataBatch.items); + const totalCount = dataBatch.total_count; + while (data.length < totalCount) { + page += 1; + dataBatch = await getDataBatch(page); + data = data.concat(dataBatch.items); + } + return data; +} + +function setupTermynal() { + document.querySelectorAll(".use-termynal").forEach((node) => { + node.style.display = "block"; + new Termynal(node, { + lineDelay: 500, + }); + }); + const progressLiteralStart = "---> 100%"; + const promptLiteralStart = "$ "; + const inlinePromptLiteralStart = "> "; + const customPromptLiteralStart = "# "; + const termynalActivateClass = "termy"; + let termynals = []; + + function createTermynals() { + document + .querySelectorAll(`.${termynalActivateClass} .highlight`) + .forEach((node) => { + const text = node.textContent; + const lines = text.split("\n"); + const useLines = []; + let buffer = []; + function saveBuffer() { + if (buffer.length) { + let isBlankSpace = true; + buffer.forEach((line) => { + if (line) { + isBlankSpace = false; + } + }); + dataValue = {}; + if (isBlankSpace) { + dataValue["delay"] = 0; + } + if (buffer[buffer.length - 1] === "") { + // A last single
won't have effect + // so put an additional one + buffer.push(""); + } + const bufferValue = buffer.join("
"); + dataValue["value"] = bufferValue; + useLines.push(dataValue); + buffer = []; + } + } + for (let line of lines) { + if (line === progressLiteralStart) { + saveBuffer(); + useLines.push({ + type: "progress", + }); + } else if (line.startsWith(promptLiteralStart)) { + saveBuffer(); + const value = line.replace(promptLiteralStart, "").trimEnd(); + useLines.push({ + type: "input", + value: value, + }); + } else if (line.startsWith("// ")) { + saveBuffer(); + const value = "💬 " + line.replace("// ", "").trimEnd(); + useLines.push({ + value: value, + class: "termynal-comment", + delay: 0, + }); + } else if (line.startsWith(customPromptLiteralStart)) { + saveBuffer(); + const promptStart = line.indexOf(promptLiteralStart); + if (promptStart === -1) { + console.error("Custom prompt found but no end delimiter", line); + } + const prompt = line + .slice(0, promptStart) + .replace(customPromptLiteralStart, ""); + let value = line.slice(promptStart + promptLiteralStart.length); + useLines.push({ + type: "input", + value: value, + prompt: prompt, + }); + } else { + buffer.push(line); + } + } + saveBuffer(); + const div = document.createElement("div"); + node.replaceWith(div); + const termynal = new Termynal(div, { + lineData: useLines, + noInit: true, + lineDelay: 500, + }); + termynals.push(termynal); + }); + } + + function loadVisibleTermynals() { + termynals = termynals.filter((termynal) => { + if (termynal.container.getBoundingClientRect().top - innerHeight <= 0) { + termynal.init(); + return false; + } + return true; + }); + } + window.addEventListener("scroll", loadVisibleTermynals); + createTermynals(); + loadVisibleTermynals(); +} + +function shuffle(array) { + var currentIndex = array.length, + temporaryValue, + randomIndex; + while (0 !== currentIndex) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + return array; +} + +async function showRandomAnnouncement(groupId, timeInterval) { + const announceFastAPI = document.getElementById(groupId); + if (announceFastAPI) { + let children = [].slice.call(announceFastAPI.children); + children = shuffle(children); + let index = 0; + const announceRandom = () => { + children.forEach((el, i) => { + el.style.display = "none"; + }); + children[index].style.display = "block"; + index = (index + 1) % children.length; + }; + announceRandom(); + setInterval(announceRandom, timeInterval); + } +} + +async function main() { + if (div) { + data = await getData(); + div.innerHTML = "
    "; + const ul = document.querySelector(".github-topic-projects ul"); + data.forEach((v) => { + if (v.full_name === "tiangolo/fastapi") { + return; + } + const li = document.createElement("li"); + li.innerHTML = `
    ★ ${v.stargazers_count} - ${v.full_name} by @${v.owner.login}`; + ul.append(li); + }); + } + + setupTermynal(); + showRandomAnnouncement("announce-left", 5000); + showRandomAnnouncement("announce-right", 10000); +} + +main(); diff --git a/docs/js/termynal.js b/docs/js/termynal.js new file mode 100644 index 0000000..08985f1 --- /dev/null +++ b/docs/js/termynal.js @@ -0,0 +1,283 @@ +/** + * termynal.js + * A lightweight, modern and extensible animated terminal window, using + * async/await. + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + +"use strict"; + +/** Generate a terminal widget. */ +class Termynal { + /** + * Construct the widget's settings. + * @param {(string|Node)=} container - Query selector or container element. + * @param {Object=} options - Custom settings. + * @param {string} options.prefix - Prefix to use for data attributes. + * @param {number} options.startDelay - Delay before animation, in ms. + * @param {number} options.typeDelay - Delay between each typed character, in ms. + * @param {number} options.lineDelay - Delay between each line, in ms. + * @param {number} options.progressLength - Number of characters displayed as progress bar. + * @param {string} options.progressChar – Character to use for progress bar, defaults to █. + * @param {number} options.progressPercent - Max percent of progress. + * @param {string} options.cursor – Character to use for cursor, defaults to ▋. + * @param {Object[]} lineData - Dynamically loaded line data objects. + * @param {boolean} options.noInit - Don't initialise the animation. + */ + constructor(container = "#termynal", options = {}) { + this.container = + typeof container === "string" + ? document.querySelector(container) + : container; + this.pfx = `data-${options.prefix || "ty"}`; + this.originalStartDelay = this.startDelay = + options.startDelay || + parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || + 600; + this.originalTypeDelay = this.typeDelay = + options.typeDelay || + parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || + 90; + this.originalLineDelay = this.lineDelay = + options.lineDelay || + parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || + 1500; + this.progressLength = + options.progressLength || + parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || + 40; + this.progressChar = + options.progressChar || + this.container.getAttribute(`${this.pfx}-progressChar`) || + "█"; + this.progressPercent = + options.progressPercent || + parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || + 100; + this.cursor = + options.cursor || + this.container.getAttribute(`${this.pfx}-cursor`) || + "▋"; + this.lineData = this.lineDataToElements(options.lineData || []); + this.loadLines(); + if (!options.noInit) this.init(); + } + + loadLines() { + // Load all the lines and create the container so that the size is fixed + // Otherwise it would be changing and the user viewport would be constantly + // moving as she/he scrolls + const finish = this.generateFinish(); + finish.style.visibility = "hidden"; + this.container.appendChild(finish); + // Appends dynamically loaded lines to existing line elements. + this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat( + this.lineData + ); + for (let line of this.lines) { + line.style.visibility = "hidden"; + this.container.appendChild(line); + } + const restart = this.generateRestart(); + restart.style.visibility = "hidden"; + this.container.appendChild(restart); + this.container.setAttribute("data-termynal", ""); + } + + /** + * Initialise the widget, get lines, clear container and start animation. + */ + init() { + /** + * Calculates width and height of Termynal container. + * If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS. + */ + const containerStyle = getComputedStyle(this.container); + this.container.style.width = + containerStyle.width !== "0px" ? containerStyle.width : undefined; + this.container.style.minHeight = + containerStyle.height !== "0px" ? containerStyle.height : undefined; + + this.container.setAttribute("data-termynal", ""); + this.container.innerHTML = ""; + for (let line of this.lines) { + line.style.visibility = "visible"; + } + this.start(); + } + + /** + * Start the animation and rener the lines depending on their data attributes. + */ + async start() { + this.addFinish(); + await this._wait(this.startDelay); + + for (let line of this.lines) { + const type = line.getAttribute(this.pfx); + const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay; + + if (type == "input") { + line.setAttribute(`${this.pfx}-cursor`, this.cursor); + await this.type(line); + await this._wait(delay); + } else if (type == "progress") { + await this.progress(line); + await this._wait(delay); + } else { + this.container.appendChild(line); + await this._wait(delay); + } + + line.removeAttribute(`${this.pfx}-cursor`); + } + this.addRestart(); + this.finishElement.style.visibility = "hidden"; + this.lineDelay = this.originalLineDelay; + this.typeDelay = this.originalTypeDelay; + this.startDelay = this.originalStartDelay; + } + + generateRestart() { + const restart = document.createElement("a"); + restart.onclick = (e) => { + e.preventDefault(); + this.container.innerHTML = ""; + this.init(); + }; + restart.href = "#"; + restart.setAttribute("data-terminal-control", ""); + restart.innerHTML = "restart ↻"; + return restart; + } + + generateFinish() { + const finish = document.createElement("a"); + finish.onclick = (e) => { + e.preventDefault(); + this.lineDelay = 0; + this.typeDelay = 0; + this.startDelay = 0; + }; + finish.href = "#"; + finish.setAttribute("data-terminal-control", ""); + finish.innerHTML = "fast →"; + this.finishElement = finish; + return finish; + } + + addRestart() { + const restart = this.generateRestart(); + this.container.appendChild(restart); + } + + addFinish() { + const finish = this.generateFinish(); + this.container.appendChild(finish); + } + + /** + * Animate a typed line. + * @param {Node} line - The line element to render. + */ + async type(line) { + const chars = [...line.textContent]; + line.textContent = ""; + this.container.appendChild(line); + + for (let char of chars) { + const delay = + line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay; + await this._wait(delay); + line.textContent += char; + } + } + + /** + * Animate a progress bar. + * @param {Node} line - The line element to render. + */ + async progress(line) { + const progressLength = + line.getAttribute(`${this.pfx}-progressLength`) || this.progressLength; + const progressChar = + line.getAttribute(`${this.pfx}-progressChar`) || this.progressChar; + const chars = progressChar.repeat(progressLength); + const progressPercent = + line.getAttribute(`${this.pfx}-progressPercent`) || this.progressPercent; + line.textContent = ""; + this.container.appendChild(line); + + for (let i = 1; i < chars.length + 1; i++) { + await this._wait(this.typeDelay); + const percent = Math.round((i / chars.length) * 100); + line.textContent = `${chars.slice(0, i)} ${percent}%`; + if (percent > progressPercent) { + break; + } + } + } + + /** + * Helper function for animation delays, called with `await`. + * @param {number} time - Timeout, in ms. + */ + _wait(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + + /** + * Converts line data objects into line elements. + * + * @param {Object[]} lineData - Dynamically loaded lines. + * @param {Object} line - Line data object. + * @returns {Element[]} - Array of line elements. + */ + lineDataToElements(lineData) { + return lineData.map((line) => { + let div = document.createElement("div"); + div.innerHTML = `${ + line.value || "" + }`; + + return div.firstElementChild; + }); + } + + /** + * Helper function for generating attributes string. + * + * @param {Object} line - Line data object. + * @returns {string} - String of attributes. + */ + _attributes(line) { + let attrs = ""; + for (let prop in line) { + // Custom add class + if (prop === "class") { + attrs += ` class=${line[prop]} `; + continue; + } + if (prop === "type") { + attrs += `${this.pfx}="${line[prop]}" `; + } else if (prop !== "value") { + attrs += `${this.pfx}-${prop}="${line[prop]}" `; + } + } + + return attrs; + } +} + +/** + * HTML API: If current script has container(s) specified, initialise Termynal. + */ +if (document.currentScript.hasAttribute("data-termynal-container")) { + const containers = document.currentScript.getAttribute( + "data-termynal-container" + ); + containers.split("|").forEach((container) => new Termynal(container)); +} diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..449b1af --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1 @@ +First of all, have a look on the [Installation](installation.md) page to install Blitz. Once Blitz is installed, you can start to create your first Blitz project using the Blitz CLI. \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..112a9f5 --- /dev/null +++ b/main.py @@ -0,0 +1,5 @@ +from blitz.cli import app + + +if __name__ == "__main__": + app() diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..18407e4 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,106 @@ +site_name: Blitz +site_url: https://paperz-org.github.io/blitz/ + +repo_name: Paperz-org/blitz +repo_url: https://github.com/Paperz-org/blitz + +theme: + name: material + favicon: "images/logo.png" + icon: + repo: fontawesome/brands/github-alt + annotation: material/plus-circle + logo: "images/logo.png" + palette: + - media: "(prefers-color-scheme: dark)" + primary: black + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + - media: "(prefers-color-scheme: light)" + primary: blue grey + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + features: + - content.tabs.link + - content.code.annotate + - content.code.copy + - announce.dismiss + - navigation.tabs + - navigation.footer + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/Paperz-org + +extra_css: + - css/termynal.css + - css/custom.css +extra_javascript: + - js/termynal.js + - js/custom.js + +plugins: + search: null + mkdocstrings: + handlers: + python: + options: + extensions: + - griffe_typingdoc + show_root_heading: true + show_if_no_docstring: true + preload_modules: + - httpx + - starlette + inherited_members: true + members_order: source + separate_signature: true + unwrap_annotated: true + filters: + - "!^_" + merge_init_into_class: true + docstring_section_style: spacy + signature_crossrefs: true + show_symbol_type_heading: true + show_symbol_type_toc: true + +markdown_extensions: + - attr_list + - md_in_html + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - admonition + - pymdownx.details + - mkdocs-typer + +nav: + - Get Started: + - Welcome to Blitz: index.md + - Features: features.md + - Installation: installation.md + - Quickstart: quickstart.md + - Blitz file: + - Overview: blitzfile/index.md + - Config: blitzfile/config.md + - Resources: blitzfile/resources.md + - Relationships: blitzfile/relationships.md + - Blitz file reference: blitzfile/reference.md + - CLI: + - Installation: cli/index.md + - Commands: + - Create: cli/create.md + - Start: cli/start.md + - List: cli/list.md + - Release: cli/release.md + - References: cli/references.md + - API: + - Blitz API: api/index.md + - Dashboard: + - Dashboard: dashboard.md diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..58756c8 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,2459 @@ +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "aiofiles" +version = "23.2.1" +description = "File support for asyncio." +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiofiles-23.2.1-py3-none-any.whl", hash = "sha256:19297512c647d4b27a2cf7c34caa7e405c0d60b5560618a29a9fe027b18b0107"}, + {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"}, +] + +[[package]] +name = "alembic" +version = "1.13.2.dev0" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.8" +files = [] +develop = false + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.3.0" +typing-extensions = ">=4" + +[package.extras] +tz = ["backports.zoneinfo"] + +[package.source] +type = "git" +url = "https://github.com/mde-pach/alembic.git" +reference = "HEAD" +resolved_reference = "8aa1a02d0bca0096d89ef6957292debe31aed746" + +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + +[[package]] +name = "anyio" +version = "4.2.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, + {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, +] + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "babel" +version = "2.14.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "bidict" +version = "0.22.1" +description = "The bidirectional mapping library for Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "bidict-0.22.1-py3-none-any.whl", hash = "sha256:6ef212238eb884b664f28da76f33f1d28b260f665fc737b413b287d5487d1e7b"}, + {file = "bidict-0.22.1.tar.gz", hash = "sha256:1e0f7f74e4860e6d0943a05d4134c63a2fad86f3d4732fb265bd79e4e856d81d"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton"] +lint = ["pre-commit"] +test = ["hypothesis", "pytest", "pytest-benchmark[histogram]", "pytest-cov", "pytest-xdist", "sortedcollections", "sortedcontainers", "sphinx"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "distro" +version = "1.9.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "dnspython" +version = "2.5.0" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dnspython-2.5.0-py3-none-any.whl", hash = "sha256:6facdf76b73c742ccf2d07add296f178e629da60be23ce4b0a9c927b1e02c3a6"}, + {file = "dnspython-2.5.0.tar.gz", hash = "sha256:a0034815a59ba9ae888946be7ccca8f7c157b286f8455b379c692efb51022a15"}, +] + +[package.extras] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=5.0.3)", "mypy (>=1.0.1)", "pylint (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0.0)", "sphinx (>=7.0.0)", "twine (>=4.0.0)", "wheel (>=0.41.0)"] +dnssec = ["cryptography (>=41)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=0.17.3)", "httpx (>=0.25.1)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1)"] +trio = ["trio (>=0.14)"] +wmi = ["wmi (>=1.5.1)"] + +[[package]] +name = "email-validator" +version = "2.1.0.post1" +description = "A robust email address syntax and deliverability validation library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "email_validator-2.1.0.post1-py3-none-any.whl", hash = "sha256:c973053efbeddfef924dc0bd93f6e77a1ea7ee0fce935aea7103c7a3d6d2d637"}, + {file = "email_validator-2.1.0.post1.tar.gz", hash = "sha256:a4b0bd1cf55f073b924258d19321b1f3aa74b4b5a71a42c305575dba920e1a44"}, +] + +[package.dependencies] +dnspython = ">=2.0.0" +idna = ">=2.0.0" + +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "fastapi" +version = "0.108.0" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.108.0-py3-none-any.whl", hash = "sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7"}, + {file = "fastapi-0.108.0.tar.gz", hash = "sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296"}, +] + +[package.dependencies] +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.29.0,<0.33.0" +typing-extensions = ">=4.8.0" + +[package.extras] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "fastapi-crudrouter" +version = "0.8.6" +description = "A dynamic FastAPI router that automatically creates CRUD routes for your models" +optional = false +python-versions = ">=3.7" +files = [ + {file = "fastapi-crudrouter-0.8.6.tar.gz", hash = "sha256:32704a7aa1d0b23bb6437f717599e9c4c01d8e5a91370a0359837a899a809ceb"}, + {file = "fastapi_crudrouter-0.8.6-py3-none-any.whl", hash = "sha256:4ceb0289cd7b7c687f88581838c032cdb21f24d36971e54b0e594ddcfaf9634e"}, +] + +[package.dependencies] +fastapi = "*" + +[[package]] +name = "fastapi-socketio" +version = "0.0.10" +description = "Easily integrate socket.io with your FastAPI app." +optional = false +python-versions = "*" +files = [ + {file = "fastapi-socketio-0.0.10.tar.gz", hash = "sha256:202f9b319f010001cbd1114ec92a0d9eb5f5ca9316eae5fd41a6088da0812727"}, + {file = "fastapi_socketio-0.0.10-py3-none-any.whl", hash = "sha256:11c2bfa3f25d786bd860ed13c892472e86bfeba85e7a0bec4f922ae5e4d8650f"}, +] + +[package.dependencies] +fastapi = ">=0.61.1" +python-socketio = ">=4.6.0" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "fastui" +version = "0.4.0" +description = "Build better UIs faster." +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastui-0.4.0-py3-none-any.whl", hash = "sha256:ec47383c4d7e7dcb2c0bf01196bf2c0ee28902bb53c267b7c7fdd911818fbc21"}, + {file = "fastui-0.4.0.tar.gz", hash = "sha256:563d5c37b671bf483f8550f7ff2b3f52857d6382329793698b34258eef7e7c56"}, +] + +[package.dependencies] +pydantic = {version = ">=2.5.2", extras = ["email"]} + +[package.extras] +fastapi = ["fastapi (>=0.104)", "python-multipart (>=0.0.6)"] + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "griffe" +version = "0.40.1" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +optional = false +python-versions = ">=3.8" +files = [ + {file = "griffe-0.40.1-py3-none-any.whl", hash = "sha256:5b8c023f366fe273e762131fe4bfd141ea56c09b3cb825aa92d06a82681cfd93"}, + {file = "griffe-0.40.1.tar.gz", hash = "sha256:66c48a62e2ce5784b6940e603300fcfb807b6f099b94e7f753f1841661fd5c7c"}, +] + +[package.dependencies] +colorama = ">=0.4" + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.2" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, + {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.23.0)"] + +[[package]] +name = "httptools" +version = "0.6.1" +description = "A collection of framework independent HTTP protocol utils." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, + {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, + {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, + {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, + {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, + {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, + {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, +] + +[package.extras] +test = ["Cython (>=0.29.24,<0.30.0)"] + +[[package]] +name = "httpx" +version = "0.26.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "ifaddr" +version = "0.2.0" +description = "Cross-platform network interface and IP address enumeration library" +optional = false +python-versions = "*" +files = [ + {file = "ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748"}, + {file = "ifaddr-0.2.0.tar.gz", hash = "sha256:cc0cbfcaabf765d44595825fb96a99bb12c79716b73b44330ea38ee2b0c4aed4"}, +] + +[[package]] +name = "ipython" +version = "8.21.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.10" +files = [ + {file = "ipython-8.21.0-py3-none-any.whl", hash = "sha256:1050a3ab8473488d7eee163796b02e511d0735cf43a04ba2a8348bd0f2eaf8a5"}, + {file = "ipython-8.21.0.tar.gz", hash = "sha256:48fbc236fbe0e138b88773fa0437751f14c3645fb483f1d4c5dee58b37e5ce73"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +prompt-toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" + +[package.extras] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.23)", "pandas", "pickleshare", "pytest (<8)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<8)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pickleshare", "pytest (<8)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "pickleshare", "pytest (<8)", "pytest-asyncio (<0.22)", "testpath", "trio"] + +[[package]] +name = "itsdangerous" +version = "2.1.2" +description = "Safely pass data to untrusted environments and back." +optional = false +python-versions = ">=3.7" +files = [ + {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] + +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "loguru" +version = "0.7.2" +description = "Python logging made (stupidly) simple" +optional = false +python-versions = ">=3.5" +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} +win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} + +[package.extras] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] + +[[package]] +name = "mako" +version = "1.3.2" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Mako-1.3.2-py3-none-any.whl", hash = "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c"}, + {file = "Mako-1.3.2.tar.gz", hash = "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markdown" +version = "3.5.2" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, + {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, +] + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "markdown2" +version = "2.4.10" +description = "A fast and complete Python implementation of Markdown" +optional = false +python-versions = ">=3.5, <4" +files = [ + {file = "markdown2-2.4.10-py2.py3-none-any.whl", hash = "sha256:e6105800483783831f5dc54f827aa5b44eb137ecef5a70293d8ecfbb4109ecc6"}, + {file = "markdown2-2.4.10.tar.gz", hash = "sha256:cdba126d90dc3aef6f4070ac342f974d63f415678959329cc7909f96cc235d72"}, +] + +[package.extras] +all = ["pygments (>=2.7.3)", "wavedrom"] +code-syntax-highlighting = ["pygments (>=2.7.3)"] +wavedrom = ["wavedrom"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.5.3" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "0.5.0" +description = "Automatically link across pages in MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_autorefs-0.5.0-py3-none-any.whl", hash = "sha256:7930fcb8ac1249f10e683967aeaddc0af49d90702af111a5e390e8b20b3d97ff"}, + {file = "mkdocs_autorefs-0.5.0.tar.gz", hash = "sha256:9a5054a94c08d28855cfab967ada10ed5be76e2bfad642302a610b252c3274c0"}, +] + +[package.dependencies] +Markdown = ">=3.3" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-markdownextradata-plugin" +version = "0.2.5" +description = "A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template" +optional = false +python-versions = ">=2.7.9,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +files = [ + {file = "mkdocs-markdownextradata-plugin-0.2.5.tar.gz", hash = "sha256:9c562e8fe375647d5692d11dfe369a7bdd50302174d35995fce2aeca58036ec6"}, +] + +[package.dependencies] +mkdocs = "*" +pyyaml = "*" + +[[package]] +name = "mkdocs-material" +version = "9.5.9" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.9-py3-none-any.whl", hash = "sha256:a5d62b73b3b74349e45472bfadc129c871dd2d4add68d84819580597b2f50d5d"}, + {file = "mkdocs_material-9.5.9.tar.gz", hash = "sha256:635df543c01c25c412d6c22991872267723737d5a2f062490f33b2da1c013c6d"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.5.3,<1.6.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "mkdocs-redirects" +version = "1.2.1" +description = "A MkDocs plugin for dynamic page redirects to prevent broken links." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-redirects-1.2.1.tar.gz", hash = "sha256:9420066d70e2a6bb357adf86e67023dcdca1857f97f07c7fe450f8f1fb42f861"}, +] + +[package.dependencies] +mkdocs = ">=1.1.1" + +[package.extras] +dev = ["autoflake", "black", "isort", "pytest", "twine (>=1.13.0)"] +release = ["twine (>=1.13.0)"] +test = ["autoflake", "black", "isort", "pytest"] + +[[package]] +name = "mkdocs-typer" +version = "0.0.3" +description = "An MkDocs extension to generate documentation for Typer command line applications" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_typer-0.0.3-py3-none-any.whl", hash = "sha256:b2a9a44da590a7100114fde4de9123fedfea692d229379984db20ee3b3f12d7c"}, + {file = "mkdocs_typer-0.0.3.tar.gz", hash = "sha256:4dd37f024190a82aaf0f6c984faafb15167d34eab7e29a6a85e61362423a4eb7"}, +] + +[package.dependencies] +markdown = "==3.*" +typer = "==0.*" + +[[package]] +name = "mkdocstrings" +version = "0.24.0" +description = "Automatic documentation from sources, for MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings-0.24.0-py3-none-any.whl", hash = "sha256:f4908560c10f587326d8f5165d1908817b2e280bbf707607f601c996366a2264"}, + {file = "mkdocstrings-0.24.0.tar.gz", hash = "sha256:222b1165be41257b494a9d29b14135d2b7ca43f38161d5b10caae03b87bd4f7e"}, +] + +[package.dependencies] +click = ">=7.0" +Jinja2 = ">=2.11.1" +Markdown = ">=3.3" +MarkupSafe = ">=1.1" +mkdocs = ">=1.4" +mkdocs-autorefs = ">=0.3.1" +mkdocstrings-python = {version = ">=0.5.2", optional = true, markers = "extra == \"python\""} +platformdirs = ">=2.2.0" +pymdown-extensions = ">=6.3" + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "1.8.0" +description = "A Python handler for mkdocstrings." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings_python-1.8.0-py3-none-any.whl", hash = "sha256:4209970cc90bec194568682a535848a8d8489516c6ed4adbe58bbc67b699ca9d"}, + {file = "mkdocstrings_python-1.8.0.tar.gz", hash = "sha256:1488bddf50ee42c07d9a488dddc197f8e8999c2899687043ec5dd1643d057192"}, +] + +[package.dependencies] +griffe = ">=0.37" +mkdocstrings = ">=0.20" + +[[package]] +name = "nicegui" +version = "1.4.9" +description = "Create web-based user interfaces with Python. The nice way." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "nicegui-1.4.9-py3-none-any.whl", hash = "sha256:bfcee1de68b65870676f95416fd55ccae63d486219afa511e401c7b2b81c6801"}, + {file = "nicegui-1.4.9.tar.gz", hash = "sha256:330e0f4276ae206e06c68f29f9741325b4db3fec70e78a902137e6e8e9402ffd"}, +] + +[package.dependencies] +aiofiles = ">=23.1.0,<24.0.0" +fastapi = ">=0.108.0,<1.0.0" +fastapi-socketio = ">=0.0.10,<0.0.11" +httpx = ">=0.24.0,<1.0.0" +ifaddr = ">=0.2.0,<0.3.0" +itsdangerous = ">=2.1.2,<3.0.0" +jinja2 = ">=3.1.2,<4.0.0" +markdown2 = ">=2.4.7,<2.4.11" +orjson = {version = ">=3.8.6,<4.0.0", markers = "platform_machine != \"i386\" and platform_machine != \"i686\""} +Pygments = ">=2.15.1,<3.0.0" +python-multipart = ">=0.0.6,<0.0.7" +python-socketio = ">=5.10.0" +typing-extensions = ">=4.0.0" +uvicorn = {version = ">=0.22.0", extras = ["standard"]} +vbuild = ">=0.8.2" +watchfiles = ">=0.18.1,<1.0.0" + +[package.extras] +highcharts = ["nicegui-highcharts (>=1.0.1,<2.0.0)"] +matplotlib = ["matplotlib (>=3.5.0,<4.0.0)"] +native = ["pywebview (>=4.4.0,<5.0.0)"] +plotly = ["plotly (>=5.13.0,<6.0.0)"] + +[[package]] +name = "openai" +version = "1.12.0" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "openai-1.12.0-py3-none-any.whl", hash = "sha256:a54002c814e05222e413664f651b5916714e4700d041d5cf5724d3ae1a3e3481"}, + {file = "openai-1.12.0.tar.gz", hash = "sha256:99c5d257d09ea6533d689d1cc77caa0ac679fa21efef8893d8b0832a86877f1b"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.7,<5" + +[package.extras] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] + +[[package]] +name = "orjson" +version = "3.9.13" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.9.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fa6b67f8bef277c2a4aadd548d58796854e7d760964126c3209b19bccc6a74f1"}, + {file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b812417199eeb169c25f67815cfb66fd8de7ff098bf57d065e8c1943a7ba5c8f"}, + {file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ccd5bd222e5041069ad9d9868ab59e6dbc53ecde8d8c82b919954fbba43b46b"}, + {file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaaf80957c38e9d3f796f355a80fad945e72cd745e6b64c210e635b7043b673e"}, + {file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:60da7316131185d0110a1848e9ad15311e6c8938ee0b5be8cbd7261e1d80ee8f"}, + {file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b98cd948372f0eb219bc309dee4633db1278687161e3280d9e693b6076951d2"}, + {file = "orjson-3.9.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3869d65561f10071d3e7f35ae58fd377056f67d7aaed5222f318390c3ad30339"}, + {file = "orjson-3.9.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43fd6036b16bb6742d03dae62f7bdf8214d06dea47e4353cde7e2bd1358d186f"}, + {file = "orjson-3.9.13-cp310-none-win32.whl", hash = "sha256:0d3ba9d88e20765335260d7b25547d7c571eee2b698200f97afa7d8c7cd668fc"}, + {file = "orjson-3.9.13-cp310-none-win_amd64.whl", hash = "sha256:6e47153db080f5e87e8ba638f1a8b18995eede6b0abb93964d58cf11bcea362f"}, + {file = "orjson-3.9.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4584e8eb727bc431baaf1bf97e35a1d8a0109c924ec847395673dfd5f4ef6d6f"}, + {file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f37f0cdd026ef777a4336e599d8194c8357fc14760c2a5ddcfdf1965d45504b"}, + {file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d714595d81efab11b42bccd119977d94b25d12d3a806851ff6bfd286a4bce960"}, + {file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9171e8e1a1f221953e38e84ae0abffe8759002fd8968106ee379febbb5358b33"}, + {file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ab9dbdec3f13f3ea6f937564ce21651844cfbf2725099f2f490426acf683c23"}, + {file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811ac076855e33e931549340288e0761873baf29276ad00f221709933c644330"}, + {file = "orjson-3.9.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:860d0f5b42d0c0afd73fa4177709f6e1b966ba691fcd72175affa902052a81d6"}, + {file = "orjson-3.9.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:838b898e8c1f26eb6b8d81b180981273f6f5110c76c22c384979aca854194f1b"}, + {file = "orjson-3.9.13-cp311-none-win32.whl", hash = "sha256:d3222db9df629ef3c3673124f2e05fb72bc4a320c117e953fec0d69dde82e36d"}, + {file = "orjson-3.9.13-cp311-none-win_amd64.whl", hash = "sha256:978117122ca4cc59b28af5322253017f6c5fc03dbdda78c7f4b94ae984c8dd43"}, + {file = "orjson-3.9.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:031df1026c7ea8303332d78711f180231e3ae8b564271fb748a03926587c5546"}, + {file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fd9a2101d04e85086ea6198786a3f016e45475f800712e6833e14bf9ce2832f"}, + {file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:446d9ad04204e79229ae19502daeea56479e55cbc32634655d886f5a39e91b44"}, + {file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b57c0954a9fdd2b05b9cec0f5a12a0bdce5bf021a5b3b09323041613972481ab"}, + {file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:266e55c83f81248f63cc93d11c5e3a53df49a5d2598fa9e9db5f99837a802d5d"}, + {file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31372ba3a9fe8ad118e7d22fba46bbc18e89039e3bfa89db7bc8c18ee722dca8"}, + {file = "orjson-3.9.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e3b0c4da61f39899561e08e571f54472a09fa71717d9797928af558175ae5243"}, + {file = "orjson-3.9.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cc03a35bfc71c8ebf96ce49b82c2a7be6af4b3cd3ac34166fdb42ac510bbfff"}, + {file = "orjson-3.9.13-cp312-none-win_amd64.whl", hash = "sha256:49b7e3fe861cb246361825d1a238f2584ed8ea21e714bf6bb17cebb86772e61c"}, + {file = "orjson-3.9.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:62e9a99879c4d5a04926ac2518a992134bfa00d546ea5a4cae4b9be454d35a22"}, + {file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d92a3e835a5100f1d5b566fff79217eab92223ca31900dba733902a182a35ab0"}, + {file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23f21faf072ed3b60b5954686f98157e073f6a8068eaa58dbde83e87212eda84"}, + {file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:828c502bb261588f7de897e06cb23c4b122997cb039d2014cb78e7dabe92ef0c"}, + {file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16946d095212a3dec552572c5d9bca7afa40f3116ad49695a397be07d529f1fa"}, + {file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3deadd8dc0e9ff844b5b656fa30a48dbee1c3b332d8278302dd9637f6b09f627"}, + {file = "orjson-3.9.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9b1b5adc5adf596c59dca57156b71ad301d73956f5bab4039b0e34dbf50b9fa0"}, + {file = "orjson-3.9.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ddc089315d030c54f0f03fb38286e2667c05009a78d659f108a8efcfbdf2e585"}, + {file = "orjson-3.9.13-cp38-none-win32.whl", hash = "sha256:ae77275a28667d9c82d4522b681504642055efa0368d73108511647c6499b31c"}, + {file = "orjson-3.9.13-cp38-none-win_amd64.whl", hash = "sha256:730385fdb99a21fce9bb84bb7fcbda72c88626facd74956bda712834b480729d"}, + {file = "orjson-3.9.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7e8e4a571d958910272af8d53a9cbe6599f9f5fd496a1bc51211183bb2072cbd"}, + {file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfad553a36548262e7da0f3a7464270e13900b898800fb571a5d4b298c3f8356"}, + {file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d691c44604941945b00e0a13b19a7d9c1a19511abadf0080f373e98fdeb6b31"}, + {file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8c83718346de08d68b3cb1105c5d91e5fc39885d8610fdda16613d4e3941459"}, + {file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63ef57a53bfc2091a7cd50a640d9ae866bd7d92a5225a1bab6baa60ef62583f2"}, + {file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9156b96afa38db71344522f5517077eaedf62fcd2c9148392ff93d801128809c"}, + {file = "orjson-3.9.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31fb66b41fb2c4c817d9610f0bc7d31345728d7b5295ac78b63603407432a2b2"}, + {file = "orjson-3.9.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8a730bf07feacb0863974e67b206b7c503a62199de1cece2eb0d4c233ec29c11"}, + {file = "orjson-3.9.13-cp39-none-win32.whl", hash = "sha256:5ef58869f3399acbbe013518d8b374ee9558659eef14bca0984f67cb1fbd3c37"}, + {file = "orjson-3.9.13-cp39-none-win_amd64.whl", hash = "sha256:9bcf56efdb83244cde070e82a69c0f03c47c235f0a5cb6c81d9da23af7fbaae4"}, + {file = "orjson-3.9.13.tar.gz", hash = "sha256:fc6bc65b0cf524ee042e0bc2912b9206ef242edfba7426cf95763e4af01f527a"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pick" +version = "2.2.0" +description = "Pick an option in the terminal with a simple GUI" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pick-2.2.0-py3-none-any.whl", hash = "sha256:d301f358ee8eabe501795bb38a5160e05db68c0a89eb7ba38c7b667fc4673c8d"}, + {file = "pick-2.2.0.tar.gz", hash = "sha256:96920ebcfb9b8b6c2e50d9f211a700e5036611904169587a5a9245a645637a0d"}, +] + +[package.dependencies] +windows-curses = {version = ">=2.2.0,<3.0.0", markers = "sys_platform == \"win32\""} + +[[package]] +name = "platformdirs" +version = "4.2.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.43" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "pscript" +version = "0.7.7" +description = "Python to JavaScript compiler." +optional = false +python-versions = "*" +files = [ + {file = "pscript-0.7.7-py3-none-any.whl", hash = "sha256:b0fdac0df0393a4d7497153fea6a82e6429f32327c4c0a4817f1cd68adc08083"}, + {file = "pscript-0.7.7.tar.gz", hash = "sha256:8632f7a4483f235514aadee110edee82eb6d67336bf68744a7b18d76e50442f8"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "pydantic" +version = "2.6.1" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.6.1-py3-none-any.whl", hash = "sha256:0b6a909df3192245cb736509a92ff69e4fef76116feffec68e93a567347bae6f"}, + {file = "pydantic-2.6.1.tar.gz", hash = "sha256:4fd5c182a2488dc63e6d32737ff19937888001e2a6d86e94b3f233104a5d1fa9"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""} +pydantic-core = "2.16.2" +typing-extensions = ">=4.6.1" + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.16.2" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3fab4e75b8c525a4776e7630b9ee48aea50107fea6ca9f593c98da3f4d11bf7c"}, + {file = "pydantic_core-2.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8bde5b48c65b8e807409e6f20baee5d2cd880e0fad00b1a811ebc43e39a00ab2"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2924b89b16420712e9bb8192396026a8fbd6d8726224f918353ac19c4c043d2a"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16aa02e7a0f539098e215fc193c8926c897175d64c7926d00a36188917717a05"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:936a787f83db1f2115ee829dd615c4f684ee48ac4de5779ab4300994d8af325b"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:459d6be6134ce3b38e0ef76f8a672924460c455d45f1ad8fdade36796df1ddc8"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9ee4febb249c591d07b2d4dd36ebcad0ccd128962aaa1801508320896575ef"}, + {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40a0bd0bed96dae5712dab2aba7d334a6c67cbcac2ddfca7dbcc4a8176445990"}, + {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:870dbfa94de9b8866b37b867a2cb37a60c401d9deb4a9ea392abf11a1f98037b"}, + {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:308974fdf98046db28440eb3377abba274808bf66262e042c412eb2adf852731"}, + {file = "pydantic_core-2.16.2-cp310-none-win32.whl", hash = "sha256:a477932664d9611d7a0816cc3c0eb1f8856f8a42435488280dfbf4395e141485"}, + {file = "pydantic_core-2.16.2-cp310-none-win_amd64.whl", hash = "sha256:8f9142a6ed83d90c94a3efd7af8873bf7cefed2d3d44387bf848888482e2d25f"}, + {file = "pydantic_core-2.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:406fac1d09edc613020ce9cf3f2ccf1a1b2f57ab00552b4c18e3d5276c67eb11"}, + {file = "pydantic_core-2.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce232a6170dd6532096cadbf6185271e4e8c70fc9217ebe105923ac105da9978"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90fec23b4b05a09ad988e7a4f4e081711a90eb2a55b9c984d8b74597599180f"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8aafeedb6597a163a9c9727d8a8bd363a93277701b7bfd2749fbefee2396469e"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9957433c3a1b67bdd4c63717eaf174ebb749510d5ea612cd4e83f2d9142f3fc8"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0d7a9165167269758145756db43a133608a531b1e5bb6a626b9ee24bc38a8f7"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dffaf740fe2e147fedcb6b561353a16243e654f7fe8e701b1b9db148242e1272"}, + {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8ed79883b4328b7f0bd142733d99c8e6b22703e908ec63d930b06be3a0e7113"}, + {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cf903310a34e14651c9de056fcc12ce090560864d5a2bb0174b971685684e1d8"}, + {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46b0d5520dbcafea9a8645a8164658777686c5c524d381d983317d29687cce97"}, + {file = "pydantic_core-2.16.2-cp311-none-win32.whl", hash = "sha256:70651ff6e663428cea902dac297066d5c6e5423fda345a4ca62430575364d62b"}, + {file = "pydantic_core-2.16.2-cp311-none-win_amd64.whl", hash = "sha256:98dc6f4f2095fc7ad277782a7c2c88296badcad92316b5a6e530930b1d475ebc"}, + {file = "pydantic_core-2.16.2-cp311-none-win_arm64.whl", hash = "sha256:ef6113cd31411eaf9b39fc5a8848e71c72656fd418882488598758b2c8c6dfa0"}, + {file = "pydantic_core-2.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:88646cae28eb1dd5cd1e09605680c2b043b64d7481cdad7f5003ebef401a3039"}, + {file = "pydantic_core-2.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b883af50eaa6bb3299780651e5be921e88050ccf00e3e583b1e92020333304b"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bf26c2e2ea59d32807081ad51968133af3025c4ba5753e6a794683d2c91bf6e"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99af961d72ac731aae2a1b55ccbdae0733d816f8bfb97b41909e143de735f522"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02906e7306cb8c5901a1feb61f9ab5e5c690dbbeaa04d84c1b9ae2a01ebe9379"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5362d099c244a2d2f9659fb3c9db7c735f0004765bbe06b99be69fbd87c3f15"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ac426704840877a285d03a445e162eb258924f014e2f074e209d9b4ff7bf380"}, + {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b94cbda27267423411c928208e89adddf2ea5dd5f74b9528513f0358bba019cb"}, + {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6db58c22ac6c81aeac33912fb1af0e930bc9774166cdd56eade913d5f2fff35e"}, + {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396fdf88b1b503c9c59c84a08b6833ec0c3b5ad1a83230252a9e17b7dfb4cffc"}, + {file = "pydantic_core-2.16.2-cp312-none-win32.whl", hash = "sha256:7c31669e0c8cc68400ef0c730c3a1e11317ba76b892deeefaf52dcb41d56ed5d"}, + {file = "pydantic_core-2.16.2-cp312-none-win_amd64.whl", hash = "sha256:a3b7352b48fbc8b446b75f3069124e87f599d25afb8baa96a550256c031bb890"}, + {file = "pydantic_core-2.16.2-cp312-none-win_arm64.whl", hash = "sha256:a9e523474998fb33f7c1a4d55f5504c908d57add624599e095c20fa575b8d943"}, + {file = "pydantic_core-2.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ae34418b6b389d601b31153b84dce480351a352e0bb763684a1b993d6be30f17"}, + {file = "pydantic_core-2.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:732bd062c9e5d9582a30e8751461c1917dd1ccbdd6cafb032f02c86b20d2e7ec"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b52776a2e3230f4854907a1e0946eec04d41b1fc64069ee774876bbe0eab55"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef551c053692b1e39e3f7950ce2296536728871110e7d75c4e7753fb30ca87f4"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ebb892ed8599b23fa8f1799e13a12c87a97a6c9d0f497525ce9858564c4575a4"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa6c8c582036275997a733427b88031a32ffa5dfc3124dc25a730658c47a572f"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ba0884a91f1aecce75202473ab138724aa4fb26d7707f2e1fa6c3e68c84fbf"}, + {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7924e54f7ce5d253d6160090ddc6df25ed2feea25bfb3339b424a9dd591688bc"}, + {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69a7b96b59322a81c2203be537957313b07dd333105b73db0b69212c7d867b4b"}, + {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e6231aa5bdacda78e96ad7b07d0c312f34ba35d717115f4b4bff6cb87224f0f"}, + {file = "pydantic_core-2.16.2-cp38-none-win32.whl", hash = "sha256:41dac3b9fce187a25c6253ec79a3f9e2a7e761eb08690e90415069ea4a68ff7a"}, + {file = "pydantic_core-2.16.2-cp38-none-win_amd64.whl", hash = "sha256:f685dbc1fdadb1dcd5b5e51e0a378d4685a891b2ddaf8e2bba89bd3a7144e44a"}, + {file = "pydantic_core-2.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:55749f745ebf154c0d63d46c8c58594d8894b161928aa41adbb0709c1fe78b77"}, + {file = "pydantic_core-2.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b30b0dd58a4509c3bd7eefddf6338565c4905406aee0c6e4a5293841411a1286"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18de31781cdc7e7b28678df7c2d7882f9692ad060bc6ee3c94eb15a5d733f8f7"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5864b0242f74b9dd0b78fd39db1768bc3f00d1ffc14e596fd3e3f2ce43436a33"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8f9186ca45aee030dc8234118b9c0784ad91a0bb27fc4e7d9d6608a5e3d386c"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc6f6c9be0ab6da37bc77c2dda5f14b1d532d5dbef00311ee6e13357a418e646"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa057095f621dad24a1e906747179a69780ef45cc8f69e97463692adbcdae878"}, + {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ad84731a26bcfb299f9eab56c7932d46f9cad51c52768cace09e92a19e4cf55"}, + {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3b052c753c4babf2d1edc034c97851f867c87d6f3ea63a12e2700f159f5c41c3"}, + {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0f686549e32ccdb02ae6f25eee40cc33900910085de6aa3790effd391ae10c2"}, + {file = "pydantic_core-2.16.2-cp39-none-win32.whl", hash = "sha256:7afb844041e707ac9ad9acad2188a90bffce2c770e6dc2318be0c9916aef1469"}, + {file = "pydantic_core-2.16.2-cp39-none-win_amd64.whl", hash = "sha256:9da90d393a8227d717c19f5397688a38635afec89f2e2d7af0df037f3249c39a"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f60f920691a620b03082692c378661947d09415743e437a7478c309eb0e4f82"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:47924039e785a04d4a4fa49455e51b4eb3422d6eaacfde9fc9abf8fdef164e8a"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6294e76b0380bb7a61eb8a39273c40b20beb35e8c87ee101062834ced19c545"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe56851c3f1d6f5384b3051c536cc81b3a93a73faf931f404fef95217cf1e10d"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d776d30cde7e541b8180103c3f294ef7c1862fd45d81738d156d00551005784"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:72f7919af5de5ecfaf1eba47bf9a5d8aa089a3340277276e5636d16ee97614d7"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4bfcbde6e06c56b30668a0c872d75a7ef3025dc3c1823a13cf29a0e9b33f67e8"}, + {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ff7c97eb7a29aba230389a2661edf2e9e06ce616c7e35aa764879b6894a44b25"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9b5f13857da99325dcabe1cc4e9e6a3d7b2e2c726248ba5dd4be3e8e4a0b6d0e"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7e41e3ada4cca5f22b478c08e973c930e5e6c7ba3588fb8e35f2398cdcc1545"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60eb8ceaa40a41540b9acae6ae7c1f0a67d233c40dc4359c256ad2ad85bdf5e5"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7beec26729d496a12fd23cf8da9944ee338c8b8a17035a560b585c36fe81af20"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22c5f022799f3cd6741e24f0443ead92ef42be93ffda0d29b2597208c94c3753"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:eca58e319f4fd6df004762419612122b2c7e7d95ffafc37e890252f869f3fb2a"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed957db4c33bc99895f3a1672eca7e80e8cda8bd1e29a80536b4ec2153fa9804"}, + {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:459c0d338cc55d099798618f714b21b7ece17eb1a87879f2da20a3ff4c7628e2"}, + {file = "pydantic_core-2.16.2.tar.gz", hash = "sha256:0ba503850d8b8dcc18391f10de896ae51d37fe5fe43dbfb6a35c5c5cad271a06"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pydantic-settings" +version = "2.1.0" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_settings-2.1.0-py3-none-any.whl", hash = "sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a"}, + {file = "pydantic_settings-2.1.0.tar.gz", hash = "sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c"}, +] + +[package.dependencies] +pydantic = ">=2.3.0" +python-dotenv = ">=0.21.0" + +[[package]] +name = "pygments" +version = "2.17.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, +] + +[package.extras] +plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pymdown-extensions" +version = "10.7" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"}, + {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"}, +] + +[package.dependencies] +markdown = ">=3.5" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "python-engineio" +version = "4.9.0" +description = "Engine.IO server and client for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-engineio-4.9.0.tar.gz", hash = "sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7"}, + {file = "python_engineio-4.9.0-py3-none-any.whl", hash = "sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c"}, +] + +[package.dependencies] +simple-websocket = ">=0.10.0" + +[package.extras] +asyncio-client = ["aiohttp (>=3.4)"] +client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] +docs = ["sphinx"] + +[[package]] +name = "python-multipart" +version = "0.0.6" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, + {file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"}, +] + +[package.extras] +dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] + +[[package]] +name = "python-socketio" +version = "5.11.1" +description = "Socket.IO server and client for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-socketio-5.11.1.tar.gz", hash = "sha256:bbcbd758ed8c183775cb2853ba001361e2fa018babf5cbe11a5b77e91c2ec2a2"}, + {file = "python_socketio-5.11.1-py3-none-any.whl", hash = "sha256:f1a0228b8b1fbdbd93fbbedd821ebce0ef54b2b5bf6e98fcf710deaa7c574259"}, +] + +[package.dependencies] +bidict = ">=0.21.0" +python-engineio = ">=4.8.0" + +[package.extras] +asyncio-client = ["aiohttp (>=3.4)"] +client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] +docs = ["sphinx"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rich" +version = "13.7.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.0-py3-none-any.whl", hash = "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235"}, + {file = "rich-13.7.0.tar.gz", hash = "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "semver" +version = "3.0.2" +description = "Python helper for Semantic Versioning (https://semver.org)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "semver-3.0.2-py3-none-any.whl", hash = "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4"}, + {file = "semver-3.0.2.tar.gz", hash = "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc"}, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "simple-websocket" +version = "1.0.0" +description = "Simple WebSocket server and client for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "simple-websocket-1.0.0.tar.gz", hash = "sha256:17d2c72f4a2bd85174a97e3e4c88b01c40c3f81b7b648b0cc3ce1305968928c8"}, + {file = "simple_websocket-1.0.0-py3-none-any.whl", hash = "sha256:1d5bf585e415eaa2083e2bcf02a3ecf91f9712e7b3e6b9fa0b461ad04e0837bc"}, +] + +[package.dependencies] +wsproto = "*" + +[package.extras] +docs = ["sphinx"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.27" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d04e579e911562f1055d26dab1868d3e0bb905db3bccf664ee8ad109f035618a"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c7a596d0be71b7baa037f4ac10d5e057d276f65a9a611c46970f012752ebf2d"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954d9735ee9c3fa74874c830d089a815b7b48df6f6b6e357a74130e478dbd951"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5cd20f58c29bbf2680039ff9f569fa6d21453fbd2fa84dbdb4092f006424c2e6"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:03f448ffb731b48323bda68bcc93152f751436ad6037f18a42b7e16af9e91c07"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-win32.whl", hash = "sha256:d997c5938a08b5e172c30583ba6b8aad657ed9901fc24caf3a7152eeccb2f1b4"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-win_amd64.whl", hash = "sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c5bad7c60a392850d2f0fee8f355953abaec878c483dd7c3836e0089f046bf6"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3012ab65ea42de1be81fff5fb28d6db893ef978950afc8130ba707179b4284a"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbcd77c4d94b23e0753c5ed8deba8c69f331d4fd83f68bfc9db58bc8983f49cd"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d177b7e82f6dd5e1aebd24d9c3297c70ce09cd1d5d37b43e53f39514379c029c"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:680b9a36029b30cf063698755d277885d4a0eab70a2c7c6e71aab601323cba45"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1306102f6d9e625cebaca3d4c9c8f10588735ef877f0360b5cdb4fdfd3fd7131"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-win32.whl", hash = "sha256:5b78aa9f4f68212248aaf8943d84c0ff0f74efc65a661c2fc68b82d498311fd5"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-win_amd64.whl", hash = "sha256:15e19a84b84528f52a68143439d0c7a3a69befcd4f50b8ef9b7b69d2628ae7c4"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0de1263aac858f288a80b2071990f02082c51d88335a1db0d589237a3435fe71"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce850db091bf7d2a1f2fdb615220b968aeff3849007b1204bf6e3e50a57b3d32"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dfc936870507da96aebb43e664ae3a71a7b96278382bcfe84d277b88e379b18"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4fbe6a766301f2e8a4519f4500fe74ef0a8509a59e07a4085458f26228cd7cc"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4535c49d961fe9a77392e3a630a626af5baa967172d42732b7a43496c8b28876"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0fb3bffc0ced37e5aa4ac2416f56d6d858f46d4da70c09bb731a246e70bff4d5"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-win32.whl", hash = "sha256:7f470327d06400a0aa7926b375b8e8c3c31d335e0884f509fe272b3c700a7254"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-win_amd64.whl", hash = "sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e97cf143d74a7a5a0f143aa34039b4fecf11343eed66538610debc438685db4a"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7b5a3e2120982b8b6bd1d5d99e3025339f7fb8b8267551c679afb39e9c7c7f1"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e36aa62b765cf9f43a003233a8c2d7ffdeb55bc62eaa0a0380475b228663a38f"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5ada0438f5b74c3952d916c199367c29ee4d6858edff18eab783b3978d0db16d"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b1d9d1bfd96eef3c3faedb73f486c89e44e64e40e5bfec304ee163de01cf996f"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-win32.whl", hash = "sha256:ca891af9f3289d24a490a5fde664ea04fe2f4984cd97e26de7442a4251bd4b7c"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-win_amd64.whl", hash = "sha256:fd8aafda7cdff03b905d4426b714601c0978725a19efc39f5f207b86d188ba01"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec1f5a328464daf7a1e4e385e4f5652dd9b1d12405075ccba1df842f7774b4fc"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ad862295ad3f644e3c2c0d8b10a988e1600d3123ecb48702d2c0f26771f1c396"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48217be1de7d29a5600b5c513f3f7664b21d32e596d69582be0a94e36b8309cb"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e56afce6431450442f3ab5973156289bd5ec33dd618941283847c9fd5ff06bf"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:611068511b5531304137bcd7fe8117c985d1b828eb86043bd944cebb7fae3910"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b86abba762ecfeea359112b2bb4490802b340850bbee1948f785141a5e020de8"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-win32.whl", hash = "sha256:30d81cc1192dc693d49d5671cd40cdec596b885b0ce3b72f323888ab1c3863d5"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-win_amd64.whl", hash = "sha256:120af1e49d614d2525ac247f6123841589b029c318b9afbfc9e2b70e22e1827d"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d07ee7793f2aeb9b80ec8ceb96bc8cc08a2aec8a1b152da1955d64e4825fcbac"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb0845e934647232b6ff5150df37ceffd0b67b754b9fdbb095233deebcddbd4a"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc19ae2e07a067663dd24fca55f8ed06a288384f0e6e3910420bf4b1270cc51"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b90053be91973a6fb6020a6e44382c97739736a5a9d74e08cc29b196639eb979"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2f5c9dfb0b9ab5e3a8a00249534bdd838d943ec4cfb9abe176a6c33408430230"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33e8bde8fff203de50399b9039c4e14e42d4d227759155c21f8da4a47fc8053c"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-win32.whl", hash = "sha256:d873c21b356bfaf1589b89090a4011e6532582b3a8ea568a00e0c3aab09399dd"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-win_amd64.whl", hash = "sha256:ff2f1b7c963961d41403b650842dc2039175b906ab2093635d8319bef0b7d620"}, + {file = "SQLAlchemy-2.0.27-py3-none-any.whl", hash = "sha256:1ab4e0448018d01b142c916cc7119ca573803a4745cfe341b8f95657812700ac"}, + {file = "SQLAlchemy-2.0.27.tar.gz", hash = "sha256:86a6ed69a71fe6b88bf9331594fa390a2adda4a49b5c06f98e47bf0d392534f8"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sqlmodel" +version = "0.0.14" +description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "sqlmodel-0.0.14-py3-none-any.whl", hash = "sha256:accea3ff5d878e41ac439b11e78613ed61ce300cfcb860e87a2d73d4884cbee4"}, + {file = "sqlmodel-0.0.14.tar.gz", hash = "sha256:0bff8fc94af86b44925aa813f56cf6aabdd7f156b73259f2f60692c6a64ac90e"}, +] + +[package.dependencies] +pydantic = ">=1.10.13,<3.0.0" +SQLAlchemy = ">=2.0.0,<2.1.0" + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "starlette" +version = "0.32.0.post1" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette-0.32.0.post1-py3-none-any.whl", hash = "sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09"}, + {file = "starlette-0.32.0.post1.tar.gz", hash = "sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] + +[[package]] +name = "starlette-admin" +version = "0.13.2" +description = "Fast, beautiful and extensible administrative interface framework for Starlette/FastApi applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette_admin-0.13.2-py3-none-any.whl", hash = "sha256:95b60ce71f05696df49d95b8664726abb9e3f76a44b49aeea25d1d6b68c039ed"}, + {file = "starlette_admin-0.13.2.tar.gz", hash = "sha256:4a2ee4e5e24b49aaaa6c034ba7f538a6accdd736c4ae7ea2c38cfb0c2c09bcce"}, +] + +[package.dependencies] +jinja2 = ">=3,<4" +python-multipart = "*" +starlette = "*" + +[package.extras] +cov = ["coverage[toml] (>=7.0.0,<7.4.0)"] +dev = ["pre-commit (>=2.20.0,<4.0.0)", "uvicorn (>=0.20.0,<0.26.0)"] +doc = ["mkdocs (>=1.4.2,<2.0.0)", "mkdocs-material (>=9.0.0,<10.0.0)", "mkdocs-static-i18n (>=0.53.0,<0.57.0)", "mkdocstrings[python] (>=0.19.0,<0.25.0)"] +i18n = ["babel (>=2.13.0)"] +test = ["aiomysql (>=0.1.1,<0.3.0)", "aiosqlite (>=0.17.0,<0.20.0)", "arrow (>=1.2.3,<1.4.0)", "asyncpg (>=0.27.0,<0.30.0)", "backports-zoneinfo", "black (==24.1.1)", "colour (>=0.1.5,<0.2.0)", "fasteners (==0.19)", "httpx (>=0.23.3,<0.27.0)", "itsdangerous (>=2.1.2,<2.2.0)", "mongoengine (>=0.25.0,<0.28.0)", "mypy (==1.8.0)", "odmantic (>=0.9.0,<0.10.0)", "passlib (>=1.7.4,<1.8.0)", "phonenumbers (>=8.13.3,<8.14.0)", "pillow (>=9.4.0,<9.6.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pydantic[email] (>=1.10.2,<2.6.0)", "pymysql[rsa] (>=1.0.2,<1.2.0)", "pytest (>=7.2.0,<7.5.0)", "pytest-asyncio (>=0.20.2,<0.24.0)", "ruff (==0.1.15)", "sqlalchemy-file (>=0.5.0,<0.7.0)", "sqlalchemy-utils (>=0.40.0,<0.42.0)", "sqlmodel (>=0.0.11,<0.15.0)", "tinydb (>=4.7.0,<4.9.0)"] + +[[package]] +name = "tqdm" +version = "4.66.2" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, + {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "traitlets" +version = "5.14.1" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, + {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "typer" +version = "0.9.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.6" +files = [ + {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, + {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, +] + +[package.dependencies] +click = ">=7.1.1,<9.0.0" +colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""} +rich = {version = ">=10.11.0,<14.0.0", optional = true, markers = "extra == \"all\""} +shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""} +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] +doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.12" +description = "Typing stubs for PyYAML" +optional = false +python-versions = "*" +files = [ + {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"}, + {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"}, +] + +[[package]] +name = "typing-extensions" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, +] + +[[package]] +name = "urllib3" +version = "2.2.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"}, + {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "uvicorn" +version = "0.27.1" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.8" +files = [ + {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"}, + {file = "uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} +h11 = ">=0.8" +httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "uvloop" +version = "0.19.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] + +[[package]] +name = "vbuild" +version = "0.8.2" +description = "A simple module to extract html/script/style from a vuejs '.vue' file (can minimize/es2015 compliant js) ... just py2 or py3, NO nodejs !" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "vbuild-0.8.2-py2.py3-none-any.whl", hash = "sha256:d76bcc976a1c53b6a5776ac947606f9e7786c25df33a587ebe33ed09dd8a1076"}, + {file = "vbuild-0.8.2.tar.gz", hash = "sha256:270cd9078349d907dfae6c0e6364a5a5e74cb86183bb5093613f12a18b435fa9"}, +] + +[package.dependencies] +pscript = ">=0.7.0,<0.8.0" + +[[package]] +name = "watchdog" +version = "4.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "watchfiles" +version = "0.21.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, + {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, + {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, + {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, + {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, + {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, + {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, + {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, + {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, + {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, + {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, + {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, + {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, + {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, + {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "websockets" +version = "12.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + +[[package]] +name = "win32-setctime" +version = "1.1.0" +description = "A small Python utility to set file creation time on Windows" +optional = false +python-versions = ">=3.5" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] + +[package.extras] +dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] + +[[package]] +name = "windows-curses" +version = "2.3.2" +description = "Support for the standard curses module on Windows" +optional = false +python-versions = "*" +files = [ + {file = "windows_curses-2.3.2-cp310-cp310-win32.whl", hash = "sha256:0286d35c9a2589731af3cf2b1251635a400f4b61aef2b9c081f6c98e7887a170"}, + {file = "windows_curses-2.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:b5e68520c7e92dff72914e4126cadb5b8eb3b6c968d955de6d35ff42306da8c0"}, + {file = "windows_curses-2.3.2-cp311-cp311-win32.whl", hash = "sha256:95d2a288af6172270da5ca9225aa99eeae98595c6e90f3574aa9b9f2fc1d2619"}, + {file = "windows_curses-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:9b7ecd0f21f643e22a979effff25f62200626bb9853ea8b9aacf0bbcaab0950d"}, + {file = "windows_curses-2.3.2-cp312-cp312-win32.whl", hash = "sha256:4546122f5bec2fb46c1706c020d971bcfc4d9a5158372f25ba7472a834b0f165"}, + {file = "windows_curses-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:e3f27939f39143c513f444a8c0419b2737e8de55fbe5d63d765992512125366d"}, + {file = "windows_curses-2.3.2-cp36-cp36m-win32.whl", hash = "sha256:a570f744a62108d024a7775b3b156b2ae2380fc971237c3bd2742341e7151f22"}, + {file = "windows_curses-2.3.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f81294465a67e43ddc50c1b52711b100b002fa1238f87d84d0cf94b785c4fe75"}, + {file = "windows_curses-2.3.2-cp37-cp37m-win32.whl", hash = "sha256:72ff5d8963fbb3aa662bfced2c5ea22dc3ed58bac827a3bff74a1de5eacdbe57"}, + {file = "windows_curses-2.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:70d8cb4ddad43f695a266f79c7a31d40ac8aee2a17cf8e06ecfd4a71589ad30d"}, + {file = "windows_curses-2.3.2-cp38-cp38-win32.whl", hash = "sha256:6bc698058081408685975256f46f570c32f8d7e1f4f82f9d6c66c300c6daff89"}, + {file = "windows_curses-2.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:f73bfd283f86d3ac0a72b74307ccc99ea0fd008a732d80db95d31fbafeee3c66"}, + {file = "windows_curses-2.3.2-cp39-cp39-win32.whl", hash = "sha256:e4ec5245f0c00ede45b033a885511eea80d5928c9bd3ceb523fbfb086370a4df"}, + {file = "windows_curses-2.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:00d5d000b68db38bd97b6a5b90ee4b4c915a7cef7492fc5aa9ecc7794ee2ca93"}, +] + +[[package]] +name = "wsproto" +version = "1.2.0" +description = "WebSockets state-machine based protocol implementation" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, + {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, +] + +[package.dependencies] +h11 = ">=0.9.0,<1" + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "707c737e522a6490207d40c4165f1d7d1cd1c3b513cf0ffe1ace8cf3726a801f" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..941ff7b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,44 @@ +[tool.poetry] +name = "blitz" +version = "0.1.0" +description = "" +authors = [] +readme = "README.md" + +[tool.poetry.scripts] +blitz = "blitz.cli:app" + +[tool.poetry.dependencies] +python = "^3.11" +typer = {extras = ["all"], version = "^0.9.0"} +pyyaml = "^6.0.1" +pydantic = "^2.5.3" +sqlmodel = "^0.0.14" +pydantic-settings = "^2.1.0" +requests = "^2.31.0" +fastapi = "^0.108.0" +fastapi-crudrouter = "^0.8.6" +fastui = "0.4.0" +ipython = "^8.19.0" +openai = "^1.6.1" +nicegui = "^1.4.8" +jinja2 = "^3.1.3" +pick = "^2.2.0" +starlette-admin = {extras = ["sqla"], version = "^0.13.1"} +types-pyyaml = "^6.0.12.12" +alembic = {git = "https://github.com/mde-pach/alembic.git"} +semver = "^3.0.2" +loguru = "^0.7.2" +httpx = "^0.26.0" + +[tool.poetry.group.doc.dependencies] +mkdocs = "^1.5.3" +mkdocs-material = "^9.5.3" +mkdocs-markdownextradata-plugin = "^0.2.5" +mkdocs-redirects = "^1.2.1" +mkdocstrings = {extras = ["python"], version = "^0.24.0"} +mkdocs-typer = "^0.0.3" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" \ No newline at end of file