From c8b319006a2e33a36f81d3b403db363e74b0f545 Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sun, 21 Sep 2025 00:50:15 +0300 Subject: [PATCH 1/9] Implement ASGI application with fibonacci, factorial, and mean endpoints --- hw1/app.py | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/hw1/app.py b/hw1/app.py index 6107b870..be3a76c5 100644 --- a/hw1/app.py +++ b/hw1/app.py @@ -1,5 +1,100 @@ from typing import Any, Awaitable, Callable +import json # https://docs.python.org/3/library/json.html - это стандартная библиотека в составе python (я не хочу делать алгос по десериализации JSON) + + +# Числовые коды (если нельзя использовать http.HTTPStatus) +OK, BAD_REQUEST, NOT_FOUND, UNPROC = 200, 400, 404, 422 + + +# Специальные исключения +class ENotFound(Exception): ... + + +class EBadRequest(Exception): ... + + +# --- helpers & math ----------------------------------------------------------- +def read_query(qs: bytes) -> dict[str, str]: + """Вместо urllib вот такая заглушка""" + if not qs: + return {} + out: dict[str, str] = {} + s = qs.decode() + for pair in s.split("&"): + if not pair: + continue + k, v = (pair.split("=", 1) + [""])[:2] + out[k] = v + return out + + +def factorial(n: int) -> int: + """Факториал""" + r = 1 + for i in range(2, n + 1): + r *= i + return r + + +def fibonacci(n: int) -> int: + """Фибоначчи""" + a, b = 0, 1 + for _ in range(n): + a, b = b, a + b + return a + + +def mean(nums: list[float]) -> float: + """Среднее""" + return sum(nums) / len(nums) + + +async def read_body(receive: Callable[[], Awaitable[dict[str, Any]]]) -> bytes: + """ + Args: + receive: Корутина для получения сообщений от клиента + """ + body = b"" + while True: + msg = await receive() + if msg["type"] == "http.request": + body += msg.get("body", b"") + if not msg.get("more_body"): + break + else: + break + return body + + +async def respond( + send: Callable[[dict[str, Any]], Awaitable[None]], + status: int, + data: Any | None = None, +): + """ + Args: + send: Словарь с информацией о запросе + status: статус код + data: любая инфа, которую в байтах хотим закинуть + """ + if data is None: + headers = [(b"content-type", b"text/plain"), (b"content-length", b"0")] + await send( + {"type": "http.response.start", "status": status, "headers": headers} + ) + await send({"type": "http.response.body", "body": b""}) + else: + body = json.dumps({"result": data}).encode() + headers = [ + (b"content-type", b"application/json"), + (b"content-length", str(len(body)).encode()), + ] + await send( + {"type": "http.response.start", "status": status, "headers": headers} + ) + await send({"type": "http.response.body", "body": body}) + async def application( scope: dict[str, Any], @@ -12,8 +107,72 @@ async def application( receive: Корутина для получения сообщений от клиента send: Корутина для отправки сообщений клиенту """ - # TODO: Ваша реализация здесь + # По поводу lifespan: https://www.youtube.com/watch?v=VJ963Z6lsQ4 + if scope["type"] == "lifespan": + while True: + message = await receive() + t = message.get("type") + if t == "lifespan.startup": + await send({"type": "lifespan.startup.complete"}) + elif t == "lifespan.shutdown": + await send({"type": "lifespan.shutdown.complete"}) + return + return + + if scope["type"] != "http": + return + + method, path = scope["method"], scope["path"] + body = await read_body(receive) + + try: + if method != "GET": + raise ENotFound() + + # /factorial?n=... + if path == "/factorial": + n_raw = read_query(scope.get("query_string", b"")).get("n") + if n_raw is None: + raise ValueError("missing n") # -> 422 + n = int(n_raw) # ValueError -> 422 + if n < 0: + raise EBadRequest() # -> 400 + return await respond(send, OK, factorial(n)) + + # /fibonacci/{n} + if path.startswith("/fibonacci/"): + tail = path.split("/", 2)[2] + n = int(tail) # ValueError -> 422 + if n < 0: + raise EBadRequest() # -> 400 + return await respond(send, OK, fibonacci(n)) + + # /mean (GET body = JSON array) + if path == "/mean": + if not body: + raise ValueError("empty body") # -> 422 + data = json.loads(body.decode()) # JSONDecodeError -> 422 + if not isinstance(data, list): + raise ValueError("not a list") # -> 422 + if not data: + raise EBadRequest() # -> 400 + nums = [float(x) for x in data] # ValueError/TypeError -> 422 + return await respond(send, OK, mean(nums)) + + raise ENotFound() + + except ENotFound: + return await respond(send, NOT_FOUND) + except EBadRequest: + return await respond(send, BAD_REQUEST) + except (ValueError, TypeError, json.JSONDecodeError): + return await respond(send, UNPROC) + except Exception: + # На всякий случай — считаем прочие сбои как 400 + return await respond(send, BAD_REQUEST) + if __name__ == "__main__": import uvicorn + uvicorn.run("app:application", host="0.0.0.0", port=8000, reload=True) From 4a597506c4d3e6d9030d0fb3aa001e4dd6aa3125 Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sat, 27 Sep 2025 19:58:24 +0300 Subject: [PATCH 2/9] Added first HW2 solution. --- hw2/hw/shop_api/core/schemas.py | 49 +++++++++++ hw2/hw/shop_api/core/storage.py | 142 ++++++++++++++++++++++++++++++++ hw2/hw/shop_api/main.py | 10 +++ hw2/hw/shop_api/routers/cart.py | 99 ++++++++++++++++++++++ hw2/hw/shop_api/routers/item.py | 107 ++++++++++++++++++++++++ 5 files changed, 407 insertions(+) create mode 100644 hw2/hw/shop_api/core/schemas.py create mode 100644 hw2/hw/shop_api/core/storage.py create mode 100644 hw2/hw/shop_api/routers/cart.py create mode 100644 hw2/hw/shop_api/routers/item.py diff --git a/hw2/hw/shop_api/core/schemas.py b/hw2/hw/shop_api/core/schemas.py new file mode 100644 index 00000000..f7547e01 --- /dev/null +++ b/hw2/hw/shop_api/core/schemas.py @@ -0,0 +1,49 @@ +# from __future__ import annotations +from typing import Optional, Annotated +from pydantic import BaseModel, Field, ConfigDict + +ItemName = Annotated[str, Field(description="Наименование товара", min_length=1)] +ItemId = Annotated[int, Field(description="Идентификатор корзины", ge=0)] +ItemPrice = Annotated[float, Field(description="Цена товара", ge=0)] + +CartId = Annotated[int, Field(description="Идентификатор корзины")] + + +# ---- Item ---- +class ItemOut(BaseModel): + id: ItemId + name: ItemName + price: ItemPrice + deleted: bool = Field(description="Удален ли товар", default=False) + + +class ItemCreate(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPut(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPatch(BaseModel): + # Разрешаем частичное обновление ТОЛЬКО name/price; лишние поля → 422 + model_config = ConfigDict(extra="forbid") + + name: Optional[ItemName] = None + price: Optional[ItemPrice] = None + + +# ---- Cart ---- +class CartItemView(BaseModel): + id: ItemId + name: ItemName + quantity: int = Field(description="Количество товара в корзине", ge=0) + available: bool = Field(description="Доступен ли товар") + + +class CartView(BaseModel): + id: int + items: list[CartItemView] + price: float = Field(description="Общая сумма заказа", ge=0.0) diff --git a/hw2/hw/shop_api/core/storage.py b/hw2/hw/shop_api/core/storage.py new file mode 100644 index 00000000..bc3c6cb9 --- /dev/null +++ b/hw2/hw/shop_api/core/storage.py @@ -0,0 +1,142 @@ +from __future__ import annotations +from threading import ( + RLock, +) # стандартная библиотека Python: https://docs.python.org/3/library/threading.html +from typing import Optional +from fastapi import HTTPException, status +from .schemas import ( + ItemOut, + CartItemView, + CartView, + ItemCreate, + ItemPut, + ItemPatch, +) + +# ------------------------- +# In-memory хранилище + блокировки +# ------------------------- +_items_lock = RLock() +_carts_lock = RLock() + +_items: dict[int, ItemOut] = {} +_next_item_id = 1 + +# cart_id -> { item_id -> quantity } +_carts: dict[int, dict[int, int]] = {} +_next_cart_id = 1 + + +def new_item_id() -> int: + global _next_item_id + with _items_lock: + nid = _next_item_id + _next_item_id += 1 + return nid + + +def new_cart_id() -> int: + global _next_cart_id + with _carts_lock: + nid = _next_cart_id + _next_cart_id += 1 + return nid + + +def get_item_or_404(item_id: int) -> ItemOut: + with _items_lock: + item = _items.get(item_id) + if item is None or item.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + return item + + +def get_item_soft(item_id: int) -> Optional[ItemOut]: + with _items_lock: + return _items.get(item_id) + + +def cart_or_404(cart_id: int) -> dict[int, int]: + with _carts_lock: + cart = _carts.get(cart_id) + if cart is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Cart not found" + ) + return cart + + +def build_cart_view(cart_id: int) -> CartView: + with _carts_lock: + cart = _carts.get(cart_id, {}) + kv = list(cart.items()) + + items = [] + total = 0.0 + for item_id, qty in kv: + item = get_item_soft(item_id) + name = item.name if item else f"item:{item_id}" + available = bool(item and not item.deleted) + items.append( + CartItemView(id=item_id, name=name, quantity=qty, available=available) + ) + if available: + total += item.price * qty + + return CartView(id=cart_id, items=items, price=total) + + +def create_item(data: ItemCreate) -> ItemOut: + item_id = new_item_id() + item = ItemOut(id=item_id, name=data.name, price=data.price, deleted=False) + with _items_lock: + _items[item_id] = item + return item + + +def put_item(item_id: int, data: ItemPut) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = data.name + existing.price = data.price + return existing + + +def patch_item(item_id: int, data: ItemPatch) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + # Пробрасываем семантику 304 на верхний уровень + raise HTTPException( + status_code=status.HTTP_304_NOT_MODIFIED, detail="Item deleted" + ) + + if data.name is not None: + existing.name = data.name + if data.price is not None: + if data.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = data.price + + return existing + + +def delete_item(item_id: int) -> dict: + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} diff --git a/hw2/hw/shop_api/main.py b/hw2/hw/shop_api/main.py index f60a8c60..4775e747 100644 --- a/hw2/hw/shop_api/main.py +++ b/hw2/hw/shop_api/main.py @@ -1,3 +1,13 @@ from fastapi import FastAPI +from shop_api.routers.item import router as item +from shop_api.routers.cart import router as cart app = FastAPI(title="Shop API") + +app.include_router(item) +app.include_router(cart) + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, port=8001) diff --git a/hw2/hw/shop_api/routers/cart.py b/hw2/hw/shop_api/routers/cart.py new file mode 100644 index 00000000..9e040b6f --- /dev/null +++ b/hw2/hw/shop_api/routers/cart.py @@ -0,0 +1,99 @@ +from typing import List, Optional +from fastapi import APIRouter, Query, Response, status + +from shop_api.core.schemas import CartView +from shop_api.core.storage import ( + _carts, + _carts_lock, + new_cart_id, + cart_or_404, + build_cart_view, + get_item_or_404, +) + +router = APIRouter(prefix="/cart", tags=["cart"]) + + +@router.post("", status_code=status.HTTP_201_CREATED) +def create_cart(response: Response): + """ + POST /cart — RPC: создаёт пустую корзину, тело не принимает. + Возвращает 201 и JSON {"id": }, а также заголовок Location: /cart/{id}. + """ + cart_id = new_cart_id() + with _carts_lock: + _carts[cart_id] = {} + response.headers["Location"] = f"/cart/{cart_id}" + return {"id": cart_id} + + +@router.get("/{cart_id}", response_model=CartView) +def get_cart(cart_id: int) -> CartView: + """ + GET /cart/{id} — получить корзину по id. + """ + cart_or_404(cart_id) + return build_cart_view(cart_id) + + +@router.get("", response_model=List[CartView]) +def list_carts( + offset: int = Query(0, ge=0, description="Смещение по списку (offset)"), + limit: int = Query(10, gt=0, description="Лимит количества (limit)"), + min_price: Optional[float] = Query( + None, ge=0.0, description="Мин. сумма корзины (включительно)" + ), + max_price: Optional[float] = Query( + None, ge=0.0, description="Макс. сумма корзины (включительно)" + ), + min_quantity: Optional[int] = Query( + None, ge=0, description="Мин. общее число товаров (включительно)" + ), + max_quantity: Optional[int] = Query( + None, ge=0, description="Макс. общее число товаров (включительно)" + ), +) -> List[CartView]: + """ + GET /cart — список корзин с фильтрами и пагинацией. + + Фильтры: + • min_price/max_price — по суммарной стоимости корзины (включительно); + • min_quantity/max_quantity — по суммарному количеству позиций в корзине (включительно). + Порядок: фильтрация -> offset/limit. + """ + with _carts_lock: + ids = list(_carts.keys()) + + views: List[CartView] = [] + for cid in ids: + v = build_cart_view(cid) + + if min_price is not None and v.price < min_price: + continue + if max_price is not None and v.price > max_price: + continue + + qsum = sum(it.quantity for it in v.items) + if min_quantity is not None and qsum < min_quantity: + continue + if max_quantity is not None and qsum > max_quantity: + continue + + views.append(v) + + return views[offset : offset + limit] + + +@router.post("/{cart_id}/add/{item_id}") +def add_to_cart(cart_id: int, item_id: int): + """ + POST /cart/{cart_id}/add/{item_id} — добавить товар в корзину. + Если товар уже есть — увеличивает его количество. + """ + cart = cart_or_404(cart_id) + get_item_or_404(item_id) # проверка на товар + + with _carts_lock: + cart[item_id] = cart.get(item_id, 0) + 1 + + return {"ok": True} diff --git a/hw2/hw/shop_api/routers/item.py b/hw2/hw/shop_api/routers/item.py new file mode 100644 index 00000000..acc511f6 --- /dev/null +++ b/hw2/hw/shop_api/routers/item.py @@ -0,0 +1,107 @@ +from typing import List, Optional +from fastapi import APIRouter, HTTPException, Query, Response, status + +from shop_api.core.schemas import ItemOut, ItemCreate, ItemPut, ItemPatch +from shop_api.core.storage import _items, _items_lock, get_item_or_404, new_item_id + +router = APIRouter(prefix="/item", tags=["items"]) + + +@router.post("", status_code=status.HTTP_201_CREATED, response_model=ItemOut) +def create_item(body: ItemCreate) -> ItemOut: + """ + POST /item - добавление нового товара + """ + item_id = new_item_id() + obj = ItemOut(id=item_id, name=body.name, price=body.price, deleted=False) + with _items_lock: + _items[item_id] = obj + return obj + + +@router.get("/{item_id}", response_model=ItemOut) +def get_item(item_id: int) -> ItemOut: + """ + GET /item/{id} - получение товара по id + """ + return get_item_or_404(item_id) + + +@router.get("", response_model=List[ItemOut]) +def list_items( + offset: int = Query(0, ge=0, description="Смещение (offset)"), + limit: int = Query(10, gt=0, description="Количество (limit)"), + min_price: Optional[float] = Query(None, ge=0, description="Мин. цена"), + max_price: Optional[float] = Query(None, ge=0, description="Макс. цена"), + show_deleted: bool = Query(False, description="Показывать ли удалённые"), +) -> List[ItemOut]: + """ + GET /item - получение списка товаров с фильтрами и пагинацией + """ + with _items_lock: + items = list(_items.values()) + + if not show_deleted: + items = [i for i in items if not i.deleted] + if min_price is not None: + items = [i for i in items if i.price >= min_price] + if max_price is not None: + items = [i for i in items if i.price <= max_price] + + return items[offset : offset + limit] + + +@router.put("/{item_id}", response_model=ItemOut) +def put_item(item_id: int, body: ItemPut) -> ItemOut: + """ + PUT /item/{id} - замена товара по id (создание запрещено) + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = body.name + existing.price = body.price + return existing + + +@router.patch("/{item_id}", response_model=ItemOut) +def patch_item(item_id: int, body: ItemPatch): + """ + PATCH /item/{id} - частичное обновление (разрешено менять всё кроме deleted) + Если товар удалён — 304 Not Modified. + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + return Response(status_code=status.HTTP_304_NOT_MODIFIED) + + if body.name is not None: + existing.name = body.name + if body.price is not None: + if body.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = body.price + + return existing + + +@router.delete("/{item_id}") +def delete_item(item_id: int): + """ + DELETE /item/{id} - мягкое удаление (deleted=True), идемпотентно + """ + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} From b6ed0b177ba166282eb0e679a8e424942ca8a7b6 Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sat, 27 Sep 2025 20:26:17 +0300 Subject: [PATCH 3/9] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B8=20=D1=81=20websocket'?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Также добавлена доп. зависимость для работы в виде websockets==15.0.1 и файл с простыми тестами на комнаты (test_websocket_chat.py). --- hw2/hw/requirements_with_websockets.txt | 10 +++ hw2/hw/shop_api/main.py | 3 + hw2/hw/shop_api/routers/chat.py | 83 +++++++++++++++++++++++++ hw2/hw/test_websocket_chat.py | 60 ++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 hw2/hw/requirements_with_websockets.txt create mode 100644 hw2/hw/shop_api/routers/chat.py create mode 100644 hw2/hw/test_websocket_chat.py diff --git a/hw2/hw/requirements_with_websockets.txt b/hw2/hw/requirements_with_websockets.txt new file mode 100644 index 00000000..de0e8590 --- /dev/null +++ b/hw2/hw/requirements_with_websockets.txt @@ -0,0 +1,10 @@ +# Основные зависимости для ASGI приложения +fastapi>=0.117.1 +uvicorn>=0.24.0 +websockets>=15.0.1 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw2/hw/shop_api/main.py b/hw2/hw/shop_api/main.py index 4775e747..fdf6ed68 100644 --- a/hw2/hw/shop_api/main.py +++ b/hw2/hw/shop_api/main.py @@ -1,12 +1,15 @@ from fastapi import FastAPI from shop_api.routers.item import router as item from shop_api.routers.cart import router as cart +from shop_api.routers.chat import router as chat app = FastAPI(title="Shop API") app.include_router(item) app.include_router(cart) +app.include_router(chat) + if __name__ == "__main__": import uvicorn diff --git a/hw2/hw/shop_api/routers/chat.py b/hw2/hw/shop_api/routers/chat.py new file mode 100644 index 00000000..6c3e1d5e --- /dev/null +++ b/hw2/hw/shop_api/routers/chat.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import asyncio +import secrets # стандартная библиотека: https://docs.python.org/3/library/secrets.html +from collections import defaultdict + +from fastapi import APIRouter, WebSocket, WebSocketDisconnect + +router = APIRouter(tags=["chat"]) + + +class RoomManager: + # Решил реализовать в одном файле систему чатов, чтобы проще было проверять + def __init__(self) -> None: + # room -> set of websockets + self.rooms: dict[str, set[WebSocket]] = defaultdict(set) + # websocket -> username + self.usernames: dict[WebSocket, str] = {} + self._lock = asyncio.Lock() + + @staticmethod + def _gen_username() -> str: + # короткий случайный ник + return f"user-{secrets.token_hex(2)}" + + async def connect(self, room: str, ws: WebSocket) -> str: + await ws.accept() + username = self._gen_username() + async with self._lock: + self.rooms[room].add(ws) + self.usernames[ws] = username + await ws.send_text(f"[system] :: your_name = {username}") + return username + + async def disconnect(self, room: str, ws: WebSocket) -> None: + async with self._lock: + self.rooms[room].discard(ws) + self.usernames.pop(ws, None) + if not self.rooms[room]: + self.rooms.pop(room, None) + + async def broadcast( + self, room: str, text: str, sender: WebSocket | None = None + ) -> None: + async with self._lock: + targets = list(self.rooms.get(room, ())) + for ws in targets: + if ws is sender: + continue + try: + await ws.send_text(text) + except Exception: + try: + await self.disconnect(room, ws) + except Exception: + pass + + +manager = RoomManager() + + +@router.websocket("/chat/{chat_name}") +async def chat_ws(websocket: WebSocket, chat_name: str): + """ + Пользователи, подключённые к одному chat_name, получают сообщения друг друга. + Формат сообщения: "{username} :: {message}". + """ + username = await manager.connect(chat_name, websocket) + try: + while True: + # Ждём текст от клиента + msg = await websocket.receive_text() + # Бродкастим другим пользователям в комнате (без эха отправителю) + await manager.broadcast(chat_name, f"{username} :: {msg}", sender=websocket) + except WebSocketDisconnect: + await manager.disconnect(chat_name, websocket) + except Exception: + # Любая иная ошибка закрывает сокет и удаляет из комнаты + await manager.disconnect(chat_name, websocket) + try: + await websocket.close() + except Exception: + pass diff --git a/hw2/hw/test_websocket_chat.py b/hw2/hw/test_websocket_chat.py new file mode 100644 index 00000000..248e7625 --- /dev/null +++ b/hw2/hw/test_websocket_chat.py @@ -0,0 +1,60 @@ +import re +from fastapi.testclient import TestClient + +from shop_api.main import app + +USERNAME_RE = re.compile(r"^\[system\] :: your_name = (user-[0-9a-f]{4})$") + + +def _extract_username(system_msg: str) -> str: + """ + Из приветственного сообщения вида: + "[system] :: your_name = user-ab12" + достаём "user-ab12". + """ + m = USERNAME_RE.match(system_msg) + assert m, f"unexpected system greeting format: {system_msg!r}" + return m.group(1) + + +def test_websocket_broadcast_and_format(): + client = TestClient(app) + + # Подключаем двух пользователей к одной комнате и третьего — к другой + with ( + client.websocket_connect("/chat/room1") as ws1, + client.websocket_connect("/chat/room1") as ws2, + client.websocket_connect("/chat/room2") as ws3, + ): + # Приветственные сообщения с именами + u1 = _extract_username(ws1.receive_text()) + u2 = _extract_username(ws2.receive_text()) + u3 = _extract_username(ws3.receive_text()) + assert u1 != u2 and u1 != u3 and u2 != u3 # имена случайные и разные + + # user1 -> room1 + msg1 = "hello from 1" + ws1.send_text(msg1) + + # Должно прийти ТОЛЬКО второму участнику той же комнаты + got2 = ws2.receive_text() + assert got2 == f"{u1} :: {msg1}" + + # user3 -> room2 (не должен мешать room1) + ws3.send_text("ping from 3") + + # user2 -> room1 + msg2 = "hi from 2" + ws2.send_text(msg2) + + # Должно прийти первому участнику room1 + got1 = ws1.receive_text() + assert got1 == f"{u2} :: {msg2}" + + +def test_websocket_username_greeting_format(): + client = TestClient(app) + with client.websocket_connect("/chat/any-room") as ws: + greet = ws.receive_text() + # Проверяем точный формат приветствия и шаблон username + assert USERNAME_RE.match(greet), f"bad greeting: {greet!r}" From df092dafe6327373bd972d31e282676044d24a8d Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Fri, 3 Oct 2025 21:46:22 +0300 Subject: [PATCH 4/9] =?UTF-8?q?=D0=A0=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=94=D0=97=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw3_own/Dockerfile | 13 + hw3_own/README.md | 25 ++ hw3_own/__init__.py | 0 hw3_own/docker-compose.yml | 34 +++ hw3_own/docs/dashboard_1.png | Bin 0 -> 72928 bytes hw3_own/docs/dashboard_2.png | Bin 0 -> 109184 bytes hw3_own/requirements.txt | 9 + hw3_own/requirements_hw3.txt | 11 + .../provisioning/dashboards/dashboards.yml | 8 + .../dashboards/shop_api_overview.json | 66 ++++ .../dashboards/shop_api_routes.json | 51 ++++ .../provisioning/datasources/datasource.yml | 8 + hw3_own/settings/prometheus/prometheus.yml | 10 + hw3_own/shop_api/__init__.py | 0 hw3_own/shop_api/core/schemas.py | 49 +++ hw3_own/shop_api/core/storage.py | 142 +++++++++ hw3_own/shop_api/main.py | 25 ++ hw3_own/shop_api/routers/cart.py | 99 ++++++ hw3_own/shop_api/routers/chat.py | 83 +++++ hw3_own/shop_api/routers/item.py | 107 +++++++ hw3_own/test_homework2.py | 284 ++++++++++++++++++ hw3_own/test_websocket_chat.py | 60 ++++ 22 files changed, 1084 insertions(+) create mode 100644 hw3_own/Dockerfile create mode 100644 hw3_own/README.md create mode 100644 hw3_own/__init__.py create mode 100644 hw3_own/docker-compose.yml create mode 100644 hw3_own/docs/dashboard_1.png create mode 100644 hw3_own/docs/dashboard_2.png create mode 100644 hw3_own/requirements.txt create mode 100644 hw3_own/requirements_hw3.txt create mode 100644 hw3_own/settings/grafana/provisioning/dashboards/dashboards.yml create mode 100644 hw3_own/settings/grafana/provisioning/dashboards/shop_api_overview.json create mode 100644 hw3_own/settings/grafana/provisioning/dashboards/shop_api_routes.json create mode 100644 hw3_own/settings/grafana/provisioning/datasources/datasource.yml create mode 100644 hw3_own/settings/prometheus/prometheus.yml create mode 100644 hw3_own/shop_api/__init__.py create mode 100644 hw3_own/shop_api/core/schemas.py create mode 100644 hw3_own/shop_api/core/storage.py create mode 100644 hw3_own/shop_api/main.py create mode 100644 hw3_own/shop_api/routers/cart.py create mode 100644 hw3_own/shop_api/routers/chat.py create mode 100644 hw3_own/shop_api/routers/item.py create mode 100644 hw3_own/test_homework2.py create mode 100644 hw3_own/test_websocket_chat.py diff --git a/hw3_own/Dockerfile b/hw3_own/Dockerfile new file mode 100644 index 00000000..2e62a48a --- /dev/null +++ b/hw3_own/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.12-slim + +WORKDIR /api + +RUN apt-get update -y + +COPY requirements_hw3.txt requirements.txt + +RUN pip install -r requirements.txt + +COPY . . + +ENTRYPOINT ["uvicorn", "shop_api.main:app", "--host", "0.0.0.0", "--port", "8080"] diff --git a/hw3_own/README.md b/hw3_own/README.md new file mode 100644 index 00000000..2c222cb8 --- /dev/null +++ b/hw3_own/README.md @@ -0,0 +1,25 @@ +# ДЗ 3 + +## Задани - настроить сборку образов Docker и мониторинг с помощью Prometheus и Grafana + +Интегрировать Docker с Prometheus и Grafana в любой уже написанный в ДЗ сервис (по аналогии с тем, как в репе) + +По сути, если вы выполнили вторую домашку, то теперь для неё надо написать Dockerfile и настроить мониторинг. Если вторую домашку вы не делали, то можно взять сервис из [rest_example](../hw2/rest_example/main.py) + +Сдача через PR, так же нужно: + +1) Dockerfile для сборки сервиса +2) docker-compose.yml для локального разворачивания в Docker +3) Приложить скрин с парой Дашбордов в Grafana + +## Комментарий к решению + +1) Визуализации для реализованных дашбордов находятся в директории [docs/](docs/) +2) Для воспроизведения "нагрузки" на систему используются следующие запросы в разных терминалах: +```bash +while true; do curl -s -X POST http://localhost:8080/cart > /dev/null; sleep 0.4; done +``` +и +```bash +while true; do curl -s http://localhost:8080/item > /dev/null; sleep 0.2; done +``` diff --git a/hw3_own/__init__.py b/hw3_own/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw3_own/docker-compose.yml b/hw3_own/docker-compose.yml new file mode 100644 index 00000000..e6c0dab1 --- /dev/null +++ b/hw3_own/docker-compose.yml @@ -0,0 +1,34 @@ +services: + server: + build: + context: . + restart: always + ports: + - 8080:8080 + + grafana: + image: grafana/grafana:latest + ports: + - 3000:3000 + restart: always + volumes: + - ./settings/grafana/provisioning:/etc/grafana/provisioning + depends_on: + - prometheus + + + prometheus: + image: prom/prometheus:latest + volumes: + - ./settings/prometheus:/etc/prometheus + + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/usr/share/prometheus/console_libraries" + - "--web.console.templates=/usr/share/prometheus/consoles" + ports: + - 9090:9090 + restart: always + depends_on: + - server diff --git a/hw3_own/docs/dashboard_1.png b/hw3_own/docs/dashboard_1.png new file mode 100644 index 0000000000000000000000000000000000000000..12b7a4b13b5798739ba49296bd5137ce041c4d2a GIT binary patch literal 72928 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�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

4j+k&k9J5#Ey*2?i`8#Gn#B_*$lX02=X_H4 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 SMLkw~G%AXkPfO%2-u@3Z;8fWF literal 0 HcmV?d00001 diff --git a/hw3_own/docs/dashboard_2.png b/hw3_own/docs/dashboard_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4c249b975ae2faa32d2c70aa6d0a3a573431492b GIT binary patch literal 109184 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

)~u%{6F`#jzW7O8lV|I&4AP#%B(_$L zI;P}Nl9+ex+?DvZ+qXU9E3c#=R;!FRZXkuuT?C<9k@i{&wu4*9i2w#}?y2Tx*Ndt) z%m-U|0oY(IpZKDRuyIim5S_8uq$EQ%x*qM_p)Bj*GvgZ%RoC&Hq=kAm&BZl>^!n6WTN*rH48EJEu+8oY&bue+xQ2l-Bx*uQ(o#&~r# z2jaZ-E7rq_I5svmCMM?g(H1covCICj3pEofD<==n+K9tUaQtkIUUqKH+2rW}c?(`! z_l475Q#DpWfgK+a^~?JP6IFmCxy~;g$|OMt zNFKw4Tvrx0CYN;GALF?kZX4?8IPM)FlYg~@P$h|Pn_)s_45p4f8403DgQW{pR|{+7 zn425w>qjOh%R}guDEny7!M4Ll;(k}%S@1LP zAsroE6wcM^?p%h`>1_`mpDX-kWtE&Eqs;Gqz@xBg==&aFxm`rbMwT@ z8g#XjeBRL3Xth+D$~vV70ig@@V8xdix6->z57HjzOMmYYryG>wj~3=Wz`<(~aCuXLEs z_If>J*Kh~>@y5zZt<#8RaAue?Wu8{0y{L$2?V9aIUz%H&O~^oWG!Z>5y_mbLM%26Q zy2QUzgqU6T)X6C24WwiP+hi39I%rlj$Ue$3u~8q>2-WR#6(GC2yITVPn4en~l(Tvw zqG~xLiajMvR%27nmEz_WDN{uUj*mrieH zXO=c(?Gk_yGJog60&j82{3|wuh$#AvBO@Lm!NO32lA~;xZdwJr1j_MraeYFCDPoOF zSVxECzEnn$L)Q4c9IY*7qJb#xqElr_WTtZbKy%X}-iRLz##P33v^Ak(k>=;Oc)snE z3oYogWHS_sNeYvO934IIsJ=!M(q=TZGi4wpCGX`3k#A6ZmY7{Hs#7bIdh+mld^~<% zmmVH|i*n-iTxw9~!NGyL$O!J=%U)hkaLoH0ySStzPn7qE|A!CRie!~#*9q2D5si%} zjg9VMF9*S51%Y{Ull*9NS_4H5tRF{M$sd+|AqjaK}Q>|-i z`{bm4O19;a1>8!THfz;>MXZYn#zP2!h(xe9(Q8H-md=IU=&*pPIFd`M=M8P~RHD7YOt663(}_$M=|+_?VcE<$c77%cWb`wTbVv&DOVTK?;B4SkK{TF6{X!^vLMw0x~0c(02E5 z_3i3jbsXRMgN@w${9fyFRh{ZB_SZN99&6cbRA(=9&uYTk(lK#2X{n1UHlc@W5s?JG z?720#L{Cz`7({&Ob_kd2INq2tgnliRlZ60)zkYRwEU*v;+jqWMsk5s~@L}olQ}4gS zsz_e{fEuk?`0UR#*RAornQelfKhp-8G&aTC`JU&fH#b6v2o}2Hc$N7vlb_y4ygT*1 z9_YXe1Aw!W#L0}yO7-0vU286*C)uKsxfT8vIh8(LWbcXSBHCSqN3v!lO~f? zk@4}0kS%*kK|vi}vc-2Ew)*OuR6#5qHPxP`W@bYJQuykOI+_r<0=a@5bt?kMvnOvJ zHwU)p?m#5`TR5;CA=r-OT3wc~Nb;5(-o5i+k_^ozF7=Fy&5){cd*4s1lVX(` zDc3|H*NW28E9Wt&Ob7*FfHkj997ub{$D8|pt~Ph=p!ly&&%$F^SXpk?9DA8ACkkJl zcfudkB{qil@9mX#=63>2am_Ymv)zB`H2NIF#nd$Y{KPr?^hsMAC8 zlk_0^%@dw%AN2=_?BX9swKf(OF}X};T{mAOk|){>9|;Qzm9d=9NYwJ#O$G%kN<7${ zs6Aw#8VO6oR8;KJx9)leay=Up6AL4&k11H??HwJ?p>5CwEe~&8wjoO%DJehjIXhAm z854s;%A;P1{J}BZ)C6C0&M&Zo+)4eFDggpO6wt|dMOTQPPOGi^viV8*nVT;)axC`m zy|b!Tr-Q@GMlP+oo13Fs=3AzM1wGERTW2o;qA_<5`dif%aVyu|EHQa%H(u49z**@k zrEX#pA&Z}N>av#bJ@SWY9;Iv57sPTn|1@`@2A=e>k3*VH*`Jw4%^a{Xgku7|7b z;?-5GIfLB)=D&}chbTTJe2CY<;pM-$S_d;Dk(Ny0WWH$f z88-@X8WHNg>Tuj*KN<+qN%0qmHgok(vI?N-1VL z=zuC>VPe}D;(qnyp}Cob*t;j}MMvCOJvbFuZ3R9_+!KMO< zUv)tB^Iyh5Kx1Po6n1m4JIS^gDN=~zC`eCdU=d82t9; z%}*(k{#hAWgGqno&aV%Yl$SrFJ)ACm1L7}`)-b0-;P}mFSwq(B`Xa&}bI$x)$DR2> z!eNycmxxeuPQJNjUdgc8nHQ4WTmxA5_h1b4{LDX~JzG0H@C`l8WDO1N?F~adA=AFflfk7UKrv-s`~-PPU3 z#vG#%Cn8EstFCakHv?cT^NL9#G{VgL zYw%apdxx8kANH>Ird)Ex4uT-t`F%Hr-Ke)f_b>OefTj#UP#%yx5;4Ar3=f|}p1U$d z$x+vM9`3)JgQc*+^l0Z^?-g%`=Gp*4ypm2V`pU@ ztA?)6(qJZKf9cY@4(~7n;22(7+Rfg2j+)jI<06xSK(|IteY}iVuRp*d<)nOk&_5-i zxKx5a&g;xgGq0=m)^G0<^~56>#Gcx(9|g;Ai!a!3qba1Nr5#X*b+I`f_V!1i%qXS8 zqH!GxpbZ{v_uDOoqB<5!z0cj&qTTTNmRNl?G}T!=S9zVBzINsx5E^;sGXE2!0bc-F zt4|)w@bolm=(gV}v+tGpP>)Ugqcwbk=Fuukxb##SlpUpX1yO(X9pyItz#w+>PI^WL zxlk#};q|qTH)h*nDf5Vg!&G4QSbSJ4;5j^I{m#^Mw7jbu)dMaMEOaWop~+;pgP#L~ zgSYz9jz4W4vWSZEvWl9uew$&{yN>QK1DlnC%W|}Hl|6ST_jBV(M@-Lp94$S)Ar|iX zRGtH>?j|5Z+s!Rw+7m0TQ&l8luAQGf*x7_US)K_BI$nR6`gG?`Fr{Ef4>1AJ()L)T zqGcZFB3l!v_1%HGzY#)DG{Bh$2j$&~mlKuyKwKNNhHDk-*SVbg zOQ;CC@ALxULnk^ImYrpu4W#V1ua%SQeZ0>faPV=3Yqgq~q!muHpNA(Ud2XDf7$VOO z?yh9KV%kOrBVAb|VRCYT%1I*QMbkg(F7GTYFB&3Ag}hF(F@@==L*_v$qXK0cu;;Y> zyV|U9xVi8|xcl#g4y_Aby?J?j~Zppgkm z2FL*3 zvtd8;P@oV#!NH|$n&0i{=(vA>FQfDw6e>e6Loa6ZEjbyw(_1H05O<(2%qu#SQ8+=0zNDEa&2P+I~FksKhJXtqi7>P}95&)?{@H$Y5`2?+=Z z!g&vv2xI7I=}pbe8>fOj`m@?Z>q>d{71;ec^CdDg;!3HbjTcD$kxvfu9^*fkcc&yESg3Tpi-ByYsO+B>aU~fK1iHt+v-g$bCIyPfjtt+6sj8^4fuojs?NKQDXcph*)gLc_>dv5`WA5n);-7*ocxJU$+K;1p{)q@J zaOYw@-(h$*kbW^P7g5M|c9r;(1mktbq?@SLdVJ3#N_S{!&xTwE8&9T@!?g1*j*j7HmUHbO?QnBL ziwr}YXX*b882B=C?`3~y2UjNxMPz1$MzguZ%`pE(M_nAXjF~8TkJ2|cWk0|MxNr{M zfBsw9{QKj5T}C<`-1Y7;58ET94%j|+lZSsWS)|>h@xQ+ZUxPpWes#H+tVb*oDQP2f z1Ec2=6pAV9p#y#n{!9z~=f%Be?a$s|$>$wy*6ImA#Beu%+1>$;MEBTiKL5e_rzk$$ zvgZN#jk+d!`~whIZ;fSJ5JzwPdHDB+|I0{vHWA&c;o{>yNZgj zjm+;^!@#({H#9V)U5feVWuAWjJt4*l;UnM>`S;_8*8hz2|9+|e;~Or9AN+ZDTw|Wy zdE{VvixndQskV+z;OErn2eL9c1q5GdhlVsl2dX}l^*W7u4(uFqx=`58Uvn9m7A$8| z${Nthi;J}RZjIf~sBjc*B>(>9&+XOw`b9<2hAwt2a9v{4KO)i9(IFxr;3=UJ{Zhb> zW0ai54H94+6A4}{=^km~H)@u#-|mf*?T7cI?g&C}wr z%>OJVo||Fyy$$UXzeaNz6C*WX15E*PLr&klZe-*9-ewr@&1Z}kyG%~4Xaf{i8;3{x z8rp^HI7+Ki|8f^HZlnD7*+nY;0CfpF|3n`;t$|)zuz0U-tEP_xHE)M^W&! z_ZE+>f8Te#)5|9h?>KMMhDA~e`?z;++(tr=L@#>+h99g^7V&KwCGQ?-t&0)I#8kMl zT#uJpIc!z}rT=8}+9!8lDUaPZFsRmLW@d}c$H2~Zv(ONWmyhorCEwnKpD$oT2ah*U zVpo>cp>AK|D(_1zG8c8(1bhH43?Y}bcOYp+uhinzl=JF~jAtUhX3J$DNwrGO-a2~t z(N!VFz6@-95_@UCxkCBh2)ZlXy(OVXrbkAm$IMJN!dEDfvNL&_2haiuiB+PI3m?Zr z!We?6Xdqe<;8{`x}l z-J9Z+UFCU(sw$7``3cdT=V&lr$wXVqxPc*%c0^IRCwO-xt55mkS$REDVjyo zN64;!-dtUUZ z1dzcDr;!{rb3p-trRC+#u}T^`I#st2&1g;Cf(nzCZcs+j=J4gjvl}aS8!8fqNKbik z1OXi!)P05M`Sp%nfe=w?FO{ANZ#AWLAP)Q1bKzP1Qa9&mYQo$an_aN=QOK5AoqIWs zO!=vT)k|%#;YjwQgDN*SO*)I6Ipwa_KTt>cpTCVm1`8VHWneg@;ZbGXb?*$n=Xz5( zKAU&4Z)Xps9BoM!H3@Yqz5K}`>-hq{waIK^%huAmZO*jLBZ>2GUc>l1u@M38jo%kc zHk;>j=`(dU1R%RL4=FVhL+5mfO~-YCVYT@tu;7SL%gHMCD+3a*fUPLx>6*Jg)D8E3 z(>!%B$zwO~vpPbI8(P86>drgY4384`wJ|oHU06|v7HR9BEsi8V>cbWHc3IiE(hMx2 zw6bEfxDw>F81|BsOpE0<5^=qFwRI`dH}mtSZ~on_g9J~tv9*iY;G`gBIBBxO)l2u|j@3xNyI(ZVS`!uw6(l|~`KUklw{;j0bciffx& zSSUldEoud9R~SNct%(fvGfO3MF1;!wwb*HHgvxdojQi@OPBhJP`cV2O+qYwVjY9FF zyMM|(hs@vXLMC9N&zX-e539X}<2oOEZC6L!*bKI((_k}<${2o2rBHUf|IqtHYb((1 zGz}Wt^LVl~OEiwG3{^MWJf`~`;t*1qC{nMgH*Hpr{oi1#Yie$w5#FHGb3@dVkchas zrDfQvo};t(DGfP!!kaf~-HGC9U%rvsCggV(z*g$3MO|D8qlls-!5a6cFWt!)A*wrw z+d7;ky8?yE$D;@%E339G(FuW&j`r@AF`8mmXn`hkOdISaTMP)rny~LM*x4b)Xwmlb zsr6#!n5#1=4jzR-6#@z>#XdV88X7}Dsj(rY68B-Cr~eB3n`S%yDi4mo+8A;B0ij02 zq0B9gK*Ixy_R54s{nbqbjDefx@*sA;<|g6&+jt}O?Tv8XtGb0?H}SLAr<=n3KzF~` z&voeUSJhpKl+Rf6Lz#9zDAna0QF&&{Ce<-Q#m>m4g^$> zy18@e{2lb?$bO;^6sf44@1?H1e>}2GXF8Nf`5%a>cao%w*cwOLfl)V+M*bMGd=xQf zvrQptolsfn;CztCZK1qIpAYx9JAP4kCgjJsosB`2j?SFIf6=Vw-u|aPR8<)hC~m-Hu31B5}T=$wx!D(EB8r zy**Pq8DYcXZ10j#ToJHx-P~8!0WVdW@WNizKT=VqnjdKy8;{#B3(O71);_xOtZvVR z;veKIoU+JMDU=uqwI#u@Z((-~@~@e^vZ+$$U-CxOTd6CTxec4Qh!$%r{{glb?mn%i z{g>x%sPY*?i)B8SN2*FnY-5747TrmMdV>31U#<<0+DBqNNTwYw_85)gvea~S!=s{9 zpzvI$qyRCsvs1 z(jq4ik~%;LWtXjkwvBauKQ2C^QmzztQ9C;hPz{bg_bBQ3gwx0c*OV8hVhEH&x~0UG zqF<#gicLgXShV%9s)**}{7*6m6_1Bu+WKy6p;hJT3=h}#XFaQ>1dZ}fTl+u%{&||gr%98 zsNI?^G4Tkf`RjhyGpzPJ{iy;5Cakr0q!M^4jBozT9?FgGmc|QHNJ$hNwO%zvyg!nb zM8wt!4f7#?=xUC=(&51}Nh%9|ZHimQX15-IlE^_4(8P0&_K!)=SaunSjW{a3qOp0o zn$4qsbBy8Fe{raLbbK671(cg2()Q~=yif{J;w(|oD)f(zByw}Y=~evPr^j(S<2Liv zNn=BkyaNqiQ&mYsb8uohlmed&zPIe4IuOops}It5d7by21Q8b&Vfwu8r(CfICjkxf zEy|A0&f`^9iD*eW>b3rAo0x6`m!cu-A^ET7hZ`g-%gfiG4g%NRj4tr?-P;Y^SvPKy zl7cudCF2idbyt)*!2)ZLpiWNR-qv*mP*j4D*>G_R4PctS=a*TvwUd}Kz*j~=Oniw3 z>B#otZy8E7$w<_mUaN34TAaDn8uGqcw_!>lSKBGQ>cjb2$L4K$`Y}8Akqu8TsgtQd z&xwnwtha5q5L84!y`GZInRI#4uiA%?heyNnP-kqka^>-Fl zK~${Hsu-Grm(<14G3?W)0smm%K-vsePWvCr-^#-qGmq!3=Dk@rFYqbmhAO<}to!H7 zo!wkw+RTCj^THGq6}Tz2m9>iQbf@b4swgct1n|P4&H&h{dm9VmRBn!BO{sfFq8&an zSs4!Jcw7=2F?{3U!OXqEiMeF#|C=R=XxZA?2DG;IF%5#O&Q_R9=dzRkgjmtn6+Qa$>^6Y6s)} zZ#snWep$g*-`Q6G;L}8e+M@`yIAhtV27uJjXb1mb07 zyG@1}%Ks=|+>06kfY>Jnni0PNKI?bho9=S|VeVe+NG2&SV^cuXc5Gkk3IE|Tz4&Hu z)n{CT6K|=*Qc88l4tx&CE6_Y%-h=JS)n{V=F^CH-SkohBW_dMywM*=*e9ge7@XX`1 zf60d0qiS^XwOL)OZt_#n2T30o@!AODGM#_j#erz@9d!{r`g5`8l0aDa|AwAkV!4b|(B|OI#}F0hZy`Q=^YFlZ zfq(tQ|6`i{e|kfc!{+Zfd+v*kjXhrO=;rFm$<5u<(b3k?!N}0MEKmra|F|4o5S*A7 zkFX)*k8VM@FjLdeDEdlHj3W>pz+IsP@v5r_1JyJ(H2I5~ot@atC-2X0oe}@p+iMAc z%8M5b9wLUDn@vrA@s$_e>zWXo+jn}H>FHx)jC`hA5RzTdz-ju7j&5TT&dAC60{2D` zsi14?H{*TcPT;F++?~%Nef)S3{Z$y{@<+tjxd8dxs1KCo@s}^_uk&ZJ|!Cy<9fe-u@xBZ%hS|6 z3V<;Co{4g;9ZmZd*=4TG^xeTBt+AZVlQSC%NsRAF5Y*AgAh>%AJPEyGLe0h3ZGMNV zbpRY$DQmdIW`vEg?f5%+RX{>@58f|B+`BsVp+vT~6F>h$#5$H?Q*+7cgOZSZIIM3%Lq zkGm(R#>Yo}_Pa`fK>oKe6~G&CG4Lr9;?H7u(F`&>*8Tg1MyS-D`U+b#KB;R7S|ltZ zgAi|XvN}Uww{SvL`}=g23Jx359cr9cYfcvVQ&YF{4fo6R*+%Tt zbJVkdncaEyBHn=|QT%%Gr1~cTBosI6@b0ZsxlGC^x8cC)Ssmjv1>7`W6a*jqMJFoQS zcpwsaoqTk3#@2XIgQjWL3 zQAT0W(Pw+9BUJm{F>)C(Y>5c>-O0L3;gQ12uFlR{<>V_Isy8Mk@(`I&f8eUVLz`#a z@Ef1J&%$cp03KZLof%_5r7b-jL@0fKoiOq{7#0~Yx70sxEX{vjuf+fZuy_+>;H!iA zZQwumBOf1GDF)3exDP1J9JU#vq7y}-XT7tRH3q;Bm#GxHy0W6L@)Q>fQDt+?2Z}4= z!?w>-Q(n;c-wAfV{zMB{4jfumUY?t)3KG2trE=bo*arV8Yy2^|Kj|kAkGA<=valH- z&n#qQmKoK|b@lZAHpx0|UTdgpuEZH2No(vct*7*}czrL%>5GlNJn(rG;674V0PJA> zmsYQAhV$>^AYMWqJP1J*o;eLH9Yzrn7NM>l;IVq_BTx5<*>!p1VZe^uoy6PIk>?G# z8Q|og+%jZl7!(v_n1CqOJ5IVI@u{=(pkRXU89hDUmgibO$B`kz~%E9RlOWOG8@Iq$2L4vkm9U2?G5G4?t=3F$sxLjdR_s z`Pi6_l~v9Z;@I-wIjEI*uV!cgPxHmuM5tDgpJK9@1z0Z-Q-|&1gT&B4`9Re5Y{yMZ z*HCgn`-_t{fKB5aVsg}nfKl#bX~GP+4qQC{o^8z>u~YZcVb*g#hw-x4S8qN%*WRwW zJjY>TW4ZuEKWlhgCHn03!S`LT6i3V4ES?`5s%3WPAAe(v$O68h%aWrJYmGxP2Nrlq ziOozc;P8C*`ZAEGPtSc$7lo-y%bZT$j8$60mwLo~r%}Fcp_IsJ=&_o?Jh74fAi`}r zQJC-gWI&54YAr3au2)ggh8&bx#LhSVj`eY@CM`FDS=-)ZQH zw@HdbATaS(`}GVB(V&Ye_i}M_vw=gw)|LRz1A5Na0mD_(*RS%uF1!ThV)0_(gjzjQo=`fN}w0y-*ys~5j7PF!>K zzPjCH)z&$c<{-JSM}Lq>%L595;&|9nmmUvjTgg(UGD3Q47{9pc&!9RzbxHZ+_14<+ zJBN>)&kJ<7fu6evnr3^pCH>2J0bl38y=WNjfwg<>;lQHx<@3f=nVU?R^UBQ3OGvB^ zNlhj2B41wA494Gmsi;WG@%m*NrqF&*z{%$-;7X&e@jh<`y(WNqA>PhX0as_VSwoRu zQ- zIqDG=C9A3$0b>xR=N1zSfk}sw0)N@=Ks(?!ym%Vw?bBZK2K@Y?ot@6~GRxuN;Tal?Lp1TMz-BFiTRK#*yfaVH*2kD1>jR9&!MyMK(eIp0~o@3YKGUKO6cozKBjbGd>~)Fp@ns>vXah_@w&=Z)SZ;b41F$=QhntyE0b_jV z1LnEv-Qr$%q8=>!iTL(>Xbis>t~lN0qyz6CKP3j*UJ2@jgryXhZY^E6Z^5!BH-Dh2gw|x|qU#;sJ}cp4(FjB`nD-#XB~ z*o(h+Z?~x_v}$?_g5KL*t)DL;4X&7trlhpH)<@_Z>t^Jlt9E<9V*2pBH#0c?>(}*e zil;RO*bN-mCbqV!Dk|6amX^$?*L$ZT%*Ial4U>-NQsYcqsOtU21$2&Ms)&dPdn2YB z4*MrAGyhc1>IYJDbJr#uzzRI&XO8wgZX%{4S3Umh5 zxG03O)AHtM6^Q|trG`e=Tg4SlYk6+$fqL}hWP*|JdC5_9fBze5kP^QG{+lNA8hCB? zm)Vnetj=VpPy;(^qoj0Eaxq0GCmn?1Ata(c(^m#hzZ~(`^k{3lH&NkW z>*>JA*aji!O>=vr>Ln+4Nn7rDxF!j4R8;ce{ZUo*8K!SAMH%}o5LQLH>(2XqZ|_}& z?bLG!d$)I6YpcLUJ1sT!8yEx6!CaroQ#cuORA39X%YHPW|+Hyk6}YE$`_UDijYlw_eE{bYdwRE8_e2=MZ4^=9vs?F%fpz3;p`l>fkwW&Q>|n zcn#%JDJ6>~MMu9ecXi;6_VY74-Vy~KjL|BqseU)3j`sG)?!LyaZ=%$E_Yd2Tr_alm z3PRm5GgNg9*{q!1L(}u*>}@QHpzGt!m($+YWR}wAHHnFd3UpoF-JRXt3jzhf!N5EO z{D&=wPXHVPtDE@M0r35xwDl&O*9NNtKFDVD6B_vdEz8=VEybMQvbVR19TgUpc-mFj zk(ZYjk2d!4v6q;e0;-)e?sw=nIQ$TXXOfy~Uuh||zp>#QGGF6jC98EhR-nWFTmP!xIMw$L9Vw{wLhbpXLQ*FzKg00B{BD zcWbV^J3p;dSiMn0e?;;3Sshb|64cevK);(<9GBTJm5ml}2|q|x-HGwQ4GP-N_KLHT z@KoOJSUNfFeHE6Ue(5C^i1$ovY^1{GwbE&zZ531y3&v=pVS*v+_@hQ?!=UZibFOg~Br)&3wm_2> ziN|l~6yuspYu%#jnjI%WyDyM^-L@vFi@ssrzHP%32Vh%f3td=b5^6_z;N0V3Xp7Os z9@*(>wUPJX*nH25hih0X&L1y8Iu6;@#T7y$*{gOguSh)RrJT(+Xa_huh+q#63Ig_8 zw0^@-UTy8gIJ_6!!sbL}UcQ39#WpZ8ZVp(y--7G2>78xasIKBGn0^hc@djdbcG!G( zvbfr-Z@x1#N&M69Zma#FfX$7Kk18e#tq&L6oiaHg)zqXD^qoxx5#Ack#L4&*n8Lu% zWPJIo46QaZp9cDMw|w$~TlU=V-0^1>#r~HKYinz-t&xkW0%Mw|wC)>K{Y|ds!+vWx z5fKsBm?XC%Br-Z07;7xua6@-?I11}@WI+=k@I(1HI}d`20wswa=->mOdTRjfbt25{vc3G_7 z-*-Z|tqWSdeg#}1si_~w)1J{aYiVlUx^=Jy8vk0KJMYXG8Z7P!(FG-kCnmbAYu>^G zrcTiLy$wwJH5$M=e&^opUu71`L-yuYR)hpR7tO&t`T5w?T%4Q~oNp9>ZwL71LgvH6 zAC1HJA8bsG3=Z0Y9=lJNI76GNOi>zgX31igH*cPUDr0~3ejXpPxHM{nYx3h4ip_%-E!&dI@%or8Du zL&oRFyLV3hIAncIC_VR+D4__{0^#0Vszh{4Wl0I)eVjsl9J|*~691Xx8alOzq@+jW zBJJqz*|nkGjg8KWi(30B&s(=|L*2`fUZ=k@yVhN}({>BSBy3F&V&9mhVS!&Nw%&ZU4Ds(Yiw*Z7BldA=*K!22ui@Fvw zN!@cxYwNL8&fhW;UNr*Bmyz%aImi?hAFpR`XxPvNq=d8fIsW;%H+*)6F%c04Wr;2G zxTFH6Ta$jOR%0#6we&IkPVT+Bl>5z=efF0^E;>~^yin+uaWdNQe({k@G|i9W-W1U5 zD_G?;5`D)LAf%4gm(Wpk%jxsOdmEL2c>|RRK>B>q23QZVLOdUI)ka^3r53lX_yGZg8tf@2Za)$C;rfj^wEy2?nKL7PNrXg5*8 z&+!oWXA3S)^-R-#cr-Oivw9zEpp*=dwc~hU(eqr~12i-aKmq`|08^CpWL1Edm@imE zti%nVWlBWM;i|T2yY}*hPON|+ZBB7<{Xj#W-Gu9%J9og{rWg~qpg5`*|9b!B#cz#p zMtrt^algb-1vHc)sy*C2Jlr%4stu4n=&b`f;C};+s=ylRdwHe-jQcmwa0}H| z?jKX`gRQzn-;Cc)tTZZjnhJHze@i$gkWI2!u(U|$H4eM8eOh?(B3VT zj#I0@t`oU$zDH)45C^QKdzK8*=DF!?g{bkxD;^=Y?Zc0|wlXJ8BM!UJlZvHEj&UX} zB^1YO#5$$V^fb4l2!wy4nPJkMor1@>-w34IN~OXu0zB%dzTCL;>8HnCRdNvl?z;>G z|M_knzGC=oQu?cL{m|df4--m&K_jWHT{W_fY`cHrM=B<^-&T_(1d;rAiN5y%Twgkv zl!AhS8#ZwO7!BL>j6J?Y{lm-GxAvC1)(=6^YSPp%<;3s4C}rpunEx5#AXa(!@Vj-1 zv`hhNFp{r)(oFm4gt|6OFp!1%v^*8k5gz=Y>0MZ(J@CPK|M`sw$c#(3X5>xj_RoA_*e zpjY^)FI#1|F|xVY|26jSl!1XEq2}zo0giVmc3nn0QQr@RfvVfx=IlR1^~BW0)pc^` zyGX)s3n2K#|9elY`biXHU^XF?Qq+87^mBG=YcsgJX3x+Tij5b4p5fMm`#JC9IK*tG z#uf4K@Zc_R2p2tcc%{!|59{6W=JdqSBF@pupZoo5whSxB_oA7<(sq0cwXuK7#I(td z+Pi2|Yk@J)(H%9RkgF(JxiK`_^`bEhC3bGQ9htm3;6&-O)1gMEY!*ZuLr}NV5B{nH z@wuIEeVW zgSEG{`CNSyH(eXpY1#&j1X>>UhkY(@yXBJks_oh*iM`>1cl|J#)Qc9Mo24wVQ19!Q zO z$j<)oH}}~k&66$U{QP7dH_#^H0~{el5`p=e+e7#PA)D!tfX{=~r-1+F!w{IqZLXCr zX6NR12zMf*6m48By}gOhDJUo~(G8OWt*V*fvW#)35llLrx3z}LE8dr0_c537Zb9#UpUdmhgMTuM zUSj&(Y%xK6)|=u|eRk)T?rOHS@ZgCL<{v@1)VZ!si}RRA!)qfWD11ZkzF)271cmfw zj;+)S-XM73Rl9V5kWu&=1ovu(QHNo_hr zAAw(AXE8P1y+LQtsy}If-(>a2G2NY%!M%=tePI$fnFt`h8{NElz93;>V6UW%A3BQZruj%QJ>hba-b#8GF`?pK(M-NN~)82>tyu@afmR{>sxQia} zeL@>JD1w*gyXGb3@jUyT20xn*+rRWaJ8r&zaZ#dEVKttNjC$88>TMu1imG=j~QHM&zZ{RCF}7)PzOc z)EH~3sxU^rT?*QtO_RXChrJbiLyX&Ed>RId&Ndvp8*a)p85H}PrOV4H8Fb25W;RoI zbXJbt@yhb@@-8l_zwrMn$*qA$ZpittG|#fjljeKkv;7#5z$i05eGOl)uTM<7pUP@V zQTXsPCXMgrz9+D!&H>kIv38%hjS|b;u1hrszM->9%Hq3FCnE<%Uhr7bU$AKwl3c8rHgh~`~>uX>>hUggBcPp|i@V&mefDo@*T=wG_t2)sZ1=G~{@ z3uPg_x%%DAwdh`TXdm9~RTzE%pu4iIp`6}cnkJ3}G$E-GmlS|{0s!4C(N+)jUpv68 z_^3*CYF#INlz|(1-8BUdI^T97AlMmB<@I{F!*6J+v{g87d05>PyxsPp3tnllsF)!o zC0j@v-5yBbU-BWLr}w-$OAfYg@KJgpFx!u()oe8ZP1XQsEU)>585kJkq-4P7LN`Uw zHp7Pm9augL1tFnKcZQ9{Jdg3s)v*RR08cc1@h>Z4Xnu5k({@2z+=^BYcf6GH zi8pmwTSSrMwUPLN-fUvh?vRr>v5>Ts|l(p8=|u zt^$0dWMm%t$9xJ33bq<%w-gLHitNxex{6!urvs|!m_fw_TufNDt_FQ>rTTuB_(NqAPc0)Po2k3nvfbmjZKHO8{EAV z?0)8tb-!r*b0`(a=VyItR@T0ekr9`m;mxKhQ0y8kjig53V)@X>D=>YVnn}$?lMPOf zSnOJWyi)VlkTLg61wj%)s_ThMcR2BOO=8RUn^nwk`NVf_-50l5DsBh1J~K7&Z;RO3 zST4nyE@#sj-_rJ4mJx5U73EAfXHH=-*@R~O`^oLGa`|Mwi~er!jdSe`pSU?Yg97ywtu}3GQHaY}>u_H`sG)%=c;mX1 z_HcLg*;E2OqI=cG+&qEHW%=thG8rkUlTLVOsI;WqLZjQvgzZ+8z zuU?;|Q#r)ReQ58|WkcCzdsIUn@QXvin_idUG(pV0viXvuqobLMjlo22DjpvHKwswI zkPvX@TuniPXfNYmaeLKlw~A3fTf(hbQcXX{4jiRGWsY&Uh+Ide*<$C zkhNMd^>569$W8Y9`+ute5D@S(Y+QSYP$$j))iVW@9kW_x{sn^Rq_$+Ib-U z<76dJn&?tz>*euP$~KucB{GXGHbEpM(@VWe>88mZ4~gK>;`ib+1Yc^+fp45jPf&QHF>jXn_9ml}=~ z;9}{7qiNGNJ=wYpOs*&UM8K7J-b|#yqsx6}FY=@1SeR5GR!AThpH&eazti!mIGdEc ze+5FF{rkB=rn)wJXV;Os&rdAbvJv`{O`$^{9f6tcOu0D6`s{W|xwt*Y{(2J)WfGng zc3RbxxUBC&&_FvRRAgsbFvXuUSlsyFE3c)Eo|0v5QCC}iIq8)qxpFsG20Z^7{KNC= z=yl%<`2fPNzW>10NF*dMgphvT>7tN`4$F!S%PLA_nLZ=QCb_56Zi+)wl%VuwfBNz# zNLNPtJUel+Ex63^;GE$9`~b%nx?tpb+FRIvZx}lzf_C-|uCK$RyNtw=c|&=euz@Jh@vI#A+>9HRhcA=kBy^+yVbQbt-4inrGu^Do6 zTvOD)L6=PJ%LX?5MgLWgOQQ(6$7_=#-R}$V-R4h&6N^qIP5pxhbDKh!eNAe&wz`o< zB8nJfG`5~gmc(2BhGdfRO$DK0hDwx2^n}E*_tDO*J!>!#X!{tIc^9SfsDpUiZ&i zJGrFGg56QGo zb(!whRji@#b+0WGa)*w+xUzER+Wq8y0o@k|YtL3Kmo9H~!yO$LAM*TZ*g61Ptg-{m zA0?iBaA$2W{Z{YbHT5NHQf+bSRND4Je8?nc+6)JCa3zzPGO@GkM=doDrYzXDls6XZ zMiu39ai8k*#zf^@F8L^7(y^5vVOm!(Uhb5&Gl|t%MM=D-IO9VM7CfKGdQask@@JbU zD3O5|ZzqN~@O2xOPVNl#!}<4bkAAQqhCkX{<}=cE^9LE@WtnEZT!X3~^Q5aCZmaom zRU6LR$C2H1UIZLf1a+OHrWSWGnbohmty?0AV&x#r%@%}oFB%A$Pk!H-cefCkim zFFVVv5DE5ER4diPg>=eL%uB0}RN1H9sgrj(iZ1I|g9cd|GL`UF9vpl*IWF#nHOC-1 z_%oPey|HNVmSaSrsiqRF5T;PC$sD2Y$R*2SuIQMM_;};RL~`;r``k#-ybZ0>_c6+KhY6z|F{7GZOrRNX+{%D#4glG|)Yuhm}I|1|(yuht>J+!2hB+QdC zx}GanQ)C%Qft@)wLY~-IdV4VtH9O zd^dk_RWX|}7Ek-wO`=`Y=-psi#z5Ln+yP}PoLDu3^C46GrWP@kF{UC%VOGM-4UDV17KtdH);*r3*xro4J2 zs|M_<-}GAPeC5K%9YpXX+XY3Z6IaL*d8(IEX#w(mQ2D)tq-^oYVAD+(31`h~}*pR11jbe$)0@)laEh45>*mhMs( z{Ms1Pvz!79@pPi&6?g@!?eny_!H_-D7G;4`e^qUg1)}Yf?{nY&yynYiAq%rm!git= z6O9^~>)+pxH{+@%owq+pk?w4f%bvJnCW{{OT<_ev+hiOcIrkG2q1?8gHqVpp zJqI?nRWJAztd3iaN_agk_|$EsQ%BPw$qdX-3M%nv5xqd2GD8M4rAY__zrTJ-}CbJ>0VSG_^g*#p@rAj`xht)9Mv9u+> z{6|RnQv;>RksEj4{2KwLB;1&gHrDI;IZbmv$GV&`VMZ>>M-2JtAOdoJc6M}?B_}0C zj;3<|@7L7qR*)QlMpU=Vuo_!1;lAbtiI z6NqH%;LQOqyxx;dWxu-k#VI{x)C|unI}98dr%kb`NF%jC@FY-~>@!^&52ot~ApaqgUzF+L|0JdNlR+qG&$uSiy4(t&}P(~DUMS`glRd~_infSc^mp~@HP;n z#OucUPzYX9?sjx`E_8hdK(6YP*uWP}-pQ>?Yi9e9iSD!-EVZ6oPRV3}VJ`fhv|Y)_+rbu~dfA6Llj*42+BT0a=8 zQT+c11+u?%4M=S|l*e$-SPePmRJKu96P6xu_R-#_MTpCB5!ys${NG3>AL}@4s1lNz zItRG4t`MSRWFVz%^2zeU!UV^}RH-wsA?vGq&KlMtdbGkkH z3Gp9TUUcqvJ32;YMWwnb6loZEoqX`Rr>O z-P^a{*fcCfdL;Bwt*U|k7v!dSI7uvRmgGrp&%=MIUln???{#y{w+ftX;)nK&4(Zu4 zhjyES$0W_GXrgI18Z_)U_^T%x0Te5)6u`O4??2;b=VMDBw|#fiCvI7JYc#F*Qy4R&M*#>)roq zcAL8IJD{e_>_->Nz(SLpmsz2vHY2fzWD=EM0oo;zIpR%G`2pqHHymrVGL5O9hSd zKkM(LqU?APPC&6DSmkuyMb+?9lP32SfSH_knV$N^hTpgU^5Q+%-~W96DB)FruXNQ! z2)ZPCuR-m$q7|md115qhWrvva8a12mQXwB{t4kD2Wvcn_6JvFQYm~rq{wYicKcGRT zBJ4b2qNb;54@&Mxcv;L;{P2RfMfio{OWwFi@ba zdmklq$oQZKGkR{HD%@AT9xwSEtBm*fo9r>8SPFzn(RLs=RF+GX*(5}=B?zAS+myB? z6@w9fUjA0?$E_~74Z|BNcU9%FwZdj<3gLXjg#$lIoL9N!*uzbvb+YbG`)9A|#ALr= z<#C7wcHz`r{(z`cR+p;yTpG@$LB<#F5tVYlLtjn0upTTCR%sA$%T-`&eLXxCLWfk zw0g5QJjTjX(gB#*U5Ki4)JxoY+O%lE;1a{j_JOJJ5{K%cKF%8b#_-4HTH$l^GZ=1F z$g|9{^&J~*0odc2ts7Qb5)K>oxjKlB6U_c5^LWnGbK<5DroQ=SZ5;y_{Ii^b2aaeb|X^jwKWd*hxEimCc`bo ztM^)9TmB`D*G{xpAeWZ?hTrh;})kAuij+NH3tj5S0IJLhdv#LMXXlL9F!>4XGARq^K{zp{w zIwa&bP;C_0lx7x%yTqxWCl-xWj{)%$tVF-@V86bLssjCAFVeQC7z0l%GBTVINJ&Rg zXsNOHUu$TRs4^(R#cRRDwWi}A`;F(u>994GsR^c0^%eXmd|K1BpK+=tq7|_CtH??> zOKxz5sRgz=hW8gj>wt31!Can=W(I^F&Guj-c&}{?d+)LM=e-&JPrvb%y1rPI;EBGl zG_J4|T;rI`e%w8lpMfe6GROi06V8z=T}+zK)WzBEEEN@t3fTVxW;UEHJ{5g<9_LT) zwM!Jf1#LcZ`c%w_gu|M2sa$GMM*msPN)Pwjw9~)80lNcZ!Y_Vnf3LW{TpXK^c|~_< zxgVy7iVQ5pN7A;LCc=pr+}zw6u$rBNPPS@daF<4gb$=>@+7LvJeq3r)TO~rREk7Oi4>TL8U_IY| zesw8i@$kxcRf>W!aXl_DYZJO+zkK}MLq?APY^>iev&uwm)Jq;t;~sZ?saN`{tRWZ+ z<)z{D(7DBsQK}mK1u@5o^fB&ZW17EBU9lCxPkp@69MWFh!y3VR26CKftf_ITJ*cSL zqU)K(Pi$vCq`#D`6V1%gNfH#+0Lhr%^5$x-7R9eR&S0iyRGCzp9cyxmq#Ex^ymLe< zD-D^zQX%|p0fyF6rMa|K1r4rdFd1ZvSFYTSXJ5ES=!|n1P`&(`U!rhuEmB&tx*JCW zzi`@}yFIJ9-2O=f6nX3WY^t)iyW>TU-aDCPhj|J{-3^cHg7&n%@cYfmLhKp&P@p1) zdK=#QNOx65-8)OvSICKSo27vpoOO<=+STt9_)=TS#F>ga&)tc+HzF70&E5%-u^mfy zA9b0dU=+ub&esn|N+^lqNKUTQm9QvRBq=e@o0 z!z+je-O|m+Qk(CGUIX^IVz@ERII+v2ym-xfDl6-k9WKolp@>vs(XkyhB_;qZRGBiw z1xY9W2y@Kqi;0~)SLdT_yDO-EY1;#E_z+$p*Jw+qM8~P9PQML%J>&+CwghAu>Y=_t z@0w&#sxDG2-05g|adxM;EjXWF6e(pnzGIQhgXGT(3!$|TQGH&c5yTc8Y!vQ2=X_Hh zp+#*UB9ioE5JfD!6(irdQk`;j`p->rw(e2a!$ zI7zQ?xFqujy;{Qw+Th#+mjk^|A582!gqXgp7O~e4Wq1JE5ux>nwN-w`(%ihD zq@+^Q8nhwg_gRLbO|eTUjEtl?ckcxmtP7FZ6^%|85DChwN%_u6D@>IT;p4A!e4z1* zC;7eQ25vYpk0O=oU${25kZqEY)9YPT*CZw6)hyDm*wZ$hw#-Y1;?BAm(ji~C+De-V z#&`piED&GlPo~G=6PuWSzmqhS!Xdx8vwV}fLHQp~O}JNaI&-^{TZzv1Z^xo$W+{M@P*osv z*+0dO-L-zpgE4kTyv!Ri%8VZsfr z&(%MJ1mdSk{U=-XzlU_%5`$?j-FXUGOG{1ttIpjW9qPrL!iPT1RHajMmliTuS`{K1 z6(aeTd+w$!J#?J3wmi0t{ZkXR$Rr>kCMFI$yn$ZOmaCzoQ&8d2yyThkRb)7oWH3z4UZ zD=qkS@PB69%nfc9>`7E0kk}~x(|+B%#OP6jvc{_2s-(23yAsj9$%%q73V8^#90coG zPP^46qF&$xXV2{ORd$6H_1MH7B@A^<41jMOY7Qi6(t!3mG&mO)cMu?Itqh5Ud_N?e z>ep^xoFiXnHk*?-Edv=u*l_IkQ~t1wEg2pEJ-eWweFXCHyDi=g%2aaFpc<2^cy~pg zrrTC@sup>@XAM8(GkRgO z{R|R#?VQERrgH05q4tOR_XYwFVc>nOJ)iphqR~hN1-S$t!4(;a%|cun5XuNw%-@%J z*GW`5{Z8TeY!k{*Ue@_8PTX)+LkdG$_BTEay$7i-djPMFV~&V64Z5GPt07VmvqtPzLQUKiq2*ZDc(9Re|hRe&gcZp^X@g_RsMGodc{~dgg_K zgD}h`=^27#C06li_&hK+lTU(0y@Ps~I=8105M(Tb2$p_myeuOHn} zvI#&LF7glCr=J?$$R()Jp9a&=wn<2Dm`hq2@W@LWDN*I2&P)Tf(xQwNjTA>U{p1;_ zGS!1lG6A((&R)~IkhW#&;MX1$qyUCv{)*xa3Q)iGZ0Fu#MCb~Mw}n=cr>1sL8lPm_ zSsD1>w3@_f8DT{Se`Q_%^xPvIJYkdz-6V{q>wS4=A8~yAGOH(y3l2uo>kuY+#>`sF zudGgq)W3CvPsR`gqpFa^=hJ5=OeQ5NpDpg)J*tSXqcL!1zwsk!E+K6vKeprlFHVdGDnv##h^zxAf<-mTF zWz7`u#thQMoDgVyq(qVy6-G{^0oe&k+ONer1psERNwQqzT?CBLG&JL|B732=r^p7qt|NI5mp(_{J>XI7&F6V!^xY|69LtXZYG4RSOc zqFLq7;qH&_7$PY3MN_1;FcJ;5i>GD?GR{7NV#Tt@GNcyHS4resM*BG{C{q^h*!_Be z(E16BxF49BgZLaro^{?AXG*w!@9`gV0VJR>_`O*{L6nM9R|H#h(m#3gk+MIF$gU5=b_ZWcLt06%!r@%2p;A>Yr#(h>U2* zfl{9P^PO{8WLG&f{_sX-+&V3iag6mC)uu`Q+6Bnewp z+%dyRy*i-NIIgHOKy;r%F#ke$^@ZiwN|7=xzLzqW4!<|~^kDrptjMxW-yM*nhXdAr zps-Gsvj!+KB~N<7v_4j)YhU(MwuIr-E-wP?*dQQXMz|~rRu8Y5U7MW+)cBo7T4Cp4 z;P)r*I9a0P`+l2C%8W^lJ^G~X+ORq2J}f_(xoMohM=j#sJ7 ziQCWdp99?d#6rI`VtvA3-b~d9cSea!daneiop=y*AW(h0e>|$F zOJgrA6m)#f(|-AzTz5h4Wtwv`6;W3{KkB-_Q9-5o{O2(WChR_GKT=YtwRXO50E=Rv z0|9R^1r_sSZT(b*#!Sbn*qEPGCP#tHtgkS>O40f@Y0egk3ZKFr`nOM>+Q%axnCOR8 zhoxY}@sM$s|C&`E-?2G=?ja)FM$SS)PNS{R6(;Rir~Q+tR|P!+-KK_jIt$MpRG|p* zX5~f=0;bCIBqle$8^^FR1i4)2WpX~{%?BQVho7g6RwW0E>Dd(pjnuob`TC8QKZB@% zmqSKn;z*t(5X6)K15T}6N>6u~L2_QLcJd&{>o;t2x;PW(qvtd&4rCOo*1#Xq{}+}Q zNpPW*)rd=||D-LWm~Ej#fIO>C-M59QR7M+mUHtQ*3soTMuEXDXpr;2MToPZR5Jp+X*C(+1n=@d3bOJhwl(``ca!F8g6QL8U^3o&b(?#Q0H(o=p zn7>=s&#&<$?SFiWTjK!_ShQUi9=ahEeDKa86kT^Ukc#YEIzwon3sZU_;r61?<+H`Z z$wJf)yb+EXXWN*P*IA}Y$>=Oyw@io4PpHJ8R~+AD012ENiGc=6nMD!iGRs`>YUsya zw(gGej$}M=lL&cEw1}eA2XaX%8VVX+d3a(5|7v` z+x>;2=#`xl0oaygC|WsMQ_GO8NL>s;iv3^N`|pIfMbmkQs&>OPE|Sx-LKH< zibYF^= zP_>+3_Y2f8flLgm_<$v=Sgu_R8>wW6gcPZm%wttU`Ga&IUc{LXNoF%{c6Q-X0b%ib zuZ^iCvjVT-F5AOG@|n}XV3lJ*FDP4QTMl~SVK%L*-+5Q1eOHi?ix2foXo~{ZvH8;6 zL%r=)^ycMQ>Sb!-R9Fc4`CT?k{l#YS?O&0mVL{R_kC&wCFL2o`MJ#k{jdJmqXBJ)aQG z{OEh<2y#gOaicl#8Rn1hAFgSph9MaOr`q+K#g4-cB$AOLEkSH*rd6IdZ*Q4kyHx#W zDM4g8aGLKci4$A(rA<-p+20?~Z{}yCof0Cl+B|KFcVzC@(Na`b9d?x_FT1RI7F65^ z?>L;l%~&_FO}SI1oNMjZ<6AUg{t9IAzUSe0*<27*o|4UNFj<*%+SO&-EE(oeQ`@lE zf~zXReLSP}P^r*>zHfcM76%Gj)T`e&S)#-HW24cForaGn1jKq!x|wxv%)L z3{Dh>J}XxAHwjU2E08;dgwj-^d8Vl!vgX<#{%2_`Zmhg|P+v>pz{~kiKfqB82_lme6Dn_rISMiYA;DYT z-L(Zn)Wy*`F~HGh4)_9NjgBV)xx+sdK6rb}udrPTYtHmy3dhxSC(!oFUXieM>@h9~ z-PAR&{_-|2EpHxV?0@-Nu(Et=!saRc!x-4kvN-G@npW3>|W&KipUL&{`Zqd6;_@%ow^%)E?pCusLVpt9GlS|4_A?go z&hle(D^J>CsZDK?p&)YX=%7bWk%U+0OWxG6vOmUuN`M~gB7Hv^M5d`nb({eg7vWo0 zxg2l^%3MqAFE!5>QFgAd?9P%$e({mQq<-p^`4(2^E#}MPXjKkkltB2~DNLae!#QB3 zbzY~{WZhEpHT8@5_>-t(bp1Ha_w=NdmfuK@%KSbjO<|l_DHN^TQ}QJ(_fHQX0o+H~ ziVsU+>!a-is2i^dokRJx2k|x)lR-hWMjmI*ZBIkq!OM@65-~dasdy}-eD1c#Yx`R} z_E+qsM0;Pp1!Yr~ALsM2#ZZK<1`E-`I0NX5zf;6yW()al(E!*G_-$EVuoQz{N>-Q* zh6Y0|tS$LH4zk;q@y_)BYVA>3qSy7-Wh##5oumcOCO*x|GA`JK&)h^zL zDG=H%#ug%l6H~BbWamdsgIg84mGSucuiF6RxVpNktb__aY;&EXIE}&9@A_T5kGhgd z@tzM|{)KQ~<R6QDCO}FO1X={L*QBbw4%(*<1*WOOJ&t~pQ_$BIcxwduUc-07` zFQxf+*I!$70{+I?KcH9wBq>@9MpfSnK6>X}jgL6l?Cj|5tdI!$ zGCDXBCFpr&*xvf`1Hx|;ZJX<%zp`qDO0){B)JtR%S_K94v1aV)PAwc(f~n}jQ)1-fQ7Lt z@-;iC3jr>xv1b16@0W=DJGk`g@L_kF3&1;B+jNCBD0R3-8 z^K&v2Hx&N+=fxUDMH+2mk)8p=fevoLWBlq*-aIAS%{NN6i(&Dz^J9r|@U!b|@pS-y zv-3L^h)d|Jh=p~Sc3~)ZiaB;rYq=WX8OkVN57ogIcDK2&hIEA#(r{0pSBN)5SD{6w z4tfBb5}+_yQBO$xM+sBZ{_k)^CDJx*SQ2(zf950U*&hRe*G#iS#3mS%(f#Uw1Aj&l zgSL-dpBwW&p~+Sj)u^){1Q%UNt(t?3+CK=AA|I3&7tb}pd5LqnPeZogYLnx+`L@8% ze^j#hcLSsk#6%II&R*Al*V*LP>*b!eXNf^ZJ|)m%N5dlNk_(}Q$%Xv5SS4q5^P8$e z;L1wum}}Jd3tVxi6RyOl4;IJiQd=PTIeicwc2}*Bao0ObTAS1An|dA&T^MC22d3n^ zRkC|CE4DiWf6uO3yjcFA;UpS+AvfY%EBbI(>bKwA&yZeq6s3 zSj}+6mjBCYa+pBS*Re-*LZbIALmBAS^33dRB1cAv2FNUnB4V$g@nvI~=NPt@ZUHr` zv8eK=Tp~pcLMz((eH?GcoN^T9$FlR1@mRV*i;IqTRFobitYT2t%i@J8eBd!l()eY( z6lQxRiSMnyZTsLx0$0BI*Z=$<748#J$+3DO*>y5tDQ%Sdr?w5;Yu#ZV(u!j z(a>&6r40qLiK#Iux%hR&w`lI9ri(oEN#c$EdgbGgee3(n$)}r~eVHl7-JPO+D?eFe z7^&t)sBuj%W@=kHnK`$vzF45f4Y4@_;hVq1&8S>|QGPPIY+47%wKkJ=b^dL)@)ZQn zvc(zy*{bm~47iG_h5K!O72sm&aWgnZi1BBt%&)&<*$oFeRLp~B3^DfX*1IiFUFN>= zlj1oS?5>ZMT1s!yU0N%H3e;T6AhtN@%?62QO8zWXXF(pPXccX+tU__HPw!e4eimg1 zI@qF6hOSv9!s|^s^ah@9K`de&9>|oF9#LB~;b8qB!e=ttJNdCtLRIO91XWc{7!kK=}H0hf*mQBGAp(2F)WL=y;W+rOc|*jWdgV*GY`HwG)<*P z4Ct|87N&7ZV~vR$ob2JbF8F^*qqNUQu!&{p6zLX})GH-$#2oTlCD-w_5~FtR*e2Fm zG--05-}f;<*@m#X?ue*kN>Oy>Kdc z2jAsRk-d~%6U+~Vmn?LX>NsS0v@aj)17_O|iY3{)cOW`=ig=0yLZ>^4;!}L}81*H&A?>JR6HRlqgLkJ9bAr*0=Dqiq>;b1>HeuqSNo?Oc~^><3|HaoBu zb-112M0S8X`NV?}j_?dOj=?NTi16iB{cw+F1ObudpUv1MZHx0_{T4w_$Z$o&MCvlX zFN>6h_G^r4Fea`Dq%1Hvy^WQ_RLa%dZ}S%oRz6@Jf#jK=^80*!Dc2(FlSJrmtTHweu@ngu&#r0xu>8LZ zA?fs3#)eo>7K&yICnv7N0#%+jn>SLVj;D@)_B<)z5;o+1fKJ~V_Sx~56{L;;7!4Pp3G?+I} z+Y*S2jpxYCsV}}@l`DD5yasBw#gO_XmH|TTNG>W`J}YK-R@6g>fx@tGC{xM1)vH!{ zoWOEnFaAmV5p6~I_S$d!JBU)+46K*Ss(-xG67h^TP+A$ytQ+Nb>LJJw>j-$MgETVs z0$&mEuF5B*J$7}*xVMCP&PYYm;nZJ>BafAbFL9B@;Xf=9&zzf+TYRDDAZ_lkq&30Z ziDSH9l9yRjy>-wJWzk2>Ko*XBKo*K~k84q4W)GjN$ziQbPkBQ4{4<@*HorrZ%64&r za$$?rN`b5~67QTDUKu$YVCnhW>q!*hwP3Br=UF>n|eMb8Dy#U*0k*6t6 z?l8yUbabc5@v9t~V`KU%d7+gQT_Bu`rqb(sL->%Qkt~n%^{>&bdK=r~o)&GqrUxNs z3ZG@I5D`lSeQ!{=uwC7!ELqo=KH*{RL`0OS5?NGkgicXNAB$B$F8xJ^KU1PIR+VCn zz~>rIS#-DL`1R#0YkcbDtUcfPOl=3h3YIXPI=`rmzH`Uw$f)$1l%)>4ulBf9VaF7> zlXiboX;9>Fg^NlnbgOs&XtODneXhH|WV(JI5bVIpkXh#}{rw#-YI>|0I~IPQsBbw= z=({W`Hh0B{1i22WZh2|b)#DbNM>*0)M^X&?iJT0f5yG#sS#(eNK(^)jp&QvfW7=p) znr=Y4pDPD@O_!0JG#sI(v9hg|@*yEeL$aH3%4yD0O%~q9#F-ExYm(`C8`S7OhF{6^ zO?5M$#!c^+`_&FN3YCWOxx2^f#xs?5&7z zQ zwrIOrEL;}_{;mDSF;pZ(`MbvB$E1EzN6B6+CSwgs+w`H3&5S}aHriIWA{KIQip}7s zDxHys1)~>Lm5#7CwcM3GTQ_^1ksQ|nSm35)4r@8tjd`J#y8bSex*xgG zKFJfJH{e_n)f%X7p3|$T{LzXAOjywdX<^kFEGMsPlUOt@Dsxy8^$dgPp#Q~-A3E?L zaXCqD%BdaJ&q)gEXvnDR1pamzU)GHEAkUrGqHDd}1Gs@W8$ zT1OR~R3k?tWPZlC%B>{jz2V2FWbuWjs?{CE$8~ijozRr=M?5lp?sy?3YwEVN9E`SU zYdGEM(hm2m(JX?ZFmJpdnl{ELVjxHN)U-)452G~8F_SgS6uS8?)$Z$peCn!iA?)-` zgZpzxJ6<#X}2=bd#ZH`B!~1K+f`*^=gLr502m#DNZBC+oc+4pAGaP+j214Qr#t=Qv(+ zvo0O(e5ylq?`iNK87%>v51&_*OoB!oJFVuVy9xF|wLXu<0&mef*l zd|k_3kk;{EU?TkIG+={y3}*sHTf<)1*!oRtCF`kiJ|QP1Qe4Rjtv9 zx(`UKdBa7b2H*_);yRK|RtcAxQx_fXeciLIDk7oYAZ3cUhoDSR9EMDLLMO}ZAZ2ga zMgnIPWb<8O&q=C-rEKH|%u?;cF1DfOE+aMR@|2Da1fvD`o{|crJH| zyoJ>qgyklAyrt&oBXNe8rQ4~^?y-6@?X!=juZZaReEkA`bfG7gM!0#DRleG8W!Y9Q zicj|Ed8`#hP=59-AA`UpbTLomq3(8zr7Z2r)5zcde!Q9{BU3PhjFU%LzQ(6`W_G#W3E7yaRP7vsS z)uHRujM2@~RaQ78!78mN$-UjjE#=%Y8!VM+7E4~}?iUXs5csb-q0_w1{4GumNh5lF1T zNUVJeVhh4qY-ZlLm!mv3qplYS=MSB|!~}uJu7S`4Eqq z!1~t>sKKxyDb(|2;sdfuOB&k+!_eRekvo!CACsPbA$aNlNIVrwF69CwMv8PBbO=^U zv1~HmJyMu%qFwk;=W+649z(IP`8k9K5V%WeHqRa_6hgxxxT-B@W8n?4_@GmRwL|03 z+?j04lCuVY)#vqGdpH{hSrs@MQQej9AoTWb&4ZUVqbB^(hF`hYw zMycq^N{i6+TK^vw-L@NL6vMw9MRNlDeqvJndkd?Oiz<@CYxRHV)=FP;GDi7k|Q$O)!u5$E*pfEFfA(? zvP)+9420wH(ZdeV!J2`pkN9W3|b-MD|{jpZ-BM>aU^p1Kl2|tf@OqCK$vS(3Z z+Frl;G>?A-T(%G1WX_qjoT#+ld$@L!v4(Ofi!AB*+*-m|&!?s~s=JFlQ-4%TJ_SNs zt4(qCuD|eGVpN_PT=u{db&70h$SOq zNER}p?N?tN(>5P|hiH-)a?t8x{qBCXMoo_(>v|j2Yy0<2J+ra8QeTc}$s;ACW4WG2 zUo`gphwXy@?VR~&b}{8`f-FAEUyVs@+`papxR&{3&8$ME6W?R4=Kk$>(l=gdRZMs; zgdO~xZce-Uk+(N18Pis=SJOfKTvcdF!~6yqm@IwmbA9sF4o;`VjGWAjfrU2XKVM=R z$l!&~9In@Y0V^cT`s+^CU1+tEbJ7m`&4sx=^6+b!@oPKS6QfX}jt)*lm+rWn`X5YO zcEZ&k-#_QR|C=>JWN(;~8SxQT@LO^Ekdpa5BI1Pv3CH)okH=F(dYliUD=j~Knt1m5d&>`3$W}Ci-mK&ecvwONq7x(az^$jH3oX?{`|QlKo*EsX zH*Fo8sx%5WmhqnZl-UNlFH{Qc(i*(+n?Jy}*r4S=U&gi*+)K&mzej%aCr{|2{~7bM zcNSM%k27lwa-0{gwO_asFXiTdmi@I(c(-nmPO{xQFZ65nlZ-09A{>g{?2d_slK!>qf4F{O&`4v2OE*k5-;Io|1wbg zq;RJ_OcW>EVjSwR%lMm1H4|Cc-A=KZb#9A+!i-mrEAD!=eKpG(c0Oai-q+Ld(;rXs z%_Y!E073cZ=dQeRlc1)O<6sozL-?;W8S5#N_{1o*-{1xw2dq6P>(zt;eOgLM;Cy+DHg(qdW!r^YWsm15h^0NycTPE)|z( zy5@fPgP~ornk>z{4vBh57Zi0p`L;4!#`O!$dg(BT3bbgX^+C<7f1Q|$kFIe>I_GF` zJ^Z4@6(zmCtcH)$*-5QJ1N4;s)6_@TNUS##A<<5I&qD}p@GgygF^clju;C|V6`9fJ zS}@p7eYr6I)li8AE9J&ZyM3FoeR}YPkW)mxy=0$5`;NxruLIU!KAhLiT^i+%03sxD?AR&A$fh}y;T1DJu%rr%9q(ac$M z<6YzZpMFR>KpK+ zm4&2ArI+GvP-H5_y@M@F5qprMc`B1&yG!!I_X^MmJ&krQ@TodWyLdZO~NP`3|l#XFMz^`6GYdU^22^r*2k!uS#ZvFWBPUu6JfGOLWl)g6_-MB&)F8vC2@Ch*HA(c9V;;Esn$D=r;!h?Z$xlUn*pI?$}?&I95U4k1ts<(Wx^!IWD$T z^ubD0-X#6)OYgcOI;1*`dLyUVuhr?VPU)fd((45haiN2to98Y@44E{{w2NueLk(owl^@JoTG!c zVTv8l1{hzgzI&EwtAo1b%Ou_2tVIqpKRpsi9(3wWRy&qMmzkgw0C-ikH|2JEl3DFd z6V==m1;fWfFMaS8={4yU=_OB?VmOd1 z+^f5rz8Z#eGF}p3HH$4PPP{+>mlTY~^gr)&dh*y#^{{9~(1|X8C;07Bu3hiLjsC0n zb_}eKV~*~UcFcOO4C`2BeM08S5>206F)KDqf<5x#?wG0!p5NqG)~(Kh*1V9oc%Z%Q znC9pGJ@gtV07wO8!QOKR*E9U~Ar+Eq^UeRfPUT zeutZ{=2PNjLjhv-pKppuhseO8SOL<1bI&I!6FRZ^`EXcDtgE+oOM-l?zIJ+!%9b!_ zja%nFL#>1i_;S#i_`kWIX5`p#5o6(FS^?j--WDZ8-q{MSZ-(j{fp_quRuolPm0w4yBqMIY5s~op}AQ^3vSFEkVdhJIMeZ6eRCMu!c@0OF8sp4o` zo$VK7?F$LV@VH_?Y##~+JMmxMqvL34Q)>D7(aJr`^xv|r=ASjG!$Iml_wk`2E;ej4 ziD)0pxzoVz7V?T7@bdjWyr@~U4Dz-=v+O+#d94siaQ72_mB-JW&EnRVFypo@2E)Qd zNr@ib3>zxe^EUK{iK0jdoAbz-$>{gZ754flN2^EGH`PqBAqk3g;+=lY0uj4*qk$AF zh?@FQhP0;)#b??M6-4z$AN`b>;Q!GsRBzkNKHTk&K(I@X*4e6T8Tv~g>SQsMmBUs# z_Zq}nndp2Dm(){1$(`jrv6dEU@dgxjBWf|u$y?~9R-g+7?bPzOu!{PdBu~0SFk?+@ zN(RYo+eabmkHyCn3d>SGWwT-kM~zt5bf#(QaXKDNiaTcKiHA!rwB?M;Ic*ZS6BZ*H zjtB=KjtKCt{aFfd7BNJy`>1(@Fhm%IF||`5gOL;tVGd!)puH@(V=IMv9j~Df@)>;u zhXf5A;_)Pc6dCN0w6B#}7(JT?m{J9!N2UP!!>9SE9+3n>$fQ=oH;~h zd_y{;Rgqkor&BIFGd}g#>G+?EOUIm-x(^Wg;Vxl3$x9CB++_n?QuC#G#S6s(NwK|{ zn@I1(gMP}(894W>%H#CgI#L_=3Nw$>Wh%YCBeKU;Est51i&+w)V^nf8Gn<)JQ&=HX zeZ`MjNFC6uD;g6coDmEQwVcY)gxAf+93zJ6Fw79D_C4D7y@>1atRSAfmGW4!{Bc** zn{t&?h(@0Ck3low&hbcNgcM78s6{gd8!LKz zi<18RfnwBydY({q_~TBfYG?ZX<_K$9SNZVf4BwgdOt+PDIpb1RJI%>naDuJ%p+3rY z=SpSWY%N!mRjYFVI9(yvO2+xG?v-le`c%U6Wx|P+h^fRkXJP6dIvN^rad9`usciK> z6K*`4x-l8UoRu`_WM&mo61!V@c-hXf`j^R}#^^jKOM>QF)p487iuog9)L!#BZWEO&RJ>zc^?4GOB6h zG25hQWGgwj?>&9(V%8YtK4&Io_mrTz4_+7TY@YWx)Mc8!Lt3Cl1-ZO5^)J`M|GH*4 zYy^Q>{3jP6Pp7BOHiF91yL09>U5`dRwz|>FjTPp5JhMX0S2BAJzmB-p6kd0eAxa!0 z5FzuRiUPy=xu{3Q(=cNE08DY>Y>P!DnBtr^niGc_{|~1`ri3#YePgmFaL5>V^Y#%_7Bzj zaU7;kDL{dhO|zd3rDJ38*r4%|BZIn-eHt^-V5S8pL*KDljQbT{_Abe;XD0>Kk#4ey zZca~gbSBZR8c6M%@Ki?noN!5T@un1=FUnUL$Np2L-_sK&6Ihtjjt{6jMAcJ+t{dp^ z^hc-e7y|qN#s|8N8c0qwQ}T?TvdR@ZnvPe3`FA$BB9KWU*{sHlV?k?#AQ4`2(7(Bl z4bGd(PhGM^xLI4cZEOkG&61Il@|zwU<6Xsd|CDjFPAtT~u6O@J!(Lp&bUY$2S+*S4 zH~IC6sW}G`h!vHC;93;S#XZqj)Ad+j<9@3%70?7a3>Q6Ub*BG!_Ybqv+wqy{Pu*}S zen&eF?#kAL`$SfDONUqgb6f;qi6YW&;uoI0=wXcnnQymV_|AVN9k*xrSFoZkB{4xg ze8nR?&430#Y-{Mxa&d8?4y#Hn`dW~yW$Mgdg5hbqxMI0R54t+qENsoiQ}Jf6snbMO zvEH|P=G;`_TN4Wl^pa6Dw7n7qBl|+^-HcjAIvMb z{IT|9HN{FjvX3iOTFGsOP_2>#IdPf}3vR6lqbNr0$IFA_G6f@#N^HwCx(a0j;$uGBdFLcl+jH5`c!$C(;(IDQ=Dc2rV;F<>U z*l-rO+p+fm-sxzd_+%!vq`A1z5Uy;Xu7;SCLaVR4WW9urTW!X2w!|QxCCk})K||)f zk(ReB%9BYt9JIor2XBqpa6S)&;Gj~7z-BKYNvvvESJ(Aes&KVAkNBUKppHUJd5PoU zBLydws1M*-t6g<8aqGs9Wwp#Q%CoP2*-xgwn6j$WoGG!)1-1g?+|hLES^Tv_+b|A< zP!uEi9sR?J@7ST}g!4BM$3hC(Kg5m8G&bEtAX_mbn_bkA9>m(#e)wf$~-;yaUq0659KId ziu>OSN@wi82}d2xpuT_q?Sn9J3J1r4({f)!lJ5i*dI|SklWXO!P$e#ulI|91hXYNA zX3^+AtM}%>{gzKc28dEUZx1bn86s!B z>_qt*F#|?dSDwTrCnhR`!zxDp_Z|s~CCl-7F4k;Mdy)j-X9~ zBx`OhtIt2Lupuy+5uo?P^pa>n8(zgQ(z85zL~*!?tcosfE`D5*kqc#IwX(0mu#VIX z-q*IS;;>;?Hywvsdvr6=`C712vSTggCtYA;sy&u&B4K6Ph#6kfgPOGOpFf5=RIGSI zKHspT`^ques9j?4Qo_^2>-Fo@BrdzrrEZH%LpwG18sjhsC1k|b*R#=gGfq;s&iU3W z3uJp$fv;}%nUD6wyi%2-9zf~~H)yI_%5HtOhxOXbgtWj4#z*6*An+vU_o+n;3* zt?PN3Xl<^UBQ%OjyIH97t8%h^wC35&`!?yWr4X0|P=!BaS^ufM(_pyK&zYJ%y!qO( zb>)3&>268WaUb+WvfL3WYDc|9Q*X;wv$wcmFK)!Pj8N=`h&QhL67C(y9sEdnc%oOp z_~p{G?HR9A;nSaQN#r9}SHC)~_&D(khp!KnMbWs`92}wiJiAa&5~_PTdrweseLh<) zrp_p?yKDtpvP{o()Dj2Kj(mrK8YwGRML3UV>M<5o3Aso`A{dU1i79b?;=A*`tNP_D zTTADgTxZirwa;z8|mWa1B^S zP*qT;C5%$|J`c|XZM zrb-=(Y*H-wV1!o_Y`7kwMoBNk0<~RZX3yF1N7Aa;f3X?JmI7_k{O0Bv0<9ZizAgGL z6cv-nk*Os(6ufbNBY_N58Uz}7hELB&{REc;jS~~Qul!ILbG~r$HI+6oKAyv4p`vT; zTK=JFKw$TNM)@RgjL*xTVlc4dK`xLkU#Z$w*z>3^F<(e0pO>Xm3~WGM&1yX5A0Etk2}bASsH%S z1{@Sb94j?2ax88!scKxi64-6Y#bS#lDRVn)!u;^X6FFb_u%Z{2K4g(2lc4s{)Q2MO z`r@2_bZj+z(#4NP=vZG&3=1Sn;Kz>^Rdr!KVX^u?=!5w2sMy6CL4hesa!@glpMOH% z4|Ot8QRd;1ZG+(B3A47=R_(Z+{NhD3uXSB{Ew}lNi83Q5dX|b8^n|-4bxA3G6dV%i z=0zh;?}&)@W7)KmzJB%DQ)-6cwycIrIY{sFJMJbQ>B0NDScX(mkWky%O7FHo9c5dY zo=&HgKJKu`luyFS?tgeqBkZ|)7El3&R9lYJnS^Qs1o5#JWwte4U7vQ(4>d|GkuiYi zM)dX;nH`Cs?)3Hj?0M$EX$eHz(KIG4fde$%u#2gM;@F*$9ArxvfqVDvF)$>*F%2`; zWOMRJ%P_C1%YvPKw&xIGV)E*S%96QeRmZw@L?nk3Fp$3LNJ`-ILjx(AXTglYAqqB0 zS*-KVC9vPmNwDQ-IRM~xGIxq%D_60Y(_3E>bR~guWz-47x%77V`=4cWT-UFQ?oSi@ z$SAerySt3On`l#^+IXV)0IwHH8SSw_VTAR?Qm(~PGSJtmu|Ll(W$oU4l)u$QNUgJl zmFg{a{zk-R>c^ySPthvw)_DPJi64k30tIHed4rbhrX+|JQQtt{^t6r&^^hh zC^k{i606v4P*?VKOxa>0Y=ji?ZRgG7_RL7OW$LMCYun;dd)!VT+;b3Iq4Z} zt;z6iuC4LfCk`h>v^7&SmN2WHEKHpUft*ZFY3d5N9qsPs+Tjhor}6I8)0sM{sX>XiQf%0J z<$ya=r@gfy4m9db6!(_jEl9@z2a{xNu2TQO`pC+0a7LGNy zjYT7i^3oZLbdTyC?|Qkr8-E}mg|_oqj@Nh{&A_pC&6RoVC?Y4v-33`IDf0IT;2^n+g_m*UMKz%h56!~7Ho{3> z_`ggyl4CnHNO8U zcV;DPB3m{4lcAXbvXvBMXedu`HIUH%#_ikbTIx5yj94afpl&Ud!Tg>pD46S<)q>Kh zVLi@E!%VM666sVq`>hkj;;Z}KK6RuK-48B%q79XkmDM{#zF3l9np7}QkC{+ZK|siO zYbMVj3A$^apFk($R60u!_YR4OY<4?e>(|!T;u^g=@>RPFtDG!Ot6B?PSB4riLqWcJ zVcb+fI2DiNn;?wAp7+wSEi`U^o){;%Te4qMS~@qFbzE8+w3+mH#IvHg#YDoi?EGS> zTlL@L6cycx8Qr4wF@DMc^+25-QsXkaNMbD`q#XOf4pSf9`mVynFmjk%xF(iaF7Fny zOF&vZ>)P@0B%{+-yQr|6g(e?e?PgyC)?Y&=r{RzrKs>+wK z!-rPEoIBw?9&M^1j=JvCbU7H{cpRB+nTn@BuI|t;Gdp|SRP6%j6Z5Pee|e8bXE&MY zVX3t*3~C^*{`{@(v|o9p1N3P=D(E`x>CSr$tx-AvN&L68O9-;@__5i`A#-V;_mC-AfC$DoQR5u9 zcDB7{mkzq^U?>)5m)?%oNzXjE1(uD!S_uwWcSFM;D%)@f2LR8q zNxRoN9O(S^BOZ4XeBhY1#h#rBWem6@HS-k^9IP7~i_w`|g4Hx4XQ_{e;s%g8awoHa zbnGeojcM| z#!ubzW+8+CRl>~lHLK@A72qCAGq#EoMdGUojFPPC?4TsEUZd%W&k@=WVDEN$DphH| z9QCQU>Uu^Wx;IOPce*AcG$%^KLjP#PwK-jM(aG z5YTB9Jzv1{gT0H@_hb-c+DH}lQ-{`^W<=S#hZaFu$$*Hp5;PK~{Dm>%n#Ak4%Z-UgF+`L}jsEzgTe_o%8zySC{>+ z9vykj%>(yGZ+G|Iqv4_Q$EHkAc8U(CuCp**4>JlQ-1aO6w!#EY6y3nYt_*R_^IAgiU3

FiYVdpk2XKWNFb;XGLaI}zg8TPVwIf#I68g7xJk9`GAptVZBQ$p2g> z5_Vztee7}x;gq*m_?etshecy75!C6%dB5af6=YZHbHbs;iS7+j4#P;WTunAkfzJ^^ zPd39Nx#Y|E+MD(seaanLFXx{j5NWA9d8XBcz86Z~M7vO}Ad%Z(y?F=5K(99!99RCO zpf<5_kGRSY7MRFq$6>I)Ixl~1s>WdpVds)uv<9gdXo1kceVn zlEPjG+XLrp|10Jl4QyEo_Y2ak#=>tgr7wG9&X0)vBxM@nQXKf1m;%?AzB~WkaVHbR zS7&{Z=V0+F_7xWN?;2zjCYxch$t%RR_yt{(evjD8XE39Gj2dT`*Jz` zSa{W)O2Gk@UfHH=IN~Sev6uqoa0%svkRIFHB1aZgTA;LzW)XQrL0df|XS=8K&iU&1 zj#-bRs!gf7iBT1K5;zd6o#oN-@g8TbWxd*b&P^56q|*SWwTCCL=~a5~r7ztTbOtr9 z7k-k;-&8C~@u_p!k`#ac{s%BWp&C6FvC6oaD&%JEIC{%YURs)$;+mM)4=FCKYRj*m zKieyJ6c&~w^4QFzzp^sPjMk^o>X(x}a}inUec9)W&g(vdNrt_$DS%yHR(N=gQ+6{z+WtJu@<8B7gHWE|b$ z5-HwnUd!i$brEQp;0?jq(@@FN(QcoR&q613=C3-uuH7pxEc~ImQ=+mhMP{hRYb`iE z&_+IFSyetc)vHDgj5c^y>lMYyNyD3896v(a8r+$`xfEzeQwj+SQ*#Hsk*Ujdw3|7e z-&ZnBXACY^*$)_15olfS%w>FST{hxsl1w5)#yJ|OsF`tLk)`*bj_2kYG>SzJ!wp-RCTDGBCYU;4|w9&XTLk&zKZ+8{(Ex)yS%)lEEZX!A1=Y3F(7@C z9ao?ig{*VlCMTtp6bBWPefI+Rnp+qe8ye^+pZ+xD$jQns1o9gwhZG;*!3wzisY~zv z%RnsVpyDX_5oftUY~OS@EccNViRi(2|9uAF2M};sAFPs&Y{X%a<2vZc>W!zsM&@cd z%`DCBH$QN6b7Q{%sSV#@hwYf7sq=TSv2I`6Wxb9zz0gyX^q#nu>TDq{wNCfP>$_bL zX|)nfF>xEjjA!?g>YIwhSJw>#bn<;$8OF^TbvG76bm(0N{aGoBMX&*7oW;oMMjdc>5qy9akrW zcCH*)HF>IHuayy5Ee}Qo;i65Y*jxOX(SgBSy@F3b;_lu*QIW%H1+26thoMP>m#=v& z1|K(wEyjJ3XLfT}tY9SrmUTmw4aTnNd=TI_^Mk=PmS@Pq_1=>5_i7X0jl)tB(T>%{ z!ahFUbUwyGayg=8J`FL0{F$t*))yW+o_eL^I0!KUy(K7<^6bf@r!@{4*^$Bm#_$x~ zUycblbSn{qu04XH?>06zbc82+pEz22H{)aCw4t`ElUZiq;dpp>Oks(h2diHW4!SMT z*)OlhPE5oHUZ;!Wc1S2G(JzQ8qVu&+b42-{KK*YF2^SHTyiZrZ5DEqaUB>eVLgH}4 zuG=Pb96HifSJ?bb%ZnrLlaJN}TTsvilCZ&$BOr#r2K)4<6Z$zoYb2h|tNRdXYqNg! zUrva-H!DJ(@U9;Z-i??D&3gW^S7ake8fmoU8?|&*U{}Sg* zlK5m9^!jjJL-M+SPIhKC#Wg)ptov|x_Zms$=1h^g_nF6k6U`^{gZJqS>z&v3mN#}V z7<_``tFk_)0f*FMQc)VS0IhO}W!OvuN1|5#OSQ2gE4aFzXSZ)xK?!b0<=_u`OAzJx z`cNiW$ffYSf+`#h>@Sy{(V^bnb07`_LYGtcsjWmozworU?M&)9z6oQ9WKiTN{LL&*~mA z19jrQW3|m}rSpWLV#E6KosyfN93#DIYdcr>hPPn2H(L@I(h zKmqX$05AqPz!RZ`C6Ldm?PmwblF?#}(~+p)<_c^(j@RV0&JXrmBnj>I_OkEs&mTL> zeJXt_&V`b^_-8Mx-T5(*-Tb`HCY4hB-9;Hc)k-L;IJ~% zmefr*Kfj1O;AnpNE@mg%O`@upk)EBsB=t@SG_@SyEJ#7jO+dhe70qy;cHY-iPgT~M zUv_(f*NZK(a*{@LeoY~|P8b|2D(W^<$Ymx!ru3bquDn@T-b7c^r<$<5mQ9%r?v0%#OJl7tdSZN1xQOfpMNl1zI+*!4~HeAR2?0a z;_s{jn|oCe>Fslt9zmCU*n6kzhC&fv0r1K`V_`*{g-IZzCE-<8Ze9+G1F2Si+9*WG zeu;@Fp$au*vE~VMy|@tZK2J`<%LU{c2A+pPWdN?)GhC543Gzuv~;=D2G1iZFzA;G3*Z2=XiwptPEU9yVxC!-JP)935$ z{LU6@47y6zH%;%Be_MAx&1sk09L>tn+i~5VihmWl(%vo+>+!8lSS<>9J$4J>Lc!&! zBktbP;62orjPO14FgUT>Ysv#*7Cw4LMEtYyOKN^j6tGEMINA`=2nN0_Fc`j*+SveqQzLS=!KD z-Szd65(EPtK{&Ob3Zvn=DC8}d z;4nQo>j^?Ud^GHd%FX?0sH!7imo9>k9PpOKVV7UaM^NVvn7_V8SMhd! zGZ*=KrxEiWCyd!YmVCgp%xyQbKC!|SFH>9o7$uY%6I1TJ6lJN6br+pK>=e-7$zSg5 z$&OsUU7}-Gls~a0NF(g})3*zR`ay}c=Hoozlamjp+uok%IPWDPBHRbwEn-q0+hJ#{ z{{$dGCh;By9L<~@WU1#|Sdv?iH9UfATIC0U`P6jY8w}w)o_fe_(ZS0<<+ZK50$sUVvVE`UR<;I z*$pT9;}4@S=I-LzT{Bx-;JO)`v8K<5QoRyynmIT%)*V4r)*nJy*gS4snJ?CJgU1VY zN1I8>%4*hnYDR81LUN*%qxzD|O9KfC+!Li#!95;4(90lBLW@nl`P{I6pfJmndO) zeZA?tuVAG8FIjYnN$qOvW>xLdD6sDf)mTYSFjoO1g+ErR)>rn%M_?VftxX9F3bHcu ze+haPaqHEWpvUADr^ITjhqf2KX!#Bm-VXz-StFKaKEnDZ5K=%lQK!`|B1c$9Jz^m- zj^dYV^m4DVbHn%tRM@~+cKjs2GUjDUmKP3V&(1GDlyx^ftI2_^r9Yw~Zr|VFPV9CK zgy}z*k}9_e@W{Hu*mr#Tb%3FxHx*@MsnwM~0^7uz<-C0HSMR^~<`UrNfjw1x9@WTV zYCc>1VM{0@EbL%+_YFc>M5IYmGk&@rZ8?-Zy$Et0-M)PVA0N@jRcA}r%iPp1jn0po zABAoKkFZvoRLL4wyyFw{?o4K*@^a3S`n;v&Sq|hR`$WN}CW%{Q|7QXaqtZi$ni^-b zYoc3R0@DLayYqM;9-Vr6fHLYJ zW&*UoB8h^%!RyqV<>iOBZ!cd2rnsp>+mt4RLLeJOscbO!$Q@n8#iaI4 zm6)XO$;$@I2WeM%P7pWQN)7L*PF=KTgTOB4JwgOak4%=kAWOexEG)2RW@Q}!2Ntl% zfzYH52*9W52>A3VD?3{S`qud%7?iU9!qAQ_U&tXKrk_d1?!|J602x2tz%L4X>Dxc> zFc6HNuGilK{C<+_)*07qez1Rd2)p4Xcf!NWyoZ#Zy~|}e)wSeD4A8dM4(v;6>JdBz zmLW%z$b|`v*Y69C;8&f<=e5xqYw+k!_0_PbZ&4|-oZUtnk&$I?CUUr8`8-ZMP|IgE zZ@1w>aJ#AFSVH1@@(bnoc>O0R{Or@Q{6w3tf$#jQi70OLq|a8A{p5YnKGD9PZp8wa zTG~zA8xx|C^y5BENtN}4XIr`GjQ4q?zVFGJ#xSX5)N)TUk7esP8SISTcWOxA_s~I3 z4vMGr&tePygUV)ucWY=+X~d(EcG}BrYY;gEpH*L3qGFEI>j+AnG2&V|CsW++ zK*tcfo>cC}r@vnNJF7pgU8|#@vlDGI?oz7%FW6I@(d-{R8N2!SmV6ib^8Xm7^fP*v z$3OWf8rJI`{58x=b1K&eN}B!8_J{E4yLx)S8UW)~YE=E__mzZ1`&?WVUGjH=-rQ_E z=w1_F%dh^28m@DF`@dLU|KD-Ouh1{J&y01<4UPo$J;{K&w+d z&N3A{JA={62|PA?BeAnSCnFt#uC}Tr1AmXUFa6Yi*d-1-8hHP{!Po4tyl}{Dnrrn8 zdPXoc1!iyiqj{&9f&MB96)gqD*-0!N3;gu-w5>I1vc{vx1`7hK0+tp$w0Dn>L1YDN zg(L_>bIj)Nsmgt?#r$T(3@|@>y1KlPMR!p9GUCP@+P}P_s?xV^E(HCAkL>^#2k>9z zBh`ML^8`J6RfLo`8H)3tq>T@Tj9phZ*i}K zf{-=yEfT<8<=vZ4%w^WIHdUL*xsriLr;q7?YHL*|^El01JmL5t@#jwo=pmoQ)IrOU zh<>Bt)?liykL{#1fjl0m&oTB+x369cs(~{yGIA#sWBzk>nT3FA^ zwz5}3W>nL}%8PjDN(V>1=KLm6H>Resj>70P3r-Nkxkwq2QKkTyZr8s$GQ zKfF>)^vck&4`3h;W%A*NIgb1UgZ~IN1Gp#PJE39L+&1f>MjbMY>A>Li1fUHXi*X%o z<|*KPoK$VRYt-`WI^XYqt@?MTtEX1v!0oj<^ffh9!1v%Qd-BHTbAoF(h z)Yg;;IeFOGGJ^davqMXt@XU7|u;Q>gNXfN1-+PT%+2xq(w2i9uW2@#Bl zB+`9rsTvY||HrpfU!fs5+;98LPOVta)hx$$Xcik31http=JuQ*-DCx<`=`BT!Yc>1H+Ssh$ zG`H7iGtgD4=ZQWh2#{Lp99-(E5S{)kD6o-hWWb2_0) z*x7>5c3pK%jr(Y|ek+rXLh~u+1fGoR1@=ZgC{PM!naEp}tZdd-zt&+$i~e-6;>cGM zdyDjNbp`{8oe}UoTLli^$yzJKPp0ABn7 ztk=$(n-u~9yd*d7I&t#xb+ojgR?Aw%7Xil#&?S2Hcef@F{cc?F>Zo}v_us-^N1Fwk zua&oTq(^{pr{YS1U()A{vx1Z08b#*F`V3~bH#1Y5Ug}Md)l_btTn?hbZEP`k$n$X1 zX?6EEfN3jsCY*AR3w^P6DRMcu%}|oTK_!U3zBl#|@Da}dE8?zTwFrlI57?i6I42il z@s={9hh618AYlcC5il2l0oEIjsgmdqqvhF7t`_z6oK$9J?pzx4193nPqNWGw(_XH9 zshA;P>e|efnQTC1fhY8NESoUY7O^@%KLK2uensc9x7+qZ^@9ZYjFy?Ykdn7@CIWlA z;a*^O-QB5CW?oTU1(CPRMR9rokM$ZylDuz`qGe_~Y*~_CM_cGUv_~n9K|1D1)29?r z!RyzhFmiY&6NE~B3_W%2X$5vE!8|F!2eFKS=+q(yq$y1Yh_Cj1+*5`yhjA3N87AK6 zSc}@fckW0<3Zk+-g<;vU2@f7HvEWnD3pgJ1f5`}p?!axH)N7CFX>F^lapDlN3B z>*G>wh*yw(KEUx(kC}lPuaPW`(Yc)E?mxfXwi@?!y8h5G3^?k9`1#A!BkRFDjW=qu zi`{_QmK?jP++lw>P8<72L6YJ~r9%Y^p^^y*mjlT}N=l47vkB!4;Ap2nfsh=V+}~4? z%Tx@z$KyS|3RsQX)72RB;dxQ)>0tn_QLU{9Megl&*2;k>ArC$2a&qj|Q|BjILnC&~ zDJI4Z%g!3DyaFmFX0J$jJnrTs)qJ%P7N2@nY5XO%#IL#Sxc{>PeVzR`f2TrVriX-v z+8o)jd?;g$gxo5;4T!9iBF@nRt0NU1x@LW??H&5Lnhk@ldWV;xcZwFF3Sk`dpweJ> z39P6xRZl}hVMrY(3UVFMzN%_>I7_zqBl86n4>v^a#m=ke3gX`{2faIB@lSs%cEf9j z`1b8JLKgbQjCaHRUeYgQFR%IV)gMJd8m->kH|F{Sd4xKisyA^p^>yk4JKgNzpDW_k z7CQC*NRw^{%+1zorEyHHP{;MOhnbE}zeAljhf3M~m_M;s?c0mCpdb|5FaL^quiLU2 zJcUia*dJ*iFH6No&21l7@5M}7rXMg|>41uPGPyZbCCnVl`mQVH&`F5CQLpg^DLb_hCh(86#tBDtL`go*aJLj$~wFng}(qK{&_Zkb`wD>j*#9j8k1(Tie(YogN1) z@yo<<{hIpNeB~TH@na9K`xeOTs*v5e8dyA#aqFqJpmALn{1K zN7laW@a7aHfq>Yaq47xm2m?dQ7WKqfj?9`;mQ#Z^r~?76H23LsGNohz*Q%LZTSmr* zpws7*RdJvTZsxO{hGovc4QyH=@UY4CNu7Z?lI=*?e)D)B^bW&Vk^Tr+c%c)HXRQOD zKTCjhdA6P?f7dN{$$Vm8U%+LP^AN)4cj8hO7-$A-!eiH~+eJ1^pzZi<^=8k1=!wjT zIIZ+{*<1%aC3d+KbVtanR4m)Md+Kj@*d#s$Y>|E`^0V<=${L&XJa3uy!WFAl$b~K! znf083NS3Vlb((Rekp1S&yzUrwvM+kVw4w4r`qjQJ5vUUF9IUcY3b6mpJG|vFQQXa&6A>W|x!uJt!5ugK|wXcYP5Q-_iDC3>ZL z*Xd8+WMj^oxOtwaif`vTxS>po)Qa>{KHo@9N~*NOrA+c{OwAsC)8g6KoNNS!#SFaX zY()Z=yISDmbrc!iD1t<=C$ZmlTKzi#|vdyxu z$@$LC=^P&ytOir;1@uV~-|9+VVxw;hZbOYXu?pF!3*9+(>K-NLw;dE|#Jm>&v@_Y* zf*s|zPM&lDl-<4gj-7EU<6y~P#R2t~FR7|6Cm!DCFxWa(eWG1iW|uA<%NEV9|81yI z_rr$*>+zb0LJMbE-FHBIcA%>J1CQlYl?CdQa@O|;*`Mb>)7(J};o(EZXMR!f@x>Hj z*#d_z?!s|R49BN2@qA{TgZkwB#qnLsBYAeJ`L~4(ho3{#dx~W@&|qoux||YWj&`2J zTvTuZ*Q5KF@jkGLi-TuH-*&^0@UWAIq&u&VXQ_5WH8nL0Y;`779HXCXjO7{(b3sEP(GF7T$>c@!D?Mn@hLMYNm22_ltZg2)=ik?X0-7 z-~Y3*?VsA{Kkw{c|J;ia)^#ZQ%O8kM{QHpXbJf4y+G#-I|M}MnWPhK6%?Tto> zJ)Q?9BMD^nu6AzTS&zCJ?+Up2m5%l4BK-8q6~x;kQtaWvRhzTfIa!U*ObiXk|6JVf z1XaEfDm8ivk?YiUEu=0(o@|Jg;^snQ>DhJb-s1AjB42Ne5e0|V(^A|p#%0=0pTcn1 z?tsuQ^oCWYWR8u0+KBdnb?4e>nTN`;Y$VuIOcY>o+0B*#=KQTA*VWBqUS9NMB+67D z98K7heCId!{v}2}Nyrt1P?U4z$t{cidPqmzIcw(SGdyB~^SrMePso8=l;7T7e~fLK zW_Fth@ii(c!K7?_*3;b`C}__#tE0I&7I4_7+gIO{XI;u*43wX{xZKhZuoqop)iREb zQ4@wxSa^8&6YWv>o{f}LNYEB8RPi8@wh2Tt=*Uy*xcl5+6Qzumn|aFIHhbYKCVr4*k6c|80ZG z)4pOX{QM`o^B;gh!dZ0s17@Jy-Fk0aiwvm+#bj%g3BUL8J5;MghQs2nLj?@Ce0EYH zo50N%FSF7DH%|Q4X5F*}IWfCVElq+M(KltL*mAV31n&r(MT@+dRxd$+8xr0iH1XXc#eGP(}XF`!67#NTH`7$ zBG_L-y#{$Z{~iPaA@jITj|c>s*0~`fq-otfIV#HWv?s6m@kI$ra8aePZvUlzzWWjV zUnbiBCknCuHwEx1J~Cn8Zo3qyR#5dh6gp`gkSZye{oi%> zzmOXOPGGQ)t&fmC1h%tH4<0_O^FWPuc6O?RYL>ON0iU=D5iq!Q-(gH+Wo6|HHUVMb zqW`e305zC_Zr&AfEPaLI74{N|Nr_qhf5>|es3y~PZS)%*WvmRMpdv70qlhR7NC_F0 zq97n$YLwo4FNtLoq>6w@mo6Yg2oPzBO7EQj2}Ek>p(Y_A$^W3vUf=oGx7YsubI#st zoplgrDRGkbect=I%XMG(^^i!|C2B6HPo6xv2@wd~+?>}d^}v~9l(`BXK;Bz+z9^_} z8vLMEqP7C{yIv;zMmO@`Se2gO&nZ=yKN4QQF5AR4ZY@6lR8u1e@%1NT%!OX3r&msq zv67Nf%G01HjJ?9xo)ug;LdRR!XLnJni~@z_i?xiYs|WpDqHb)rx^x#>_x;zdc7pf| zI#q$L526qA}6-G7y0{a+u`U(UZgBO4zNSn%{f>i3Giembz++IG3YYxIO480=BD zt2lK?y6E-Y|N4!7B|Wz6D6%54F7P5bF@1FMD9Qz51Mw;avO-=EY3gKJ-#--RxzXLV4<*lb1my(j^t0ztPer)y~ z*?;B5{(n#_{I>;^7kHZHe4hZ7VBQYIX{4pMHk0B2i?@rou=N7e`ST=_n@q|%p)Ocd zwI#duCi6awC`rNbMA$SF5hpwce`b`Is?(n8<7JjpuDix2B;@wb12~DvjDZ0_atd!E z?L_sTuGU?i*h?ITJ6k&LX=xpcjg0jEyU1f}?z?hloBk%?lTpU@ zA^2~2Y`$S}wUufVvC4@7&cav**F^{Ab%wl8@OC(?J$^07cV`-aHF&=r5h2zuPmp!j zE=Wq=Qa)Z2Hzsp$TpTy}T5_vD*M)W?>L{yMC4#u*2@oyda4*J*I0HWRqM=8?k+KLC4bJY{NrcC2{&kH5lZcJv7V72~duZd&=07F}mHN65+K*C}? z(owCQ-U@a~=5Yw_0Cja@d37q1&OH4ULWAEu%hSf@G;bZhTU&d>S8=NuH9b zs`@|pU`w$(X%Ix7TgER5qWjcT%(pf+Y5;;#={zDV1b))oWKkm!BrYv3opUq$8Am-q zBf+un6BrB)RcXMt*Er!gjF8*sL`1HEd0g<8%QCcdTi46h|Av@wTUjU z${!~G`0Km>&%q)8Z7%MAGCZ`s8+}b65ELPG-ty+Qwzj&uS%Z!SE}%C!{M?b^a~IA)S}y?vFyWm?4`43;jFKMjzb@&$b#>>vVQ!d`&sYxUlr<$(574C zC^!cPhr}x?h9B-5r>XqtbG}p7nLniqq{<5BMWWH*_4IU$kvx$d&0zU73%uVR$A7E5 z_8t^0&@1=@h)Iy9W}Fbk!r_UDM!~^ml@7t}G#*cpCr^IiiKu$@ZztGI7BN1p!C;+K zlv9zWXx0l&Cs2#F(cT<6D2mu#Z*=ZIuJl?f-)qoUc7fl(hBs!u1%|{1Z<_cJG`;UuMKlHBz*tXKm8X7-#;f`KjHV{T~f^N zToXHYb#=||vYnp(Fq58>f5*&!0!G#ALX$}vNF3i0Rh4|;!#nPwI&DvI)oHn1Pf~UU zoRX;jC!} zOqHvVB`+o>CM8whxTdV!@bK!%!>TH!5??P{#u4y3${yf&pX`~fMEA~n zU(B9wx_N117HXe`TZ~e*@{rD&_I%J`b#>PF!S&Oc`|HLpT7vVic)TdNJ2e};jE9%) z)#{%6UatJ|Uh6a8wTMUO)xU6_l9dhp0#;bFtDoTA(o$9Gc`8#SceRG!kE$DlOUY#KsvU(e!ggq*seOY2>x?upQubnvUbhZA>E)d_ zTWqOTo?`!Q9rO1&#{sJB0EUXO%^dso|Ei*#&UPI#vg=OkUEGS|lMQn0K+QW8WH%k< z;d=JvRf0{$$cMl>OnV5YA_0ZYPb9tMZpJ39IdoKGg39U7Rzod-tH zWm!s4tXC79$0N!AP=f`-*J-O^URSh96BBZl!*78IN=oN!R0>YqL{U~utlj$h*3z0i zwmE}P9x#>&LrgxnyPKArhIpER94_v4+#7MzvcTnoq(?*LcQ-^N>R2;If=F|$y7FdV zU6{3vjYzm|zArQLw(1)Rqcz8Y84y<$JvZNl`3D8XoRU_$p7Y34y$y*KH?DD2(K$Zm z*)caYC1p80?CYWcr>)@;tct4DQ~cZnLc<}FM0>Tz0?LkDLRIpwpE@%EuU$WWvCE-Cs+N;xlpK&QB;kU6_Q3kICsDRNVK z85!w*6pVYN3@tOZ_~)h;gLY`WZnkicCW(tiH=N;&0B(aXa+@L#pzzFRYG~&Xd9n6t z+s^O{*vsYY8dulQ#!3Fjear8+E3K{_RrT2;&y&x(Q!WN($C_v72=lCo+s(tIyt(7D zarhkGCeSJ-T>Hz*`2#`Ko=e2uY4#I-d$vfhRT~*bY!e;itcu6&ahQ(ZmGOiK9v0YbBjt5R<14*Epw;7{Q9lQL6 z*H;Sr=c@_0UZuv!0aSSI~kd{ z7F)llA1l6(p&mTVe^au5(gy|`GMK7dl#oN>qBir*gm&z)yBV#o%6gf^9BMc zg#+5!$>@iakFiWY@^;Yr1~TjpDo^}{qMT)}p4vQ>7H3do$Q_%fX##c)l_6Ls4NMZ4 z&P08ad>+^)fbd+6fA1f;kxqsy3)f_mpM;zhWQu$hFeftul7=<88e39hn7@@%?xZT#cBia|xsL>HZR&h<8@_yCqE!n)tkihp^ z`3TR?_p1u{0gn9Qr~vr*(6GZx(DGZ)4|Zz`$j(1s1NroFAPlW&IM|EES1b?b`7j)i zbvL#f*Qf-&A~kC0GWYxbXrXn2l!O4p*M7L=7Zip)TX3!WR~iSM!ErBxKC~b$cBX$C zzvy|!IQr--m+Y5!fGSXYLEI8IC*KG*>_6KRqhpFDdzpLdDP*tf%)&v$agEQxR2k6S zy`;49RRYVp?${9r;K;Y@lTH*iYyP*B$MxY$a|ejs+rAxox4|w2F60Z`;hE#PYt8kO zoj|C-LiXFsvn&>?TRSjtq5Lk8Fj?-wpr!*JTps`OpeH)nO@U|Xq5h?J=B1I!HGB9a zJ)NVE@Zk=h9>uY`i~3=Aw6rk(*ZKl}BMm>Ois}*4?HTIuKuh@&?gw>zsTUyfR+6R* zrX~mCN3@dkoo;$Gdawab8?AcgTHr%7!WL-kOoKgu`mqN@g~GE4#EKd<2Tqbo5lYYJ zE^jeRq8vtiLavn!nV!3O;K15BHANftqXTl1)e9eKJ6?K15`S?DO0R-$y5Q#YYN0_< z#EYX5+cH`EyL2`>?fppU+2i<3FRCkq2*_1->3oZ`wx<;WgDW35!lM^VF690(Gi7Sq z*hZwTjHM+fms!q~tl>z?^|HCZ9>!X6ow(Z48E^KY)V12*<*P8Wig1-i@;rdhPN;=-4;G<6g_jSz%ds4BzC2T{)qp zp=tclUF+7Z9nc$7@MD`7JNj^qU=id^94tB}qP_BUV47=vUPT1L%INf?-L23>Uw04aex9ddcF489hpObhi3d|l+> z3X4UHr8qF{P!9ZDiFtL=8;>tvKCxH5>ATEm0$7V*+!c z7vu0xRiMfiVPHZZhV^iXUY=W=!spyQoaJ#9WoH#Xqo>n-VI!2o+cK8XVyWb#>J_Tq zchx#&v!^9Z_U_pO@Pty?xuwchSe>zL_@xZBk6J2Nb+w zlggLT(emzBFB5k&rMcIU0e<=l*fLg(5`h{ji1i818r2%SV1E6RXM$BTXBsCo5wJ=E z+MC)Ep3V?Ck|!aO)zcsCW2zoaje_X}u(47hLDjmsZCRQ1mYAsbPrN`#ZR3YWj{`wz~H<5bzS~s+< zDomQ83T-SpVAoh;`T8F^6ERa@AZjV2rY7;UjCDtT1{PLdAoMAqo!)6W6mh5WRQR2d zG8DJ(lXkqPTq~?2kuzoXG4T3zQ zZY4p?s6bz2xO8-|(9o?vul_GPwP-QpEwagvxS-roA&-tk)bQYR0CfyLV38C|nr zGmv=z4HqZb6+1H72VP9Yg3qyVoaYFP!Dekr_{2M zO!XV)9=F|84`|LPd8~gT3`7IMQ}jvc&#XX3bg_`-_0xdnlXBewvl9dJGBqG!_|2-q z>w+R$UdE}lClrA!|LN1VqW);0=Lu#YDzFqP=WhoKe;4qO0S)cIC22;kwr>DczSZVO z4m3M6Q`|ofrqoP|4Ab7f7xRLr+OYj*vtC)9v&BnI%!-EJ?g zH-xl&u1>}I?Q&k}0E~ zaOM{=qmt^NZY{nFE{50k#Ubwd{E7pSYNdydJUjoDlf z4=-~aD>QI=qp=d&Xes#5*^v5Ll(Goz>^XFtYz;6u04vI`<8Mw5sCYSjIHUG{qo2>L z=v{FV{%&-baCl$7A6DAQ@chM#VS3*)p!|J}KFuKt*}XLPZY3!U^Oox)=m(Q?)iPGm z{06ROSghwDSx3i+pS!4X*Xu*P{n_=L)T*K;2tch?YRIe*2DJstdA%{n8c2`pC{tGO z%s+7}hj^F|iXAJ$6GR0S;QH6SA9SF(q}@T#Qmv}**4dIzV|IC`biT1^J+33F|K6Lv z*?LU!n0W~(8P2rrOAx%aQ_!u%{$_YlK;B;;(7CKi8tL+FBXf!~0kOS>)~ zs{m8m=Pz7HSM36ee(w6M5P2@I{Mph^wqlVy4pIR z&c%Ns!~o><%(+-?Fq^0#CnpypSm`hZA85({CC&U3~L zNOhY7{5XkRxZo|%$=N*+f1H5_XlN0jrOjk}Dujonq~KB977wcE)ZyXb;7eUYi#drPV{r)Gll z>wu1eqvPu-7j?&QG+O(Ow8l)V@NMmXy3*gCnMw^md1QfJ<6m*)3Su?1Q*f1%tB{2Lo{+#0^xbrffZ-?6uk`_?w7#M*>3 zOP|i7YgN25-~8IxvW!Q=SI6ySQp{=uq9K_L5FI@EWbi+h_dfA9GrMX%m{#ERp z=x(~LAebSEtleoUBPO0vJpN|tS5RcaLvxr2l0@o8N5eG)nLugU^gFWuw)>1|+RCyd zV&V*A-*R{s3fF!@rFY&_iw?+{GA#)Se_$Zc)=J6GH_|ba&oOBtB;NpFv^KOG>O-HNm%4=A zp-%xer42(v_)5ovjdb~`^kmu!hg(xKDOhGIRYy4wOX|Eao440SbM6KU_QO>5UuD5vmv5KJPG9seN{j88PJNu;?eAF5-bH&5^$*v)Vt5?22YFRIquzyq;Br8pAh=%rOuwU*fmb2%O;nTTwU|J zF*G2tc8G)XIS_Rl5P(U6gxMD)#_w-^p5%Y&yHDP_MYHo!MxNRIZLk2$O6LMAr{QPQ zLl5Mld$QF1tr89nB+HV0m6f@2yRDc*ZVz^GM%vwIPAy&3ZcP}%)w_5kMyZdQpFtwh z?kX`JCGhoLIOVnY9wcFNu~VQ>s|cGr63Ep!jvgcw@L(d8hKrja)PXZ{wmsZ?1uRgu zjpYSy_vobHi@ z!P(3YDv4LjKlwr~o;`b0efW-dCTQ!5npba@i@1SIY7BnOB07Ce_Pu(7qmU=4^g&$* z=Hnz_RpsuzF~9tB^Msh;N>3&#G?c`f0hhI-O#Z?Qt#t04?ZiQUk3Bs|UcoDbiVbZB znvU`TydCJ)Z|6xs?h7V>1 zZ5k5yn3L@>T7*wUSNK3zZMWLbsK;F`_bAZK0pVnL`PxqaE-U9Sw zMzmin3={xh_d-NtmWjeB&Te`&AM{@UDxOAgE$OPk&B&B_^1TEj2tc^E(v3S!%dV@V zV{M6GaF7^QRqQ^lAS}(N^E|RDYRFd8R9+IaU2^Sx3%B=o__=wl=~^4UY2>=EycFuL z_W2O+xy6AJr;N}2{V3hsZyJdb??=KW!|Nv-H4;AzT~67`fO?C|s=l$^Z-rTYQ2R{h z`Qt`~W4Vt*BhRGND`{qoYXe@c%$1dDW^s1J>~|X#YP0uS1VP(XO&R1c70$gBoDEa~ zK4ahJ{G(VSUei9*&UyY*hY$}wnB*phxqvdj z*2{MK`6`gNmUSCa|EEaaq`*8=VRpYt1=`7fgI0PL)RbjD&syzkPy48-_ucU>ey#gT z^5kI&E%=t>Kmw6X1CyG~;G5-VojUJb{YKn`!>B|^$Ys>qpH(FSvdXo!wdKK$YbZG> z`Gtkoxe=<-0iItQdbuw~vu1FO49YT`%#>BmQBNoY%;u_qOk?9A0Zs_rpZElz2G^a2 z$^fevOx1~nduN`FYK}}^UAsii%gql6V#HrDr_VZ^5i5|L%hw8+0#24jqYb@>8-@C& zb)`bYh1_bTeU|!fFV7zpILO#0ZEGNyca;}#Zuilyd$|sjn9Xb%5sP8SC*OsKI-PKZ zK|r6QynGWhb$9W@s(0&|nVKtr$DLfEvL0$O(E8SNw|>)1rs+nV_Deh@3iV!{t7G`u zSm)FzS^);76B2_05XmKNekz5sw%#@&*#cU^fG=f*z2*5Q`|R!gQLDSz>SY|N*~+df zwavvKjX?o~cshh-4c^kIMBirh^CJoe=KWB#P#==~dH>dJENwkoH&-3p@TaO7_hRGm zx-00|1pFQS;{moi(?i9h3F3N`Sc?z)@5ESKR^m5EQ~# zUvbsW*tysBmchYGATa@xY7(YHNZ(?4NHx?MQT^n{Mu>c-llHjr#UDg}e+0SA@@L~;t3_09WK&Ix^0@LAH$ zyrrV8jpV4=YPoJ_QNyF>8NG{fTSQfZ^sGNKE+z~?z3mMYGjd-M1w5~@PId# z{a}rk8fIz=!?OSqcn8f89GE|nB8$w}V&W*`*;)#88m%J*HLx8A;^j`Q^^>rw+?mO}pKc07+p#|8roWK31 z7_d%DBnErVw9Pmla_p~WzPl8fC_d!}Ch@wlw4U*eK?mj5jgN1q9(EMt0s#8Y&%Af% zPIlzx=8PDev4zfXwRq!2k~r|J^iO_i@=s{OPBi96nKpY8;#r$Dj7i#7iPmWSVdM=L zYWTr3Mq=MG2WS%k@#bgp?=6(S`?T_jSZz=PkAZG){>3GyRDKpTYj$sE7lH`=_N@@9 z8D!V83a6kKmUitLZ0yh@{6L#p0rY*q%vCzXuBkPy872PyWK3j<{N)!ft_vvI`@7E+ zwu;;}t#sb;82^yMR-~o{{jARd#rOv&v=r3_=Qlz5wDTv9<3yTkf1VGqJ1KS<7MJ^} zTgS~5O!GVs`;Dai`t_u``rmUBqj6R@3v&o%e-luC`xjlr|AFy}zB@P7b>dYv5F4wj zmsd`Rz<1jk#{F+>+G!Q`z15#^xwNf??cvqT>Q- zK!-z7dNyhQ7GG0yGqZFOZPT7O3PsG!;7qTx5iT~vVJuMkqL`GG8b^z|KmapUT@~xe zW}HKiM|rrp&EF;+w{XR00^+^eVZOz;OF*Z9_|e0qa+hH=TCorUT0ww3y@>Ps2DsF@ z4b#<-i*XL1nxs}@yB#~hj4K0;!nC!tyfVd~7CLsi&%d$F1`YI;4T_AAzPP;3MORj# zSAI!g-Ne8=HyYygy=}`vfky%Ee7=AD04G$|a`W^0jA-r78 zR3eZeZ9t|Y1tD;(Z|?J#kmqKhp#p)ljw-!I(@(8l3cs>Iw<6#W{G&E#FpckQ)R0R8 zKru5gFo3Oe*>=M7FhVb!#kugwTYH0q_7e8S`0Io%0!kwKqzt7U35^98y}vHguyd4* zVbfhC>P!X~(pKsunx76tx?w*pk9==FuL>F+-dCUvW!d)UZJDnGy>m9k0$ePZ(irOD zQ94*S^!`C+UjwNb5FMJDEHV_>4327FG_NHPnY&_+d7Ga8rdbh;Ix%alGnqd1FEn2q zIc1(1ygP6xWfu}K*>H`^VXV*`wE8~W$J|o>UY98O?u69@734yT-%3$y#$zZc%=${%zW8=;&9dR01)6b|!Ajy}8!1_O)Ci(ES@=8$&5zLO25wdnfHdX9Dc(J0O{ z2f1TGN~qZD)+5E;9L$`dc2%_{h_N^Ix(5r5FUenYT&W!arJ^k?t}j=EV_yQ&qPPh( z;6OEq2ZjgeTmUI@XzJ)T7(QO*a)hf2eVZgpOb(o|%n1wLnXiF`C^7KHFdJLj@wTD& z#wcHFYvsVeqrK?gTi>y~5_XD$^-(-KRaMteh74abI&i84MA%IXeELNiIG z_2E^}`oGK*5wZs*hti!96`BN!P%|@wXg@ZPiE3_a>VnbgpFDdsGHWZDR zq>C|o4&?Qi0G%5{`57%5y1+tame1A;%AVHT^*>`DkVpBIdU7}Rc5A&=wA_rN5Ca1O zI8ScAZL|d8Ys*iH6tX@N)Ev#<>ZiB4;QUsy>-cp3^fk=^AG|5d_6q)Ct5xz9s!s}i zVH$*90zPx22w5u~JpGtZ`7G?$Uw@SW?E%KKI%gSt;b1%a!5Y3(>hKYV>!7SBX*Wgl zEwlj2VV-sf1G#LPk7en0Ci_@~%yjbRE2lw%Oq3mQCDgAP-ETXS1nbx~jo}FyhzW=6 z-pv_1B9lq2d=^^fw(9(J!MkW^K0vnnv0`59ooG4iTK#*gqJ!nqy1IIi`=2odAY82- z9iTCJ^U2H=v&h=qVy@BQ?P|HAPMP3=$6&~#cB_d)5J4Z$&p@oU)Q6}Z=2O_tJs{_r z1Qb_9!~3eNa3cK|M@T(a%h$w^S{V1UUjszseC6u2*nNlkVae-Dt$LT}lv6zgR=DR8 z@Qxsy#P}nI~W$zAu^QeK}Y7JF7%Pp*DsqkkqK2&;8cMa z>Zy0a>JJ~@Co1hd47%ZSKJ<*l%LL3+cL7ps98~t@M&qI|jAdojV1YTgW27Igv9zXDuYd3T=QOS~G)omaVVaE$;Fo%Fhz@!+7{;iMy= z5ja&xwMhYArXcCjO1+VcpIjIyv6HLrSanqyjecTjQ)`bF5%D3i*~+z%KW;4A8s z^tdew=xtX$FFq@D_Q+}ZLrBnYP64p!OU1QZG|$YyZme z*H($BQD-pKdF#14$o$r{H^9NjyF2dNhkqE|8B>>D;K|>mNitQ`9n~Ej)srM`ET>Aa z+klYJtqrKFp4d`Fx!>klHuPf5djiC7m%d9&OMYy;yK+%`xaIG42$?Y z)6UBe1GD!p!@fK`spNeRkO9G#1yeQWh2+Pe2{(dH6}?+8RvnwP#+5YQuuxM|Nf4j1 zYb~4p#IHO}oxu*n%xX_o<@99*;r+(T1L`&i3xh813!4X;2MuI5sE1ZJHrNimo($7E zEp$M;D#M8cGcGn{90H_^_k@|VM8^SfE#Hly-(x|qU&&#zJz`d(y`|-?0>bwhJ@e&( z1D=OW>&NQ!0g{%l#bjqr&GMackx8k0Z;g7X)q6MHv?)n0e|N<+G&Dk(okqZfui6gK zz~ky*J!;zCu-k~{++DiQ2(@1h>N>2QLO+O8kLYd*+SBYKi&4UWEVk666p(k6Rb%+g zs>{_J9owFb1&#_f=v79-mPdWiWLm#ch^p-ii$rE&Nl%X|EQDFW+}c{ii4s3GYbv+J zi}3OC;`0m`fm^qlBKckee(!Pp5|@;t=+{D=Iye`!Zd`bEdiQgqE~6lW5BdR%uoO@H zQ83_IOT{cJu*#s)B2rSf{Wg4ma|qsGMs}4nTGV)Mtf&zXQwu()0dNoKjuJ1ArQH0isZP+Es8yPYFQ4`A2;Y9&xC(BFT`9 z!CnO%o;10jHkNOD1|Jw79{J#)@oc=OQZp2&fPk~Nj&r4Dy^XvmC`g2daLiU378DdD zi0xl=BM2piqA?vE=wWNb?&Vy6FF0DJ!k67UT-0m@9@L{pL15WrQi_2iesTEp1Za{L z*)E3$QCJ&Ig1uh99dPjf_UF-kB5Ea5%`tPw0ffx}8_?jx{rM?Q>_LYfVdBSadEixp zBQz;?cV-}+ou;>yfimjm(qFCV0_h3QiWE0Cb8N5@38sY8M^4X}r+dA@zqzZaxwXM5 zY+mgxU=%(xJR@pwFrB&lRMeo*#>V)yo~~=@mG2C`&j{sTN?sjgGd#y*M6o^qpUb$q zvJFyi5Oi2`{eCJ9&NA5RHj}jc48hfgS8ttq!O6Xk5W~K~w|3f*iXbWA2BN$EpmP9_ zUolBZLVzLg76NjCEo%=l+7l(}HpZQ9bHoIDtd}3+6|z8Bfu7HL<+7>MUyd;mZg&{}{Brq_o&>Z-B`VdmyHDQ*BH z1&r`G4HYYT`y(dwl=)2)sQqnjI?<+6aoR*aDci4+NRqX!?FX~EotOl+Vyz+>I6nZk zDADGMP0hRw4Gp7BZP`yk#;me_OMiF#^ccy7640dr;HUt|Z}yd%3@!>q45;5iWS?^?y8@tzr#Y zgJzQGN*DQZ#}P^$=eT<-VSqGRJh5mx8=;NmzwrsJG5dph>H4EkK`_72!EDtYv$F=0 zA&@E5q{Z`N6G#_RR`q;k1^WYycB4?|`^JfXu+RU+&$E&5`!~9`3w;0aKUn8HYi(lw zWYtH2QFLl$1CeDSGF` z5?>H~|C?~z>$p4jUr(o=dg!^5-eoRFaEBuZg$oNwwtJ-XApKhb`1pL#O$^%3{=qSB4{lJek$cqPmvlhavd6+7{2vq}~5I;H^p(OU> z)qBRR%E92|n5n7CFj~6ojjO_v4>pZ|kcHn(e+>P(sNvy%{?r;%QTfRtf1D-sbEy8G zKmNC$Z1em2zy6%j7Zx>DF1L}EmNqmr(56`b_}HsH;3_93xQH7vH(Vp`=;>t(7h$n( zk{5qG|HlOdm6e!+0uT3x?$4%7ltqgQvwK&qJAPh+p5gV=>F$~WLH}{r|LSA+{5&B0 z_=zX~?p-|Eh}Z4U>wI5akhb*F*}}kJu-rk)xjlX9<@d{ejIL0@qOpsw>bs!Sr>CTB zRfHxu1n7({9BeUgg_8VbB9!02z<~Mr8MSWg0C9VWN@SMQlk3QC*s960Wgi_bIc7QP zjRcIo;3UB-kc#bwLs=7_igq?)IS?!;l+fgq7SJS@L8CPavK!R)hwiUj%f8sCqb9(p zKn63Q7>*; zX(xy726cq2K%}#rkl1xRk?GhJX-rD>u}}$UOfWLX)Y-1C#eh_tlo42CL?x0R`(YPX zmwk$B^YUg7LD%NVY^tA((iI`x&OCKu)!sb^jkW`IPT8+j!)j1C1&qfS)~!YMcUxdA z=d&8!!tdO^oo!>xspwB!JOn#pp_!|TN0ji5xQq)VGO_Il`i7t)eYig5MzLQ=w-^%R zJ<0*~#t~g*n~p!S{C>?3om`Y&$*(c<&mUXUz_2^L<;8_6Dk?6e`L_v{U@U8PDv3iw zlXAl&4dx#2l z;+KMMmPXJ+R6wg;EdQ5S=?}?xX|w6mM93^VB98!x9~#Q33#_EWKof+ zvZIqDvW7CGfu&9zfbM{cQi$FdT|{cp78qJL0){@w8JROpv489=EG%G_XM-@bZRD@o z-ON=ra`n`cItsy#dn4&vHOHA+``(n+=@$ihUV0j$3F_yMRoaNU zPGznm;5FnOrV2PSWM`Idg-$_OBtuE>&&4qDX`HTvqT$g{U%D#;jH$gD0l| zsU(B#zkz@=YlN~Yl*oibEdRkH=&@k31d9}Yn-gOB)j?vI{Rfxv+r>~vS4W=MiHWnh z1N%*-cMTg+v+-pw=Z)!bqM6sCCN+2=s~a~s$R^>iLEr*m8=;FaN(-N&po;$OrD|Ae zGSrL>khQ2VZ(m;ovxvCeUV$F>oFZb_bs6_EWNs@*D^O_dEaHsNI@lfx!fML1U1Q5w zEPKP$wU$xs-j8MqRGj~q9UhgB{~Et z5j?n|*z5t{F3Rxn(}qrMdO5eVz&n%&Z};I>KHXJjxeuP`wV&?i4Y{eTw1(sjy_Lyk zcCzo$CO9tNn2VCNXt(a;!|EFwZ}o1lw=!ZBKY@?mSI+L{dlk7Y&MeCPRn;d1jUqCy#r zjzqzbrA(sPTEzPLx(0?Z1>VV9o=M}5Ipf_^Q&?2^%qv=s4#}SACBgh{r_fl^Cn~6c zVN5!y$PhWVG)HfZf%oxS zRng)y6sF2iE7c4N+ixT$FenJK6{W#*@A%|W1!+8b>auzDd8)W0S1hVqp8AFl5NU=O zSGHGTOil3zyP?YioaP~&WY;=olb(`0T^q5}4wMyGwEV=#$fJmD4WhlXbF#ZDDVaxbg+)2XB(dJ%iA zIC&wts01T)qs)FS#gDc1hBG6?0*Dyf*-^3V=6pyucdWk)gJ5`hiEQ^Nd9c}0Q~)~Pm_VqQxx2k*2Aon0w(NUyx1SA_M(Kj zVUUvEz2CMox&Jmc}JH_PsgypVVm^HG`}%=$?c;GGt>Q-UG}9ExJ{|3OgE*l z*JBvu6S2?TYJF$ikj&3_^UVVWXE+sURPJc#{Kxv}z;9m|g+)$BmFC9$n9Gy{&_@7e zWN$<`XOHAxVcinehtDGrHTiaFVGWa|U{f1$Dou}RLzxYKCGx}qW&?GzA_Gq4(9=?4&KOw`zD0r45P_W5w#!m>Z_Dco5g;DH*HIcZ z^7-bgrH3T8k%A#B5gD5y&>IsHICB&*c2YWm4rxyRJwny3c3YlHM;$>`U_<=6YJo-i zPE|1}e%Lnl4a`nL_h~DzMk+a_rSp^8@RH)IjMG-Vb|v`H$5lFKq~jKD@!3L>|oAD1^%L`P!W->qZ?N9X+6s zFp8JgVtfl-`Lyxo%a;SL8YBiwf@In4h-@ZM#T-lg_^*fjdX!m_!nqT+R@S!XU|T9Z>< z-D0%d!Y2-aT5`*|=u#KPlTen@1RnRnI8CrSrN&g7T>VGXvDkOnj^n9gGF*3D9(JXU zl@Ia4Hn$^`wyVB{>9+Z#Ms+*e+qbx_T@lh&+@9msR!T-JRCfUj_=?%!tzCDNX>B9F zO>fP~F1>SAEBCdKWnzL$<#n9LuCMd5?OwJggZuX5I*>ddbJcBprL$8UxN*0MFVU2) zZw#osyu4i(K@HG70oTX9IX(?jxHQ;rQ3m`$ASX|@TJ~nYowe%=Oa(=1MwGH`Wd*&EH7k5U7@TFrBNMkQjRU^l3FUwWr)BrlaLU z7&0yryMph`?|Hh9qi%gc!?a9<0c?TagVwvXb%efhP*;G_HuE;id`}iPDDuigs za#lls;ZC19EljwukaY+eG?;)h(AVFuO&xK9akWw%U9v-{V_2}eIiNdT870j6>=+1e z@Y**5xQt6Jje|_pt{*#a(JdHTTmgwYG?1KP`r-u#x;_3!c=knaA1&Za4IbSlg#m1k1B0XTh*Vt-OL}fQ*%^qDHO^Y2R_U9>)Ivw+94Qoi6n6^_jOv@m>`4= zBV$Nib{RqRA-tO+X=x)JPJcNg_J#-UtfJDG9<;Kt*nVkzX(tp)Pj@lh&L`5lHDDpj zxeDZJaeum72F+X3XIT(gCmGjz20q-Iu|2?x*o@NvBBZl=v{uGaotyCSz<{hHIm*-X zcImV^Z1AKLY@1Sqtg8ii*lyO(CckjvZysri*xz+y`2!d*cfS$bWlXY>OsXMw<^}ED z%S2)*>!ICBM4vG=fe?EXl#8os3W>&0A!J4u8sWa^A`3b<>3%Ew+Kn!UtW@QzOoJr1 zmh_1mvmK?84xfDqc9_0_aRS2VBWrCyugjnH+>RGGHRuYK6d$MU$4~7<^Q>UmPx8S^ zx|Prxn|k}ehKW|3eCsgQk1H`fC#0>kH7p`{gBc2?Z8JFuxZd%A1&;3Evxdz~(gc8Na0ii5BZ|cvtLQ5jkqT zAnNksWVhKLLYh&XW9I$o0kf^kl0S5=KaROzZZE9fjyb*?zO~Iaw|9)x?Cfrb)T{8q zDI=tG_@(bh}B@O$z zav8m-A2>6}3-e#A+DRlczHUF{9G~H*PG&732_RK8>y$zU%>&3?kULCAACd-(GkF&-0nhXpD&gi?(~c z4=&STiNPRPU8V~%@S&G`r{E!K-QQ;;vf9`eJS z{t!{ie!>88Wp-?K8U960!VG0QDAgT3Bf0wspn@T*&+=2ZOJi6mVP-5mY#fBE-RFc1 znZfVgOE{?7rjFj=I-oSsb35j@bPQ&75R^umTvc;lyD`){GMmAqn$e%RxwWRE8@|d~ z)a;qkugssQQjg6fsV$*6saY1Tlv!cSo+k7BS*tJfH=W1$78wC<( z-V=64AIvCGZXqIZtzj)sI0Rm2$b8?E!v{oaE|*hx_I(k!+vwf=) zG>J{6t_?aF){Wizde;v;;nZtZLr6H$IIEo--^;bZS&?<)U71FJ0b(ZxjMGszwvU<|MwRz z=-EEBJDd}*8wYuA`L07G`?zC#pD^mU-IzLYEAujpM*B#0zgrZR4VAB--G&vsCa`$q>aVUv=VPA&gVN;C1DWuR<) z(XCjfU0|7AdHql9?xP01g<}~t?uJGuOA+0)7ke_W=W{E{E?YU|R@iGe7njS7JX3cN ze{;dmy+`+r%p1eeV;T{;7yKh~tqC_Z%DZ9)hm*d5KNy17at~^?^LLn!RX#;elWZ>+ zUv9TAEv4MdoS3$9k8owpPGi1;jf%6N?3ltIVPnYdCu68`w z6!HA0 z$P9%^#$-}ysaqsjj41ou?OIi0?Y9fv)@Rm2tb*4xSCg8k2_!!3YWB{~_4o|L^~s% z$q>zMaAkf)N&TBk4uKC_V0gE{p%kCR&J|R`^w;E=kP8=7Bg4W@o)fYxV>@r^pGVmG zzCuhXyCto5biy`>rEW zYJ_`q?eFCQ4ZgF2wE=o(1xtX4u5HY;wG_4nI-)rs?H@Hjtpr|DYsIrx=?fSmwxu}wh;#W~n( zt!3`G=C!_4^UJcBp^(LV$CDRyC2e?q;J zFH1>?ZwBp8js4haqy5_B>2lIIWpDo}W1O90E>3&vc>Tu3p#3U3LN@#VUIW&sX<0%4 z2UiG6qcb@VLfoW)NZ5~evoM_of1Gfa@oBRz+v~Q7zT>GO()c<4=FiPi>FA(~s^02w zl`b;v1U$LwgrUNG@P9Mv_Rf-H7 zL)-3=AA?)0+q=HnZ{dbLbyDV3v$f>wqdY_#dz(E?zyCmmKZ+cwkUZCtUhVVhwt-RM zI2;A$-FC+HIomG_-k5nojMtzDdWHTqm^;d&{o5)X2G>T zt+)_n?o&CxVmLTnsCv%Ue&BHQ+e|L0GcpDVx;iECuUTikW{zkHT_`BOYuE6$^~yg! zD`48ky}BV4C3c-p4jtWIl_RmI?TA!GK@y}$AK=HA;XIy%}p zX?S+~xxN1Ri7h9vhh6IFP5`jJ;8%&sueR2*yh0zNFCtaCjs{;f)zzz_vMLq-e~go@ zv}z!6$a`_JSae>~CT-hsGQ+7jPc}+!V5LZs-#+Z!@9Bprub!=u5dA#N?-NG;gj2~2 z+6L(_KY7yXe72P5Jc|6>9zNG=zc}RGnf29Mhfo04i=vv@e!dOls8XjS_L_DoqGa=c z{J5$^>!DD;S3P9dL&Aqf(k$tDiiX_(mvezu{|YSk0N9zfeQ#=^7Bi$hIa?s6uPJOF zCO7Ch!$2=k@q{-OV%ojr-y9bec(9WTLyFr z5{F&Po9RJUNq>ItBwESmeOdl65AJhSys@&?)g5W}TYiRtAZn@w|~WnSzFyE_NRL9hPj zd3SqlROv3-3bhxPQU^2TIP$nKKg0wH;R8#_rIw_mRUe`C8!KJoQ#J4R~aaiU4 zp)n}G*(f8h)axiiz)&EQl}bajxb)J@qlTvLO8Slv#kqr+^p*VJs}Rl5_DsXjGVB$JPZ(s_kT zJmuWE^GnNNu;1kevl)eIvZj8>1SEkq0Kk|3?nRAFm4@tMuJ0|`7t}Jyb3bp4x9n>u z$8xH}!sG`hg~Sl~P&5d7hMOJ!59LjDw5%0%nu+0s<=&H%1!e+J`s7Mswk4(M)y#)0m;JF2iF}-F+y5Rit!BWyxYxvyBmum6Nc;Z6 zo->Q19Me~{P|LeaUS_iEM}RI!*%Ro0#*T*9TcUyOJ1*-JL#N9N8426hAOEeMz6Q=X ztlqZQFtQ*(6_=<>edi}n>>#W5Opp|}&vgSH!Neemj$CuzwyX_>Eq-S?W?pKZJhJ0U^Mk|9K?Pla82GEea!NQ7 zR^3V5PWj)>VrmBQ+m1R$PEFNXUUenq+FAz8Uu#U z`tZMM^MQ<$7pWv*C?;o%#pX5TOCmlg3$y2`Q$(ik|8Qt z!Lf7;l8KV(6Lw@E#-U;S$D&e=nEGLn*-WASG@(|r-nf#v8g80E(TUAYUT7|J1>? z>x3u;T{7_gZtG~JBdH`vqqODLYoGAHYSliWqXFVlZbGZq3PKh0oO>lAihMh}C|DC? zeLIEAeKThg!JxS01=o5SM5^z+|HZ; z(f#Z6ma#ZvTmux%lET|t!=hpB+VyLG*2=^BTL+oPaqCc;qTcH}IAXYeiTK(GuDGVV zjbad*ERh-OLbAr89>3IY>uzbAA?Z=#1@%4-U{}bd^;xi4`Waqt9yMz-JSVG|$1xQv zccVR8`Y#ns3$=CfQfbh&>h=7XuVJPe88!U&!$OClEO2twWSOxOqKp1%1%5_EC^WzO z6Cg2Ao4RlMUyA&`-gnu{ZgtM6f75^SHS!;7nHH+4b8|&CHL7=uW>RZ;CM-xn&LFvmbaKKL>T^}6!+RPyZPGa!N1AVp>tFOgo?fb9E?@Y(5LoN%MSBLE_Y;+72`9(6{Z>OvSl+*b0~Y+JE@?h}0i`5a zjt4x`^A6Fi(}qEtx11F%Mt-vl5;fK7lj8|hD&||BiXKm4ckP?AiP+PggFtco^yd|~ zUXT4pGIJOdFb$3x8BW_4HYnwT5tya^yJv^C8L*VmB9?J$)0xu!!#uZmg;W`-b;_D& zR_VRvH*hL7{`udrlT)PtGROl?f>uUZQ;CsC`CmDVEem93$_3Q>>(HGA1w+7G@zxId z)ZM~Ck^dcfwv51J$&lbAV9NBhu1(WqBIvLI!3N6Y2T1ox|CKQ3XfmQpX*v61X6tOg z&fj-p;S5-yKCSC{2gi5wFT%Y>s_F10N_f>3M{8@Tmjl)_F4lG8F+B<*# zqzZwu42~sO^RM2S)nG{^%312@R>hn|CqKit#7bbI z9{>)pm_AAysgxq4kA(1%3rYlCx$1VRQy@}YNhM{YRB`ZdnoFq;wv#70RP0Kh`^JuY@iI0gkR00!5K^0UAIK7uQMnnaYG zGK;;T;DbAA)a*2U^XGP%e$Rb|X|!4^NV+cLWt%F=(Ft`mV=x1l9?St-!A3l-re%$EDWw>Amx6^*V^?axGR!Q29@seC>-h1Ns{(Qh_#z zG)sLrBp%j}owR0ImCu#B36dgCxQ?4}oNu1y9FEqwPHySbO=xu-hP*7&2QhSj*w9nwnl3FGKsh~$p!ugQyp^p#1i2m6s)ifdmb5OPFLH}R86#+b4Vlub4h24%7}j-6(SUo?1<0*V8ikbZ{lvG z*L|qj0v|VDUq)=yJEejZejcatEEhW7wk;EJ^A-d%{h?4~sC$m;7rRECyWQs9SsIU| z@AuDb{)FeHL^qb*DtQ;CBOBqp2>oXe9cuv@)@6$#YQm@hAts&;YA~}P;d80;qGkmJ zgo0n9Z0}h9W8*HwUM`P(#zRYvi_pz7G%6m`O z>AY7^4w&5i*xbjy>&P6VR9RY@{mwT2P|YlT{fBWKk=;kt;~qF8vkS$^k6G>~h5m_>P2S|M9*e24BlUioXN}ujPMxZr8Akj|bom-+ zC5-7-q-~?Cj0L7J1^$z|71TSQ>a?!YKUDIxJ(^m#KXf7B$iCzN2Ddx!25mJvM|UI0 zab{i{Wez6n5^^Mo>UlRB3D`3QLWv1|2Z-%pxBAyhY153#lzd+X~}s%)fGJx zmJ>teb0rg}cEvxtV)W_Kq`r2zLiO!&IU)jmIl8XM28xbVgusq>3z*f$|U9GXh$Iqv#?ce8k-%&5c=++xmi zO+9v9{|A;zQtRt9%$YoGZsVEpu2C)vk(*Y5!-o=Vk9;%N0-_JBLW1k(18k=1w9pnQ zTB_%q0hWZ`Bxt6T+9xL>J7^c9Wy@i_`El(#aA0Hf&8z?^mxHFZwxz9c>vXTL?d;+2wb2kKQNLAM= z&C;1O;P-BwZXW10`}*zH%I2%LPvkpg>{+whI%7FXv1)=YSoU44yJC{vTGT1+#aoB* zz~$pWp;R8THLDiKCX`=VC1fq2+@?iYfT=97nC%&AJAHocgTJk>Y=iA`#Og6@rQ8E; z4FsRv-34kzzuI0cNbvLX`wT5y_X0Uw`J#6k#mui8oZ7{-jnLFP`Iu*ELIP7IVWM`$ zIxxge#2WAeTvHVW?%hkX9gv}5eUPNPAVWdEu7=>6cMEjwS^!))*Tz1JB+fyUQ?5UHy z-ZQ(D+VhCXSQ0PHF*8>FeUb_yDIe-lvYHLHO1cveI`7@Mu_?3(l(V{iTs7oFHmu2= zpD9u&aa#p0A1)5eD7G2w3PPLSRdUR2KW8T=kY_R@13DTcj!#JbtX&02#7JHO)SUTJ zlNhEysrw|#tBFz9UZ;?HM=L1GU3{%+)qmCcXC{y@L4bY*Hf!)ddmt%t^7MwrbJw4Z zAcgM?D3h{sOwJm1=6`wtmJ&sPmLr{MM?II5@<`soNO+Mt zEN=j~f;|W!Z>iDzeVlKpt#{ah4bwF!mGLi3tHZ$xd=R zQLB8L_+wS{}j}lT;|ox=tK1y75vDG zU$J?A&H8!3Tz5#} zP4Is$M}0+ARH4;d9bN^kGh!Z^OslqjE8C$t=P;3N`JERs0xH5Gf5uT`e+6XEAg|6NE#w^`A8S8xl+&bTl7V)L zU>li9B+u-mNB1M(cbnUo9a{o#cX-m-QIJx{?JvgGAFVvgt5fEOK@5tYZj;k_7~Gk< zN5VyuF(;{Z)uloOf?JycfHYhEH63X0Oi}te;=|wuv|N$KiS4&o{l3hkdnyE|&@Qqj zaf%i2lJrw2dWOLBPKj_PkAj`Ax2+=c$5t;^{a6!tn8^^`O8m~bQr{^7Zya-CIgO)a zbl)pyN+Q*IcUrHxsO4ZVr)#9Zdu@2>rE_VH-A89u4xgVQy|Ri()znDbJD(n{U8FP| z;BCQU!S}6|s4Bj1d2f+IqY88+7SoJ(DopzKHeY9q0?3c?+y;`-oZ_p(DSJW;*W)us zDJXKkw0DAYMHRQ|A;NbMn?TGBhatkJR{f7o6qj6QWY(mJK~=ct4!0wm=7Rsi4sS({ z+xc9WU9BR6zLOTErBY5vKBlwog?20tbY$Ez@-XTVWFRd)KP}oCOQqo)z*_$}fZD;0 z{jy-i*?)7t1Q#{~jAm!5tkr2zS!4_=L@Y zJR%EcZ;i-~On`nNeN=M5)z;D<+z+%j#SEWmQa7I)c1$l=6i$0hhbtKAc=-+TTS1oj zF0=~*XMll>0k(4Cq`OS%;&6tysh69&o%<`@lGXJhEKn{+Dhi|)Rg8wd-E}-$zgWFs zO?~iHU2Obe0dZEBo|e)s0jL9XCh?=J{M6Dr$rvuG0aF>0&D4m?9^wAC->(waZ%!E ztuGNG4!J?8yYBtm)sf-rN&Qh0Uzyp~@{OLrD{aeNW9K1(`#j@-k2U6IbL!FB&ydzv zpLMHp{BJ-DHu4fEMnmRtCKs+#BU>;pEkL!)?@6}DAz%W;5zst-ly>)d_5sO-he{VLGN zoMn-x(93jiWCb~D9(WhWl=-hCjn1tTWe|swN=|A*mLor@b}InoD=L8(UmSPFU1wN? zyl!!u7GsL;)($u%x4Gz?u8y?le(CyNaCI}1EBmf8N@$~dZj9+7AKGR4hZ)Z-KHj~x zW;5D^XS1M3a`1<-wV2~1iWXYo8))Q?2E-jliRn5J2Ub%w!32a9%+58OYI)@XnY%65 z3a@g2caGRTjg>(znyZa9J**j&aQ5GEjsm>e@}Mg3S;=XobRoPqu^@OXe-y)=7t4Gq zyzx=-W5(P@M~jg==--`JtZNTXT^InuK5hIP2^EAC6WS4n6yCmnZ`(n0-*|7f!f_j@ zC3KSCGbdPOLp=gra6+0TG;9r*_<@Gw({X#*{I=$TTvkgwpX~m6e!M@A?z5<##uL5G84{W}*URRHOQEDf?!X*50Z>`OIfS0K$7k&$wQ`dM;T zV8>jZRW`r_h=fpvDmPWeV4eoU^*5Yp9?B>-et0Msso>|N0Et^6_SBc1>dDAYJ8)sw zg(f*Uq~`12FirX!@m5yfeakX`J`o$0l}fF7)~1gPitHNv9)9ob;CEZWP(pb`)>Bzs zD}PSMK6%9s?-fQs__Z7BUL@Ale%77R{9!UH;K|e-9`D-fMyF)_aw|RUFt8`f-@GsR^HHX3c8?3(|IELVV~Q($BDOCq1_Td(Q;Iw9Z2YK z#7S81oLOsWvr@^U!Z#KFjOd#=H)eMb8_yoC5f3cQxw2zCG=y*E6VOZWyvs zvQXS+Vc?J2P`3Z|=0|x}O#A{Mz7j%fHa@nn7y(f~l`0`T9}P!hJRGsVX}@;w2kiZL zsshF3av?u}#JHArI5`@no-30wq+M1+PFD6QT>LO(dfp{O1)OEzZpJ$UI7nMnT&NoGnoi@omfGzw}r3+q>svw?;#?^Hn2P>6sHR5VZhA;mu4N@)AV%lohA7xZl8u z|C?l5$+(LwxTMz7$?NW}g(1LN-$A)31c-%J;7bvK{O{4C!$7ZY0&SmW;+_FXdLIV= zh~#5Mu7$wzrT=_2IMJD1&RfyPc(J%w(Zg7atTQYIE;f?-;M_cL3g=w>L|Oql?2WEt^zLWo=e3lZaQ+HjGpVvEK{z->kw?;C zroE*?Q+^^U#)#=kNclY)*nz_GG z|9hxFkx`-!$?Z#x-F4^C{XxZfXOK7~7W3HdNaEGUNV~k2US$_+jqg@}4C85)eFmJU z4EYw$Spn?Aaiq8g7PZ{s60DhqQTZ08PLA3>!3wVCVs;k&;5@`YGI80Xy+Dy7dksRJwaZ)Su`~C#YpWgtOUTe7|SdHeKrp6A_<1hy9DhvM8R$*AN;J%nAdj%>jth^A`gL z*6&9io1_^(zk}1x9d(^s-HoK)p7^zR%6NBSda1@ZsQ-Y0dioYzox65YszT$LFLKUa zOPyPv!+^#LBKATA)Pp`ttH4qC!ky`x{@G^D-! zX|Z%mwV`%$7VTXt0M|fsD(dOifB@Cf%dM5kwPyL8hAr6(IrUixY?INmnq%)TPq=Gd zP&I)W=v$0XaWE(ev4zZ!GUu7`QOCuFGvuoPo?(+j-J>3EDFgpE_dV9KtgG2L@_Qci-CtLR+3*#tWCL~& z~r-u0b)@8CB~P&-OfsA@m=~7b}g$$ z+l)oS1#H)toP$8?3j-iGI%PhO^{ic%w3PceyMo~A_F>FP#TKM^Ee3d@o=m>r_=p)* zUVN#d$KI@^F{|6nUq|PAg?3lG4;*swSRoZlfO>#V*!6 zi{Qb6ULs385WkLABD$10x#JoT-BAbqn1fo;c~5>bdjGNJ4PzgyVwc!NtxNyHnziTd z;zC`n8Q>5CnvxWg0(j+m9Ye|+iMD8zZP`)dn67I4keo_4pH$5{i^rl8hA1`7P-xFD z#oUE(pJkSo5a%`5-}+9SrXP5ERWt5=Iy<^p8ZS=c^Mii!dGdbvbxU5^Cu|qC>y+hz z(Di^=sLz>s5T8Kge51fOP(r3@OrdKR(6a%Ccb zE(f%P#Hwv3%XFz`$r8*JEd!GJ2&ekq3JT}$#iE^B&1z7u>@lfR>}XjT6x{ps5$!Ov zK}B@tv3PwZ_d^j8JDr&~^f<4{ugjg!dojhIxhqOaH9HoRZdoV-E}A@D0e8F2`E$p z8L@Y79$sre9^hy9x1?qjo+w zwtBh-G3VI1kojSW8qxcMHN$pP`a)wr=bn$Y0jJoS+FYwP5NH*>IrS?{q;snTYJxe< zf3}v6RiEIeu^&gN+=pwS9Tl%XdUcjP9qrmcb<9#MO^M~JyajphnFN%@`rh4w2#}`H z)YI0wfZ;lM{u z(S|}BO_1T<250tqRgFHP#Gyvap2yF|AErlT0Xm^JECD(d%V(;<5+99Q*8mU?<$!R+ z^BOoB;Jx8BNSK9N-|4BgXf_SJvO5crs3lMN(CqBMT>^fHW?BA5d5?Bj#+*DVr6Z2$ zxIkgSQZOMP+gEf`XjsBoZu3{-*+x`J)|Szs<#3moMoOLZ+z_kstSyuiodDM^FYE=< zMOKhCDxr9;XBVnos;w7laS%dyepUCBB`-kco+(JXM}NCM;ihDi+DSG?7VU7_?QaY7wL3Q%kjnP?ffw@tYZ z^`6}bZ~$SK>6_4_+AvgKh9jaD-~$4Us$*HM$d^IWQJgTLugg?2?9&zeQ*D;;t;0s7 z#n@KaP{LA`K;Q5Lw_h$|5*7EIkwLRwu^%BtufB|b9DhP>$Jfc|^ zZp8D%gsv5Id-36Msi@4IW+?xz(*4z5>^WhVH7{P{oWE)Hm+mlpK%-C*%*5Cs$;oHi zMkzW=_=|_Hf4+L<#d^>4NNQMabXcZCtt}Y*=uVu*%a3_0N{XC{fZHnrLDzzN!(`Y4 zp8m0astvnyD-YF|2|>mrqQb{ukc&UNi#~yrvOjUY+gN*7ti$|sKqt|UO{GXFaVdY# z-X|lI&DX6wUot+OoGu5p1->DruCCq@Mudu1IKaKR^_FG2?)TM9Yinyi=!Qq*U7ul{ zXKvN?&Go~BiD_(n)uCX1OE1Dbef4T6jY+Q=^A@CQ<3@!J=CGIxc~d!F+<&;?(MCe* zHw7ZZDL4NU4f3RgsnI3}*7-b5`qDFcJ6jg-+FM3y(;}H;*{Jvrw=$+m3BY;w-o07A zV@S2<;i=Z-;<+o@8j5q_D2i5Wvlr4hF&;P{N5hUS_y zA3rbOAQC?1aiVn{c-k5F;T?5P9Kl2P-vR13U8Q|e6Fd8{H*rv;0x>TLaBdW{`GD1M zUYUQ670hMvjDB_cToe&n4(@*pdkl>Lhp@Z>euBY}-29KVaizn7vV7MM-|)a@S@rU4^?p+J`=KzF5_IXn*4OE4rmW zn~Wc4l=v-E`8>A2D@`mnKt@ubKNHC1Sh7m%jL0Q&>$`Vcrq&s#7qT4T>qXI%p)px6 z@EJqZZgz%JO5=Yb?+H1A<$Q2&=j+5n!rDD#28B|T+QCodlIL&{H!Yq+%m$Xhh;PRP zd4yIYA~Eh)^3`bJ9FG8Y!fczsn-_FEPs`XMWt?6)3Fja2%2W^ab}?3Rtk>gXJM zj2l~k-T}6j951-q5xAih`9-VKt)1^_3Vt4;#rF3Z(*f?S3s!v_VvB5Wa7XoIxeYgo zZ;ShPTlqP#f^o&_p_DS$uVq(mF%1XNla)WK)mv&;j2E>eRUPs&q#vz6Iatsd)=x|IZ^C9TfJrzS9(okKC5I&viQ^vQX z_MsndXB^uCW1Y%y-24EWstGJSwOM>qHN}khYL*59ny!%B(!&H zEO-yScwvU$Xt`s(;ExJxt;s>({fR8B19GPD!m6UyS9ZyNyc^eUX|r(lIQha<)g%|h zpSD?e-_1B6=I3F8KK`pV2zZtf<;%<0&DV#&VW-xH$kShAh2h448)Q1T{2g#RxbU6# zbo8{{Rr~4+^krgveKoeahrPQ*4X=mJNXe5ND~&JEnOu6Y8sN61bCV!aQaN03x8~J% zJDiUtIe%_4tG;nt9Kn0+8@{vhDwOo?O}iB%g~drJ6QP9?TyC0=M7zoa!7n9j<*4uA zf{Um?ruT%Mbe+vVbKnh{-3tuK0(nC#pLlfGK8M41}Q++M*i1!xl$Dy0;UAKmB4c{21ptvJW!b=MX-Y}E&CL!*T z{G8l9j~dSV&(%^1LXMQTOS*|}D{BP#tqtLj-lUs{$Ny<`gbmQ3PrAYg|G_V!w(CbJUkTg&vzO$4o zG{gYEPpDD0V^X0Fqb~5NT=~6s!p0=+QjBW$wJMWF2mzb|za-6l<`nh4g%OkgHBDGx zL+0kVcvbT2HT)jRp=FM!s&--d^f^$JRFb&8AQ_G+<(S5o{5GXTN+=_?6wDiUUp5iJ z$$`CzRkEbAd<(`hL1g0Yi+J9M1*uuaQmRqPCf?V(t*35Db@T3zO)xgMtb_|^`{vv> z*6d4rME2*$z1iP9PWCuD?%I0P>@9mH*ezTb>Jz#(CM@eH#(bd8dc%>^&|x5A14O6X zTb>n$UPavobXVaZ+{m(&qC`8w{Pc+viVc8{!F4L)=-@Nu5LM-;7_PL5z<7g`#?;@z zo*_Fwpyy22vYC^2c0d8Q!`MmqpFF@do7|RUZg>H97IqxrNjlqNbXxx8y_dwX>b8;t zHq}&Q!9*n}h1q4^qEJ2AB_9q>xf2hin^8E7@s<%*`SR$Ch$(H6$4PKKh-$&v)sM1X z-Yp|CGZPva|bCDB4wJkx z-FsN;IV&;VbZ^+nOImx!Xe;0kr*K14`0dMa0D1ZbA`c^hFwQr(Amx!fl`4UJ%2Zo# ztc&~mXGw{6W1_Q-pqVrWcTYt*j` z*39qrKUuw!oo>@J0P}I@;Eq{6d#+WR>WDO=clB%E(>A1c4WLY-S)l(Epmo-P|E8FHnM8nTSs+eH(fjc0XdG|T zgm#ury5|Y3!x~h_vbWi#_#<95JG31kVV4?TQ3@>ip?v%3WyqzfHV&m)`_r=5yRYs) zeoCkNFr<$3lB9EJdYaJqVTcd2ul|&=)^kRzn-Pv|@c3ml$MEK`_+-5|--mAjTP0aC z6edE;l&QYh28fl!EoC^h^8AKfIcGA(q_i&yT(Yc+G& zstDh)_T7ELnBfhVea-h5tbY-8BKLQH=){-KklBOQ*)oUW&-+B8#*aKyq1u%ovb6i@ z-nl9)dJ4$<{yqfv#8C-SLlSR#qpYHFDD@b#!4cAyvNyQSDY1bWnv}0|aejE{X1^w% zAujT&T9J7)3Reo_dhRL>yCHCa9@0!AQL(-OCN%UH6v}?cjC*-*sb`0RtI3Hmqh#W5h>?}+cqcuT6iM{i`7#^%?*#D;uS*@ebhf&@9Bu$yUbS@b&0 z!;tP^NYY)!4J7X;^DvL$^)V!(KabOdWAO}?1eZogLvkoSTc8`jBts6;O$Ze#H8**4FtVUV?t(i2HdKT~D(iD!5I z%0MU+S}zj|972< zf#^FXM`YirNsCA)&&eUwqTzBA1f67kWPRWbe4DS2Dv0k4)i8eaJI(Qmw3`LPL<$N4 zQDAApbE$pooB#Z>my3{I{e<72jD>ci@%H=AIuNHn{;#yk3!i?#PYs-R`m%Zz{Vi8WLqB{eygHzlp%?V7aX$9&2fIn}T% zVw#!Kh)GTZu1nQVjz~og1w9a??D70La*PnJjX`OXsuK>js1YlL-P%@zv>Y*d4pbk^ zn%rnlTdh*~@Jmmd5+iT(@{iQ=Fo#|sLp{RPoK-q97RRhklu_c~L_0-7qxj7FVJU=5 zSBLyj5aL`&d(1#Q1#A`iR9ZM!#r6UshcAzRs}KC;`2))iW<`4F2`pEh+&&1nv|_)- z)ub3hPZVG;%2IJ~z^<$wUHdIE;m7^a?E5jg3XzX)e2ip9kTSE#B?DK}WH%Oo@@p&u z4>DqlpN-|m#SB_&P}I8`hU+Jzq>%|TfE<9J+IxlLa=U_+Y-9%HRcyhR9Xu}-GC67j&|x9C+++Jg znApgtJ~tDTJR4c3Qt1D65}^bdlbi$)N)G#d2y|FNFMN=Yn8s~pXFZcsW?0B+7V=P@ z=^Rzb?pEUx%9J0x*+-Qo;Ks_8k$;xJ9IWDjI^-{V!Mj$&Hj+YDkndSip-s9F(!WQx z0J!^7uJ5;NRys=PuU$7%X`Ye%P)#kZjj#{Xvi3S7JUN;H$r)$kFeK+nCB-|UU1*mx z^BId*XI22aMnr!CmzY&85#`rRQt45d6rLU#$ipk0p;7^Jb6WJ=ccsu`3qg#BZ=Wx_ zFQ|+x-hgx=*R^Z&j~1nPE+@OwPa8etAX1fm4qoTHG^HyabL|X=k`hklhfV;82ivrr z!t%ZGCVP?tu$O#l+q!GS66co8#I=hWjd0BZ6bfSC)BDLPIRNmTpGZR+Xf;grGlo-A zUdg!Dme2{@Bck_}$yguP=fVsoEeIHQaM=!LYS8f8K?=h}N1T2;R{*HtrBotpnDAlS zb>bP}Khzi*{m31_V_GfUJXK?(W4B44`bq&)tbLMHvk;G0I@PZFjws#RydJZ~<~kF; zcpLfv4lkfg;P`Ys3_7}@&fOGfN(OxWx3qFqzYYg~<VC0f#XH*hxa@0|hK;Gf_J6ssa-+P1SryoD8j?0v2gr zJ8YDK^{R&(7NE19o`;f(vg$34HAQ}Q@-Wx#J&TlhMM-O@VX44pN5J}9XK0|tTd82g zTWMR#tDRM?ec2UCz7SHO-Or5(BkRDc2m7PJcXmoXDYE<%6|RS@`MJUH%Hq9DK$94! z4LgZM6;< zNQ=xlSsH7{cuFf+Pfz4)-qmQHPKium?empWMjb|~;fuQraS=L?YJ9oBkUPBWqT>2K zM3K@>&GkQSRecQA48=6EmEa)u70Yb$c5=;71&wNI{U!lFPqgrQh*sNQ7IZswUl!9Fi!-{vRtg^mRUJ0 zEz|CN`x|zVN)r%Lz~$ePKef)7@K*IsOAK(I>#);d3+Ez;P`qE8wHV#%?v`SxOFg%5 z_Y(-@;aiJ?E$6S#cd~LN$_b^xq7yyCc0{Stb3#?mRYiw#za~7gA#@(M%%vUvHLgU? z(g6ajjw>R>;6(Fo$UIuW!JP`OLL~Wee_kR)eqcLU+pWm{kI9c8BL8@!Hef2vj>-%G zoIomYbz%U_8`oX6*M1)Zh=Eo_A1WhYBiFUDu<~rZU$y1y&RB1ihmV)0IiSrUe0&CB zKoJUSc{+(|!qs_E$dl8Rtiz;qAW?Xp1LOnJMMeUm`FO0ysCnG3ZYxi82~)&R_6#@v zqT4Xc1#rzUWSEX0+_3)s`O)R)FLPcV^{Z=}|8a~bX@md*Yd5z&%(u=4T%lDK6)~vy z>v5HIVx%M684H+OgHSOc7jCurtg%Rw8yIS;;F88CGV(?>QfX!6tUzsl_(I(+?E8AF z{fpl#9ksGKWhwWFGLjKI6l)Wf@lb|Jghrb1mL40<_bof11*}0H zmgK*z7d|7(l^nzfIA#M~_BY=DDP$%kyXmDi;5-iv<^+vsH7 z1VENY{>3~`-1B}`x#p;W{`~|g{NC-vRFt(DEn2^t)&8@DU0FI9WPc1AMSG!+wF7W< z9{1!6`9ye)`~`P>#tG?9X40@h2|eJYx8I8tEoxxju!x-ytSW>s0ei?9U0f|_5CCv4 zn)yg{1hbbsp+s>?@}RsR9pC1#-jtWG_EyFRDT*~E&gy{Fs~;i`SdrS+af3Aq!`$Yv z9R_B@kyNopz%l)Q$Xx`9J_!9Q1-Gcc0p$5C@suz2A)mguoNE?SCb9<{ZFBL&kz5Yb| zSwinuW8s7)a+QBQGrh|UAohkU2CiAWEAseZ0{9)zd8pdmyn^`f4;OGXEYx92=Fx%b zQ#;AuYy3dj|9U_;WQP8CS*2VN`>>cLRPQGF#E>U&kb2uinnZ|B-)^$L-;d92_uu87 zi9G&K9n9_Z2ryTz-$LL2@CftQDHY=SrSi)o!&3X_LP|%X3_Knh@g`rG@e>rD&hkl$ z)*H;NMVthFi|$*x<<1DO#Qt_VLT{WCvqu-wyT*RbFV2sg3g!lPIfHR~+4y&zgW+zfykkXk5u(sHvdGcU^5Tl|-<9Ki0$c$^Xh>XsXdJ z1)R1pMt~T=a1y%D_`w=Ku`N?4uY=Hj7n3;CZYQ>U>^-1^Bp*!*)t+)uCsYK?n%Xg3L(xAPQe;KJyePM^aWcdbYI&|ujW!U@ zO>m8Uo=vk8axM-=h0ZW^#T^MP8#r?ndS> z=4gY*%n1eP=l&6w@%bPMSWdPA1dR0AO9HmD6h|{CDl!^pVXgCi_5GAS-lLaBynfnB zr}21DCXy@dQ4Z|}SNfFtkdg?W&7(Smn|10UAMDnxano%AtXIO}|-=Z}-Ta6nG zkAU4Wau;-rt7z4{M)HH#2i0iZGT9>IOEqN{M=ZjgB0XVkU@lfkDdYQ}z7&z5=oK=& zq;CufP*Ou_CyaqAUvKVMv1-^SyF^@!rOhW37new{lmCDsG}GH zPs^TomoOoO$!bmT!Zc1-4a|VCvt7*ix&AZj+-q-lrm94ARV-}8Em$pAz%cjffl_cO zMNVWf20Ya17KTf~ck!zB+XX9dPyjSmTK{PyhxoI4aMQ^%&)i|I&mjx#+)h{i_21%o z#qzZt(9iyqm-=6i46u*vM+BG`pZd06b-j5DlgjyZAQ!}5!4$Uy2~EZ0Q+L3EK*Rf1 z&OT`Q6MlYfa>jgTV<06f1F>Q$qKlu6wdUm+8gP41mJ`qPW_W|*B-;I201LgcJqVuF zCpt!aR#Vo(6DV0)oM?Jc@*;plD9GV|h@iGk0l(YUQSJ>^xAcTfavPr?I|>?oAG0!VTnB@8@X5?Ep2gi$6;OUxU^6N&Aa} zuy~Wf4xKj^O@Bjl;1UsOD``anBDT&=wDfQ|6gYbAS4L|yr}V8**iiZtG!FmpOw_y70wvRX^(rod7^w#C9nTXwihjh zs?`RQ+mE);95)_7h4SI z+Vnsy>E{%5aW&wXl+Agm&~!r8QF6}&{u66y@C~4tK*uMIxQw}E!v}>*eNHcDKGx5Q zmBsJfN^w@^`Driv!d+hV{uULJfW-R2nl_unx{2;@0bj4O_vwl3H*sXOEunF;dWn>J zNGo-97QF}efj^w2<7D*WEWN0pu~t4SAX&}Ler&$21162!>eC0QQ=8@frmsZyR@fsX zIBCCFm*@CE_aX6r%FgIX+a5}J6Xyjtg34W~8#kVDxeM6&hsPSuuwNiC5|vVP#lgpC zZ9Xe8mW;TGW7ZXCvEyN8qlbENB<8O6Qa%krfZZK^sU;)ZPlUj72Aj=giSXvXJ4vDx zff2>k{i%#`=dZS~w=z4;G$E1MRQ}IP!_QfxW6fWs0J6~>WEL*9u_=`JdFgN0lu#*; zT&xGyhq+T4D|=aQu6Vr9HK3G00!mvCZjd#JQqx#{AdxF7@A+P0_+X*QCv4UXDbwg_ z^C{+!9@UO2=%|=@>euO6w;-Lt{oRh9;s22_Y5BVpaGrKwd+%ggC#1OPDeWO*DUW(j zOgIjgU&$WwbWlmtsVCnGHK6~7RYj3qeQ4lfQ_b2MsY(vyToO+rkt+{^Ht0Lb*pgX* z{1Z@jdEYroq}q0|V}u3Ucq^5$moEL@=_m-Y22SUsW{`aMACBYG-BMEc^xVH^o!e$( zBV(@kdlojM|A@qelVCj|d`cvmRQgd4ORU8zr@kB_Mep&fC4pz^+DU1A3fbS{2}peq z>?bqIb-9q++?mIkCKF?+Ac#PM<;4ezZwb5_?40_Wl>f_3!nXt%1t$F~u#%5RnFlQ> z6nU*D+iBO*m63^ZX2jKfoY&=My{#(l){MFeAb%j$YFawyQ7?=w)^bxG^cdVVngBw`^WW!?FV9xGXE+rdG_U` zPxgu zW-DdlQOK{NBbk5y??$`Tr9oHc3NgJ{k5ayl=`xzgO7%~2>6W&okC&}es?8WRC4^?W znT3QVnu_|OX6}v7%nl`}rzKm^m6gTL#_s+|@^^mtDoi$Nv1nHhp#Z2X5Cf>>DD8ez z=;vjgv&E%0j&Z1|T8G3H=Pa9aQ3-&=#t)8)T8@)Q8a*qPUeRJ20-~2!gx5O^m zC-gV+P(OnweLJIctoUCKZ62yEue!!XZ(C~V<70et?y+*6)|ydfk^;HiFlTdu^RVLa zNR0ZZoT)=&i-3@>Sqz858Z&48@WaI0f5^G)mOSEJzsH$smt}JLB60)%ornQt`y6yVF?AS4b)$0!*th+hPva@pFC5%NfT?{5V)^j(UpzGW zgsXaPtGO>t6q{uj(Qb|ZPnhx**A9c?3I@DqUCSov&et%d%VAy#v&@O|j#9WUgi~=V zh1z=&;#ju={?BIw=nsR2daX#Z(a)02PTCw+{$GzJu4sWg`*PA2_pdZB%e$3w-1+?P za{~^Tx%rg6{^LrreI9YO8R_^yd1S!`DxFgAf^WCwPcv<|pCl_uo0lmH)1i9)S+sTa_5cUiz?e zpO#HgIq7}`QC+?hwE9}3QZ4FRC@Gh{)#cveeev`Tc(ynTYbKYzc?XUTBX+edi9PdM zrwLB^rXah%^%3ju@fc*E8tw%8Fir0^$apFP62W2&@fOl=%1-<^DRC}b?o!v~X3}!G z#wGsYD!&(9QxoY!m@GF>QrMKfi_m6gIA8OdUqg|Pe4zOVX<62p3G2y&@Lro%@6*Aa zdoPhxm#4pOme;bxqT}5S;3DQrHhZtkfR2q20 z;4}(mPR6EmV07Q_&wSuT7-7!@`A4WP{tP3wslb%=a z*z_%1tM_=uuSeoFMBo-0$~AW5*3&^N#QkX@#QtgnVSuN=*n1{dbBwh}QQMIB7I$pj z-#LBP5^KnT6qIkZkV9%$%bhM5C+F(kp4VMH5gLJB^*z-n$E0JTpq?;O>DTKdGZGHQ zgdq9~P zML*&G0yRwYCUO0^YRSYK~xz04bep=i} zUzo}<3E#icG<1!E&ChA<3yt}hN?<@LB>Rrhg}Lsmk;F>GUg{w?R~@bz3q7d^|Od|T|%K0FjphPziE=__2-hS_4V1`_pb3O{zdN(c)Y+7wbMJJ_l7 zT+u)KU1?_`RS5b}QPJAXP3!SqYr=3%&x1f-^PYy#05?N}ru#DrPs0t7Vvb=}r<$J!F892xyVDl%$J|2fx|T<6R#Sn5^sI*OR{!wS zFo@B)7(~zcl<_m(RdZuHGku?;+vK#3(Iu_nxA)qNs}Ogu<8*7_`opV+D(4y7uj zOTJ_dKJ~BZ_t8C!^eZy=(=#hrkynvIR`OE1-q^7gS zU%wt;tu4IGuN!0b&?PmY!Zzw`-RFp%1K%AM#AKT2J|wR(So;IIketJi$&S3v z@n`mD=6sou7_Ve0)t2^Y6cy+KHw}Ohd_Ue+DdM)nV9KaiBpIr0p!$RrlO3XfRFq+i z5x%sHi|hHxO9Q(O)VOxoyb;m#h8l1|50t~BC3%g~D&s@EO2JOh+&?VdR`5WX8x$j; z9P|epWZkzL3prKC|I2Cu#Gngqf8>jyCPCNngCS|(Y&Lq;`0CB^DY{m3dC{Y(%Qrrv5LU(5zc zw-s>3e&!3ey2(GEJ@Y_o+QX7I7ijbU2gM5J;D4t1(+Q4(Hh(#ZRvWU3?wkuOGrqB9 z(*MnVyr*s};cRm_)9FyqyI6QYg0bg`TjcjcP)TU z-^591SeQAI^MBxtYr@jXiuE@NCtgrrpOYu2e)+#KAo)+mC(8f(ExYi~s>FXUgcb)1 z75X+afQ|07s+IY*&fGOKHOvsiQ^1<-c6^H;4f>o zX!wI^RyBeAGyuyf2j@H#CR* zEtiV<)0^SRPpltqel-8(56Oz#ZuqEut1I;80fB}l_M<+|6X zDxu0rN6TzhPBn&SK1lMa#PlshxcY#NWNyrDTS0{`Y!I%efm(k-`gWLSAP?dmKfE02 zuJ0RZ!>sfc9cm5!z}8|Zs8vk&DT|Kv^i)Sx=7x9sAam0VSVV>`8*4hoF+a`@&K-&! z44>I~&)a#ST>52LWj{;#g5Nb{PIx;FG;Z#S`>3{Rk98Q){%nEAAd5~C-o&3P@6N<5 zit%t+79J$fy5oOIO=xwk@=aA`BbK8tRlM~oMC+=87I{G8WYx_S8;-||A7nyv!sk9R zrZb#Gx2~2-kEAM(%TI|%E~vL!Ess5JqBoE!uotpF;%GOoxFWx6WofYO_pXtN0i~`` z#msgEM<(yZ06F*YzN!B*;+|3!SL%&qp%{$ylp@6xf44ihWWR$@@oM(0d|fi5R$g5 zoYiFX{@GI6y?Sy8#laTv<4`Yw)(e-!4_lY&e8p86e6rkI9!XxqY7<3aUHp zbe_Mm-9xxIjS|El;_1ChIySp2P;+&swFNW(`rYH7J#l^)nXKL2xAExl`@6eSeW=Y$ z9L#KF_dfpoass{~icW>dFIIvs_22u(dFuwd#p?7$epV6t@Zp&1sSObqOf{W+yBAxub9g)%O7_ZHFX`9v?a0;m0TWQOl@ zpkJp?FWJUDqP13OljH96BXWuCzK>wbcUt=JUDEePv`u4DCJM)Jht0Bm^5smchO&kV zrrvX>yUvuGn>&~*!TLAQq}#Klj=P&x&+o;SCyUztdZ7}Nc+Y^aWV17LKC~1@Ts9Hn(CyDl%Om6**0G1>P-{nAg|1v;Go3*|f&Gre zh#)1DBIWQ1N`-hdezR|fNvu3@u^+no7v-VowI25%Wq(%N!Tj;CK2)~LFGtb9gMP$C zxlG)ml|+gHX7@gmjJYmzn+(2%Bq$`vsd2re_hYY>=q=E^>D5rX0B9DG+~bS|qe*o^ z8fqI};$1SOh(?%Lf3_L(XL0nr)i)zv2X<27n?YZdM{Ngt325P zownXYGfCOi3sr(u^S!A;>&0QifyX=hilThEJgpk8;%Q>NNrcVZ{Yy7q)%#@_dk)tG z9PJ*@)v-SEx&{HAK%zkdX3ccjt)Gb`sjcOXZ{ODN>Kq)H@?`P6!o@GLHoupeHJM&X zLO$o`%edllFUq9`j>m1`0!eG*-m--gBJgDKWC5?i@D(%I+_x=#jn%OtHQ{Fe+3W%y z9v-ia37Vq&x}IHh&LbayF4}TEG&A4NaAt~3ueN3SOa`ZNYIT-3+Fu#sRz-{p zETt5wsE9(6?!!(CUu=9m&PS{#_vb?4{p@YRUrLT1$^wgfbb%UrPyyX&^j1WdkN3%K z-12-=cr9-^(r9D6!D_}+r`&I0JXuTwB_hPm!_L0bACht8++iM&tVoUe!kGeN2=adg z`IMY|^8Jx_(M2;cEB_q@`dY3>d{-mrtOBIQ7V&rO6&Ry|W`bwe#FmDadaj_C^GIvn zW^MPo75QbC>=^5CetkBX{7I50%P75apUH`~A(Y4ROKY3D`j?};8@LNCyih zazt%D7}^CRO-5vRm}Cg$_1mN2;o+c_%wcxO#&zj~U7_Ig^OO^Oxn6qmL6N@|!vt$N ztzVfx`?*;fWYO?3h&PTk&`{8A;5i=09yOt(qvNspqH)WZ%E%I*Ufi?ryi0hMV=*}O zPEoX}$M`h|blF6s1rNjD!n4?C!d*1CwgR%UCSRMzp*2&VYH8J4EYvFUcWLo;=7(Sw zX)Z#7K2<4Y+Nf1B;v^*#F&~%<1N`=x#JrjY`(!1pMq7%DJGs%g!t&ql>+zSrVdv7l zr9TC}z|9uXn))50XyF-SjR8s@;8?5NJVwx=N73RL%Z8bGpY%-WPOI_e>W=1wUmGQ8 zryXo3B;Vvn!D)R?L7Xi4+CG!`2Iwt#e&xwFSm@{ zcWx)cy0fpr6C|1iIHSwgL_~(=P8zBMOqBw3&XT2#73-#MBwV0MtaaMCKqbuxkryS0 zBr{?-^74WpY&TWRt7^}9A?z1=Q+0H8eJ5WK%}R)?zZ%&grDmx4{W%5E)7ai8RH22Uy#U|i8Op?s9d1; zH+vLmOR8WnIVR1##xR76QFbLA-PPG8>NN4yvSYeGw>Qi>$z!3%cVS!%kGd!#^F(*N zvbVeY9uLp?r{rf8wB+l_6hk{KGmf{Qhh%&Dy1K;8!GSLd;QIt!CyO*fXd$)E*zJ*0 zw3=#YSm;Ila>Hy>nx^&Qt($V7VUcVG=?C!yN=<(QMtX;_iISy<>#WFk)$iBn9M4`#LRgiU*Gx z)fLK^+2nC#mIivcC1qt2PQN})Pv=ku!X0)inR{}=m6Ir0D~flk!`1k%A5R=t?MnPX zMh|+N66>s1T9LjFgqIV%kSlPeNB=^)WQ%oGO*O61+goE+F1SXS zhTo-P>O8(Aq& zCl2tC)-07*d5`BpK*t&ggpKLk>+0(29|h^K!#sVzfQ&xW!EDqVO4Llleu6+fL=ic2 zw6}EJ(R2v;0&6y$5j-kat!y|*Rj`-a^IF>;t?e21ZhUkc`6xKet;gr4Ki;t+KF?S1wN1Re^Q2Pm^+5(kBdsxT=?zO<_*G||v`ScuV*ZZWSBK@MlE`7q^ z5a~WC=H54FH4m3p`c|;IGY>Pce3~-7XI^0UdL$&uBqF1-U$Z!vTCQ;6AL!FN<*MCz$5^BYx}Tw-5VFufiZs-9rg|ABI4j?8 zs}(#xr3lyWzt{PJxgsK%0-sh}WVZwyPQbhz{~d!^*hv7UAhVY?wZP%1KM1qTqFGQO4asr zms|J%gieh^Dwfm|o8O&69&Az5cZLi(~stSjc>`?N4r8%cSEOL#T_WS&?6%N&*!%dyq>43YOIts_E}sogFUZvj?ein zLJLPN1!FV(j-r*%>w2?Zpc1!gw|nG*oN3K9Afoyj(o(Uoo|Jf?s3VKz+Nw^Xh>}{p zli?M7XXUEvZ6y?!u65O6t3&NCqUF?>6SkI*;7?rCT9747 z#-cS5^~o0s^hGMTqTE9smFxHOcb-1dpw~<*{^!s4U<&W;ZclL=T&ocgG2NjHFEJc?oQ_`b-`ulGG(P-(64mq7v$%pC**x{?TQT0u!K6mRrt-F0znnm- zJK~jOtd90Ta0aZks!uLCI>UG0g!-ADE}?>eKGKUK8c?XqnltgL>N;w6&qr3gPm6aA z7mNNRuSFxzhj=vx0wl^qDV;waHsZnU2)k(x<>7kIR1kip3kH}smnfl_vpaBP&ulUT zww3Xx-9txA^44vx#O65qCE-~rAivE5azl91J*H# z*UqbUsowBASpTGJ*o(Z9;)OW(T9Y0|_|2}FDRU$(-%ik!z01$<^a4M#1@N_9apVd> z8UnSSuvWC1-MS8XkrE38fWHchBm@uZnXV~lk$IzQ3TdmBfNRx^PfI(RJkh*&v^|It zE5Ar8k1J+j8O~(wN%dG+8zd1{qBw5^1kZdO^YR6odhq=X685p4@`Wj+J3&vc!$MG| zgr9v~FfK0fFQ8A!wLqeP&#zzeAJmk{89jOr3o--`zL8`YYq=BL^eNc#@;K@y1lFRJ zHdtiryT4>NpLsEBu%KMo;QtfO+(skMmAkwhbWWC0zTJ#Rf6VK6x6T^rj%J~*wHsdt z_KO(LmiyJ?>@BQ>$hHkOFf#x%fz1z2*0tZ?0v5{G;K;2eZq7`)?W|bx*56=@N~&|i zN%BHQY3U`B)lUX?2voCkvR+p}w2Ofikauemm( zOBOTZdswUk3f4MxdFTQTF>lTuqsz=>T!75N-^~p)7v1vW4wbFK>~5FzUAxMB0G+8<2%{^Ws{2%R z<(6BEs9_w)FXUdfP!s2wVsN?jwBYHGm3yU8y8E`B**(L;z?=5>@Yf7}>(qR^b?KbD zqm|+Qm2;4D?Q@Bd$5U-C;2yiWO_3>A=l;Zj5J>A+HNG2&$=E1DiLkptBuq>3cK1=_ z^Vkk)r%v^ahT{v6`;liZ<8MaITh%U+Eq}A<-59OG#x2o;a<4fYYIJghUx7n&Mx#JK z{SnpAOQWQBhm>~ajb+yfM$W0CySqXftnPPO&})_b1L5!f=w}etY7o@|+ga036?IBG z97TW-&+XxlHv^S1#l?4RqdBb~KbB>SkBi&gJgZ5lasM`2$ydtLrrzDP0)eDUd3JPm zyCY0OsOYk#tO$5zhWUv1uyfV^(zw3XEa(y)D0*^o z5`|0m>wE!WkT8GMMwPzMogrtlM*tR%w4NTKn1P>v{qj)=wX72t#L{Z6+6AX|+5abp z0*YAch+bbiIl}Yv$*#JJS5|opjW1$yyYLI`X-gT^G8yZo1i_R6u!s?0fk#nJ@7TAwvdQ zg7fs-TlH9c`i3jC|DNi#yjPvGOzFLGpp|ZYW8@$uD-54*i%(BlT1o~M`TWF^EAMR| z{a%>QXJI7Q3U(?O4hmRxas?US?4a8!?{@ElS*pi3*-7{m!IE9v=1>`GJ_o^5m4$!^ z0oHc|Idp#23ks;3^C47^zX_+p5Yo?|-t3CGdqe<JQijuygX`_Tgz zg&+SDn>{dVUD+x%JSjMG$W5H%qPP0oRJ!qDZ4lw2XT6tRhdX^4oUF$#_V&wZn4L8* z8)5z`b-AaSvUa}!h|o7Sp56P3I@lg8?JgB9!^&So=*!=BPF&lOgm8genCWGI5L=uy ztcHND&6LwCr#`gx2T)W7qo%dWB{Or6N)K7n%^yJye8|0e9@rsXiMEfPjwLw3+gwpK zi06>GZ5+DK{$3#jMK}^F5W*}y(aXF_yPFV4CF$wvjF5&f2+o2~)+fsZ(J(t3cai_= zGoT*|?=$%bKApQIF5d!1dFwQfS9cB_(B*!6C{4%%Q`6&z1yn`H`7yUMNr8#R0$%d= zs>>am)RIoWmUxIq?3Hee_!X%aM?*%YK3j}+ZELUYaB^@An<(ORTPs3t_?QF7dYiN0 z)$;Gd@N9OkwFwG{rZoN+rI@C+1p)XHP1!@+sfCM>EX_<>KfL4_h&y&phS)9?;Fme+ zDo#cvo(FP*(7jc6gba$fw^Pk61~AGp+GP@?08J{Zzh%%|PQSmxvjXf6;f#Xo6!1x4 z%I=s5IrWUjo5DG#1+1+tW%k+!K`sOp(545ZGDSXEDj>q)`K##B5M7jh1Zr>eBihE& z(%NRu*p--v@LDT$(T^ZIjL8dYGja1Q&@dUT=|NaGc`lRl1En7RT0yI^IJhy4Cfd{( zruSM_NjwRw3Z_OKX;dF+JdvLqVe|$TXlrOc`jb9VB$d~wmN@vNU*YrrBDGgQYpU1K zF5h>Hget4tCA}8?LH0C}pTzseH6Jc5Y=D5v(;W4NyMsHHQ=Olido&Y;W|*gzgL#i; zWxvy8N{NpbvD#K=5-sKD<^5=Fr#S0nU|`VbHNI@8WAiyLZ+~%Ohp@w^O~!9a@h3U$ zRLx}pHCNw}tM_5+eQ{!E03BTF2m7jq; zzD7^4VCew{<=1CI&A2cIB{=~Q{MYM7&fQGWx%?$Db-~8YoqQ0IiCS(xEfKK;ZgHa< z<^g8y*7LnA9uMovWp>|CM1(Uv(d_%`)H)9KM)SeBQl&Od%wQ)K>)X-WqdXf7C`|&= z?c`CE?TJ48dLUS&;NN`TTnv)-s{jYEsY@ohqJF+z6J#o+Tq19ur-Zp}j8nsnP)EnC zjTe1$K|t&}bv`k_!0PHX7SqioX%Vi}9@tJq9W}G7ySjQ$+m77xqvpDvE0*tG${z2A zg`p0Y_vI286G`Zo%krH^V*>QXFigD4$Y+r0YS@}rvse4so+4`1n&d&$B1gH%Jkn}G6uz{U=^-QEe>sZ=jymAp$9BIAFTatX1$^ZSl_Pwe zeHS(1ly4Kq>~PAo^fHK=uUgFr302j);EqPS>8V*|uWl=XSUlASKU+Pt8$ojPnHydh z*12h)hxxuHxN2a4n_74!>5}B-fNMNK-ssZ@EqV!I=RI*NQYoKU-H8RYT)^6_+cLcW8=z$#05eCcr%3wz zdK&h#9;6pA9upwd=FracbMH?!dT&K)GUa2e2et-YR7RXj%$y)?rq^q3$(Fk$MkH7> zkMTv#e;8&#nVEB2&A=Px)A|>#s0I=bkG&Tf7`4lS>0Hf;QU(SXvb_zl-lFpI53Z-x zJN~^v#Ri}cmKT*^fchKX2yS)3g&>_L;r_LEdKxbAMf6{qD?J#09r6ohT=_I zw1E#cg-xkL7D4Qb<{P&_N>vQ`lbwat{yV0ppIdIS{d5}x4wbI^csn)<)p*#7RllR7 zQ`^e0(vRHF?+FyMVqe30GsET!^Bt$258_#F-$jPFWtF*?uf}bW2oK}%L7mP9arYLG*AYTyIphkor;px8{*U5(dw8cfeOqj zwamdRfEtW}_@Add(f5ET3Fh8>$1gaF6EOmk3IfuY%OJZGRH(EIANOoK`~H1Md85}V zt)|Q?zy(k*25Rfnj_kh6eiIZ&#QZ7laH<@IAI(2~in+aXLX8774<9e@;Z)m3{j2rA zA%HlLJ3Ls?D;tG;@8C?AwAu3qzHql)z@?FRqsXQm(F+xv@+$ubV>AXY9Gf+M^}o$AJRrgvPrVbFEPX2tHW zOTDrIN4&ekkJS7qPqR_|uQOzT$@SxxxRE-3zz;$nL=A3bEf;e-fi7Fq~78^0{6 z^^oLU0g|mEJMX4!BG0`B7JBGG@3}rCV(Gx#2E^#pl@K`ewH)DPIR4=XR3ln}H&nU) z5Yv>y%bS{#LB2dM4Fi3l8wBVZc1Dyo8t_`ctvjc?p^rECd>rPFO(ea;nnJRI4Gawh z_hAeYm%g)30Fv-se8Z`&GdT3T6;#09!+L;#U^^1K?qH6P`&UD_ z8r_sowguTvnhiM!3`SWU3vH=`5o^a$ETt}QqUik#HTO3HZAr$p5C}zr%HxO61|m(c zXKu;`;+p#88ecAlb7sPPPSF;0=6oHtW;etoiShewzQPg74BWX~KJ-okzbsN${|h zLk)$gfhx6+`0Xtsy>U0-=#sv}Idoi_c{HBR@Lv9Mc{C!m%#9z~7GWRX;I6(hdQ zl&2c=q1Wmr2KR%AC1}F%X2^fNGDoR}Et{t>h6{3EN}bcx?U{vK)D4MzfNudfg%gi3 z3m4ORXMx>KXR0%el$zxA`p@A>>46gpVj2kixI|SaPp3St%h5R#{SwF;@~cY81u?z_ za^TW8`g+r`1>>$g31z8}$t_M+;{%L;hL~1ogQ@0X9a>W(0(okpBeT<^pRbu?y z-kMZzDhW0ovAc#1Y!0rWZ0G`JPB=ufmgteV$(!`e0@v|Ae)!e0#@*wME+PsEr4C(| zoD_$7HUCwWrTF{&nVu(Qh6*#=zlyg6>~mSt^PHw;ijoBY-%eWl8)H+eC@Ckm5mX5GKhn+EMg zF2HeV9(v^2gSub8euX{r(gLUP)LUCi6$?m}T(I|iZgQ$hbnm(Pomd40#|GaWMcf4+Wx!Y^+O-X|5-JQRy@fx(t$y-H4y4 z@X@O@HMJ#%Iy$-KmGVNeo5mfO5GF=3FG3A}dCHSJY(bqmh z;_U)`a8mdD=%|rii7p>1^9Q4p6v;bxg_52=v8Aj-znGu?8fsYgxz`eWr8;_8pC4C_ z9M(PPEsDh$d`l*SVeLx#&ZK0mrd^Vv)-DpesQ>RT1=F;m-toT)>&VPYSEO=ve2Zmdbk86D)PB!7yS+o-3)YkM zsN`%v!xbS=kYAR9Dw;#O3G{@i=PhAOLw7wfdDI?MR<$(&<8^hQ2q0L^W06bU|LEsd z35(f2^R%+j-YS~n?=*%j^WDAA2S#=F^?#4YIisFePVXk?=$TTZ4 zJs4D=uA|MONTAxGlNYWNg+i&LJ1hs*V&7%Nby(iGk+ITrtB&($h*G(VhDtT#;%-N8 zcjQRm?o*}FN*h#UY^;vF@xVBO^0;aMktkPpe^#*vPlIC}KDk-&<=3Xr1|4bj@TY3t z_8YIUIOj&$NAQ5HZ|OEQ)xw!PzAhaD=Lc{(KX>@!M#;^NX1jLmTKC|7rFWb#Rc1Da zmBZK7f7Pz>ui#0N;bZgO8z+{FS{@D_0gp`3QWOT;u@kJ%Ck94Wg1 zm-Rfd98w$IY_GAeL2p}?Krz?-F-Lg;T!o zA`y8j%gc9>rYQ5nQNr7?>_?eL>gKBUhN^4nSiP{}KL;Lzk<%+05=9J6Osp4a^Tewn zO~-`}r9#$;s{b&T`L}qDrr_ca2Ba!zdm+7VP%7WVi1rru*;QeU7UQrpPDp#S&K*X{Qr z>`IZ55m?aB%~vSD=ZQKlPi#?2@{;vnUHa`mqW2HMH^W!U(2Cy>)XHNi#-H?`ebRrm z_@eRhEiTvTph*=acaM8?U5()~U{FBex)RFm?VOLYsy`PMZAHBY+k`9-bPp)lE>JPg zPG#3?d6?9Tr1oIFTOw|(nSIiayPO%9nORa&YHMdF`w7X<25Xy2o4FgWuild=ig>oQ zubG;1J!+1QidDAhjLQr8&ClGi1?SIebO-J@Epc>b);+ir>*QmnHq}8(Nr`8L?Is2X zAJHe2F-retzb9;tBgy~=vsm%y$3wZa%hE+qoiiynO|0IZ&cmSh|!82E#}9F89gGx}MIrqaev3#Vi?ieRG)F=$|IZkWKN^BEhG}>qn<0 z*H4e{*?*cafV0V`e+uG*GgmH9H1*FR{--kb=_zyQKi!TY5UT(5q=i62{?nfxd|gM{ z)!y>*^7QodlX0*}_Vn;ai%Ur{T?!`qn?wOs{QD*9!-E^A*HsiW9+%6%c>DhVKbU0{ literal 0 HcmV?d00001 diff --git a/hw3_own/requirements.txt b/hw3_own/requirements.txt new file mode 100644 index 00000000..207dcf5c --- /dev/null +++ b/hw3_own/requirements.txt @@ -0,0 +1,9 @@ +# Основные зависимости для ASGI приложения +fastapi>=0.117.1 +uvicorn>=0.24.0 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw3_own/requirements_hw3.txt b/hw3_own/requirements_hw3.txt new file mode 100644 index 00000000..1593e6d3 --- /dev/null +++ b/hw3_own/requirements_hw3.txt @@ -0,0 +1,11 @@ +# Основные зависимости для ASGI приложения +fastapi>=0.117.1 +uvicorn>=0.24.0 +websockets>=15.0.1 +prometheus_fastapi_instrumentator>=7.1.0 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw3_own/settings/grafana/provisioning/dashboards/dashboards.yml b/hw3_own/settings/grafana/provisioning/dashboards/dashboards.yml new file mode 100644 index 00000000..f2f56c65 --- /dev/null +++ b/hw3_own/settings/grafana/provisioning/dashboards/dashboards.yml @@ -0,0 +1,8 @@ +apiVersion: 1 +providers: + - name: "shop-api" + type: file + disableDeletion: false + allowUiUpdates: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/hw3_own/settings/grafana/provisioning/dashboards/shop_api_overview.json b/hw3_own/settings/grafana/provisioning/dashboards/shop_api_overview.json new file mode 100644 index 00000000..9e029a74 --- /dev/null +++ b/hw3_own/settings/grafana/provisioning/dashboards/shop_api_overview.json @@ -0,0 +1,66 @@ +{ + "title": "Shop API — Overview", + "schemaVersion": 39, + "version": 1, + "time": { "from": "now-1h", "to": "now" }, + "panels": [ + { + "type": "timeseries", + "title": "RPS (requests/sec)", + "targets": [ + { + "expr": "sum(rate(http_requests_total[1m]))", + "legendFormat": "rps" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 } + }, + { + "type": "timeseries", + "title": "Error rate (%)", + "targets": [ + { + "expr": "100 * (sum(rate(http_requests_total{status=~\"5..\"}[5m])) / clamp_min(sum(rate(http_requests_total[5m])), 1e-9))", + "legendFormat": "5xx %" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 } + }, + { + "type": "timeseries", + "title": "Latency p95 (seconds)", + "description": "Если лейбл пути называется не 'handler', замените на 'path' в expr.", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))", + "legendFormat": "p95" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 } + }, + { + "type": "stat", + "title": "In-progress requests", + "targets": [ + { + "expr": "sum(http_requests_in_progress)", + "legendFormat": "inflight" + } + ], + "gridPos": { "h": 8, "w": 6, "x": 12, "y": 8 } + }, + { + "type": "bargauge", + "title": "Requests by status (5m rate)", + "options": { "displayMode": "gradient" }, + "targets": [ + { + "expr": "sum by (status) (rate(http_requests_total[5m]))", + "legendFormat": "{{status}}" + } + ], + "gridPos": { "h": 8, "w": 6, "x": 18, "y": 8 } + } + ], + "panelsState": {} +} diff --git a/hw3_own/settings/grafana/provisioning/dashboards/shop_api_routes.json b/hw3_own/settings/grafana/provisioning/dashboards/shop_api_routes.json new file mode 100644 index 00000000..495bdcc5 --- /dev/null +++ b/hw3_own/settings/grafana/provisioning/dashboards/shop_api_routes.json @@ -0,0 +1,51 @@ +{ + "title": "Shop API — Routes", + "schemaVersion": 39, + "version": 1, + "time": { "from": "now-1h", "to": "now" }, + "panels": [ + { + "type": "timeseries", + "title": "RPS by route", + "description": "Если вместо label 'handler' у вас 'path' — замените в expr.", + "targets": [ + { + "expr": "sum by (handler) (rate(http_requests_total[1m]))", + "legendFormat": "{{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 0 } + }, + { + "type": "timeseries", + "title": "Latency p95 by route", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum by (le, handler) (rate(http_request_duration_seconds_bucket[5m])))", + "legendFormat": "p95 {{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 8 } + }, + { + "type": "timeseries", + "title": "2xx / 4xx / 5xx by route (5m rate)", + "targets": [ + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"2..\"}[5m]))", + "legendFormat": "2xx {{handler}}" + }, + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"4..\"}[5m]))", + "legendFormat": "4xx {{handler}}" + }, + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"5..\"}[5m]))", + "legendFormat": "5xx {{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 } + } + ], + "panelsState": {} +} diff --git a/hw3_own/settings/grafana/provisioning/datasources/datasource.yml b/hw3_own/settings/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 00000000..c9f4f3a9 --- /dev/null +++ b/hw3_own/settings/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,8 @@ +apiVersion: 1 +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + editable: true diff --git a/hw3_own/settings/prometheus/prometheus.yml b/hw3_own/settings/prometheus/prometheus.yml new file mode 100644 index 00000000..cb41e3c3 --- /dev/null +++ b/hw3_own/settings/prometheus/prometheus.yml @@ -0,0 +1,10 @@ +global: + scrape_interval: 10s + evaluation_interval: 10s + +scrape_configs: + - job_name: service-server + metrics_path: /metrics + static_configs: + - targets: + - server:8080 diff --git a/hw3_own/shop_api/__init__.py b/hw3_own/shop_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw3_own/shop_api/core/schemas.py b/hw3_own/shop_api/core/schemas.py new file mode 100644 index 00000000..f7547e01 --- /dev/null +++ b/hw3_own/shop_api/core/schemas.py @@ -0,0 +1,49 @@ +# from __future__ import annotations +from typing import Optional, Annotated +from pydantic import BaseModel, Field, ConfigDict + +ItemName = Annotated[str, Field(description="Наименование товара", min_length=1)] +ItemId = Annotated[int, Field(description="Идентификатор корзины", ge=0)] +ItemPrice = Annotated[float, Field(description="Цена товара", ge=0)] + +CartId = Annotated[int, Field(description="Идентификатор корзины")] + + +# ---- Item ---- +class ItemOut(BaseModel): + id: ItemId + name: ItemName + price: ItemPrice + deleted: bool = Field(description="Удален ли товар", default=False) + + +class ItemCreate(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPut(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPatch(BaseModel): + # Разрешаем частичное обновление ТОЛЬКО name/price; лишние поля → 422 + model_config = ConfigDict(extra="forbid") + + name: Optional[ItemName] = None + price: Optional[ItemPrice] = None + + +# ---- Cart ---- +class CartItemView(BaseModel): + id: ItemId + name: ItemName + quantity: int = Field(description="Количество товара в корзине", ge=0) + available: bool = Field(description="Доступен ли товар") + + +class CartView(BaseModel): + id: int + items: list[CartItemView] + price: float = Field(description="Общая сумма заказа", ge=0.0) diff --git a/hw3_own/shop_api/core/storage.py b/hw3_own/shop_api/core/storage.py new file mode 100644 index 00000000..bc3c6cb9 --- /dev/null +++ b/hw3_own/shop_api/core/storage.py @@ -0,0 +1,142 @@ +from __future__ import annotations +from threading import ( + RLock, +) # стандартная библиотека Python: https://docs.python.org/3/library/threading.html +from typing import Optional +from fastapi import HTTPException, status +from .schemas import ( + ItemOut, + CartItemView, + CartView, + ItemCreate, + ItemPut, + ItemPatch, +) + +# ------------------------- +# In-memory хранилище + блокировки +# ------------------------- +_items_lock = RLock() +_carts_lock = RLock() + +_items: dict[int, ItemOut] = {} +_next_item_id = 1 + +# cart_id -> { item_id -> quantity } +_carts: dict[int, dict[int, int]] = {} +_next_cart_id = 1 + + +def new_item_id() -> int: + global _next_item_id + with _items_lock: + nid = _next_item_id + _next_item_id += 1 + return nid + + +def new_cart_id() -> int: + global _next_cart_id + with _carts_lock: + nid = _next_cart_id + _next_cart_id += 1 + return nid + + +def get_item_or_404(item_id: int) -> ItemOut: + with _items_lock: + item = _items.get(item_id) + if item is None or item.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + return item + + +def get_item_soft(item_id: int) -> Optional[ItemOut]: + with _items_lock: + return _items.get(item_id) + + +def cart_or_404(cart_id: int) -> dict[int, int]: + with _carts_lock: + cart = _carts.get(cart_id) + if cart is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Cart not found" + ) + return cart + + +def build_cart_view(cart_id: int) -> CartView: + with _carts_lock: + cart = _carts.get(cart_id, {}) + kv = list(cart.items()) + + items = [] + total = 0.0 + for item_id, qty in kv: + item = get_item_soft(item_id) + name = item.name if item else f"item:{item_id}" + available = bool(item and not item.deleted) + items.append( + CartItemView(id=item_id, name=name, quantity=qty, available=available) + ) + if available: + total += item.price * qty + + return CartView(id=cart_id, items=items, price=total) + + +def create_item(data: ItemCreate) -> ItemOut: + item_id = new_item_id() + item = ItemOut(id=item_id, name=data.name, price=data.price, deleted=False) + with _items_lock: + _items[item_id] = item + return item + + +def put_item(item_id: int, data: ItemPut) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = data.name + existing.price = data.price + return existing + + +def patch_item(item_id: int, data: ItemPatch) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + # Пробрасываем семантику 304 на верхний уровень + raise HTTPException( + status_code=status.HTTP_304_NOT_MODIFIED, detail="Item deleted" + ) + + if data.name is not None: + existing.name = data.name + if data.price is not None: + if data.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = data.price + + return existing + + +def delete_item(item_id: int) -> dict: + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} diff --git a/hw3_own/shop_api/main.py b/hw3_own/shop_api/main.py new file mode 100644 index 00000000..788a41a9 --- /dev/null +++ b/hw3_own/shop_api/main.py @@ -0,0 +1,25 @@ +from fastapi import FastAPI +from shop_api.routers.item import router as item +from shop_api.routers.cart import router as cart +from shop_api.routers.chat import router as chat +from prometheus_fastapi_instrumentator import Instrumentator + + +app = FastAPI(title="Shop API") + +app.include_router(item) +app.include_router(cart) + +app.include_router(chat) + +Instrumentator().instrument(app).expose( + app, + endpoint="/metrics", + include_in_schema=False, +) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, port=8001) diff --git a/hw3_own/shop_api/routers/cart.py b/hw3_own/shop_api/routers/cart.py new file mode 100644 index 00000000..9e040b6f --- /dev/null +++ b/hw3_own/shop_api/routers/cart.py @@ -0,0 +1,99 @@ +from typing import List, Optional +from fastapi import APIRouter, Query, Response, status + +from shop_api.core.schemas import CartView +from shop_api.core.storage import ( + _carts, + _carts_lock, + new_cart_id, + cart_or_404, + build_cart_view, + get_item_or_404, +) + +router = APIRouter(prefix="/cart", tags=["cart"]) + + +@router.post("", status_code=status.HTTP_201_CREATED) +def create_cart(response: Response): + """ + POST /cart — RPC: создаёт пустую корзину, тело не принимает. + Возвращает 201 и JSON {"id": }, а также заголовок Location: /cart/{id}. + """ + cart_id = new_cart_id() + with _carts_lock: + _carts[cart_id] = {} + response.headers["Location"] = f"/cart/{cart_id}" + return {"id": cart_id} + + +@router.get("/{cart_id}", response_model=CartView) +def get_cart(cart_id: int) -> CartView: + """ + GET /cart/{id} — получить корзину по id. + """ + cart_or_404(cart_id) + return build_cart_view(cart_id) + + +@router.get("", response_model=List[CartView]) +def list_carts( + offset: int = Query(0, ge=0, description="Смещение по списку (offset)"), + limit: int = Query(10, gt=0, description="Лимит количества (limit)"), + min_price: Optional[float] = Query( + None, ge=0.0, description="Мин. сумма корзины (включительно)" + ), + max_price: Optional[float] = Query( + None, ge=0.0, description="Макс. сумма корзины (включительно)" + ), + min_quantity: Optional[int] = Query( + None, ge=0, description="Мин. общее число товаров (включительно)" + ), + max_quantity: Optional[int] = Query( + None, ge=0, description="Макс. общее число товаров (включительно)" + ), +) -> List[CartView]: + """ + GET /cart — список корзин с фильтрами и пагинацией. + + Фильтры: + • min_price/max_price — по суммарной стоимости корзины (включительно); + • min_quantity/max_quantity — по суммарному количеству позиций в корзине (включительно). + Порядок: фильтрация -> offset/limit. + """ + with _carts_lock: + ids = list(_carts.keys()) + + views: List[CartView] = [] + for cid in ids: + v = build_cart_view(cid) + + if min_price is not None and v.price < min_price: + continue + if max_price is not None and v.price > max_price: + continue + + qsum = sum(it.quantity for it in v.items) + if min_quantity is not None and qsum < min_quantity: + continue + if max_quantity is not None and qsum > max_quantity: + continue + + views.append(v) + + return views[offset : offset + limit] + + +@router.post("/{cart_id}/add/{item_id}") +def add_to_cart(cart_id: int, item_id: int): + """ + POST /cart/{cart_id}/add/{item_id} — добавить товар в корзину. + Если товар уже есть — увеличивает его количество. + """ + cart = cart_or_404(cart_id) + get_item_or_404(item_id) # проверка на товар + + with _carts_lock: + cart[item_id] = cart.get(item_id, 0) + 1 + + return {"ok": True} diff --git a/hw3_own/shop_api/routers/chat.py b/hw3_own/shop_api/routers/chat.py new file mode 100644 index 00000000..6c3e1d5e --- /dev/null +++ b/hw3_own/shop_api/routers/chat.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import asyncio +import secrets # стандартная библиотека: https://docs.python.org/3/library/secrets.html +from collections import defaultdict + +from fastapi import APIRouter, WebSocket, WebSocketDisconnect + +router = APIRouter(tags=["chat"]) + + +class RoomManager: + # Решил реализовать в одном файле систему чатов, чтобы проще было проверять + def __init__(self) -> None: + # room -> set of websockets + self.rooms: dict[str, set[WebSocket]] = defaultdict(set) + # websocket -> username + self.usernames: dict[WebSocket, str] = {} + self._lock = asyncio.Lock() + + @staticmethod + def _gen_username() -> str: + # короткий случайный ник + return f"user-{secrets.token_hex(2)}" + + async def connect(self, room: str, ws: WebSocket) -> str: + await ws.accept() + username = self._gen_username() + async with self._lock: + self.rooms[room].add(ws) + self.usernames[ws] = username + await ws.send_text(f"[system] :: your_name = {username}") + return username + + async def disconnect(self, room: str, ws: WebSocket) -> None: + async with self._lock: + self.rooms[room].discard(ws) + self.usernames.pop(ws, None) + if not self.rooms[room]: + self.rooms.pop(room, None) + + async def broadcast( + self, room: str, text: str, sender: WebSocket | None = None + ) -> None: + async with self._lock: + targets = list(self.rooms.get(room, ())) + for ws in targets: + if ws is sender: + continue + try: + await ws.send_text(text) + except Exception: + try: + await self.disconnect(room, ws) + except Exception: + pass + + +manager = RoomManager() + + +@router.websocket("/chat/{chat_name}") +async def chat_ws(websocket: WebSocket, chat_name: str): + """ + Пользователи, подключённые к одному chat_name, получают сообщения друг друга. + Формат сообщения: "{username} :: {message}". + """ + username = await manager.connect(chat_name, websocket) + try: + while True: + # Ждём текст от клиента + msg = await websocket.receive_text() + # Бродкастим другим пользователям в комнате (без эха отправителю) + await manager.broadcast(chat_name, f"{username} :: {msg}", sender=websocket) + except WebSocketDisconnect: + await manager.disconnect(chat_name, websocket) + except Exception: + # Любая иная ошибка закрывает сокет и удаляет из комнаты + await manager.disconnect(chat_name, websocket) + try: + await websocket.close() + except Exception: + pass diff --git a/hw3_own/shop_api/routers/item.py b/hw3_own/shop_api/routers/item.py new file mode 100644 index 00000000..acc511f6 --- /dev/null +++ b/hw3_own/shop_api/routers/item.py @@ -0,0 +1,107 @@ +from typing import List, Optional +from fastapi import APIRouter, HTTPException, Query, Response, status + +from shop_api.core.schemas import ItemOut, ItemCreate, ItemPut, ItemPatch +from shop_api.core.storage import _items, _items_lock, get_item_or_404, new_item_id + +router = APIRouter(prefix="/item", tags=["items"]) + + +@router.post("", status_code=status.HTTP_201_CREATED, response_model=ItemOut) +def create_item(body: ItemCreate) -> ItemOut: + """ + POST /item - добавление нового товара + """ + item_id = new_item_id() + obj = ItemOut(id=item_id, name=body.name, price=body.price, deleted=False) + with _items_lock: + _items[item_id] = obj + return obj + + +@router.get("/{item_id}", response_model=ItemOut) +def get_item(item_id: int) -> ItemOut: + """ + GET /item/{id} - получение товара по id + """ + return get_item_or_404(item_id) + + +@router.get("", response_model=List[ItemOut]) +def list_items( + offset: int = Query(0, ge=0, description="Смещение (offset)"), + limit: int = Query(10, gt=0, description="Количество (limit)"), + min_price: Optional[float] = Query(None, ge=0, description="Мин. цена"), + max_price: Optional[float] = Query(None, ge=0, description="Макс. цена"), + show_deleted: bool = Query(False, description="Показывать ли удалённые"), +) -> List[ItemOut]: + """ + GET /item - получение списка товаров с фильтрами и пагинацией + """ + with _items_lock: + items = list(_items.values()) + + if not show_deleted: + items = [i for i in items if not i.deleted] + if min_price is not None: + items = [i for i in items if i.price >= min_price] + if max_price is not None: + items = [i for i in items if i.price <= max_price] + + return items[offset : offset + limit] + + +@router.put("/{item_id}", response_model=ItemOut) +def put_item(item_id: int, body: ItemPut) -> ItemOut: + """ + PUT /item/{id} - замена товара по id (создание запрещено) + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = body.name + existing.price = body.price + return existing + + +@router.patch("/{item_id}", response_model=ItemOut) +def patch_item(item_id: int, body: ItemPatch): + """ + PATCH /item/{id} - частичное обновление (разрешено менять всё кроме deleted) + Если товар удалён — 304 Not Modified. + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + return Response(status_code=status.HTTP_304_NOT_MODIFIED) + + if body.name is not None: + existing.name = body.name + if body.price is not None: + if body.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = body.price + + return existing + + +@router.delete("/{item_id}") +def delete_item(item_id: int): + """ + DELETE /item/{id} - мягкое удаление (deleted=True), идемпотентно + """ + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} diff --git a/hw3_own/test_homework2.py b/hw3_own/test_homework2.py new file mode 100644 index 00000000..60a1f36a --- /dev/null +++ b/hw3_own/test_homework2.py @@ -0,0 +1,284 @@ +from http import HTTPStatus +from typing import Any +from uuid import uuid4 + +import pytest +from faker import Faker +from fastapi.testclient import TestClient + +from shop_api.main import app + +client = TestClient(app) +faker = Faker() + + +@pytest.fixture() +def existing_empty_cart_id() -> int: + return client.post("/cart").json()["id"] + + +@pytest.fixture(scope="session") +def existing_items() -> list[int]: + items = [ + { + "name": f"Тестовый товар {i}", + "price": faker.pyfloat(positive=True, min_value=10.0, max_value=500.0), + } + for i in range(10) + ] + + return [client.post("/item", json=item).json()["id"] for item in items] + + +@pytest.fixture(scope="session", autouse=True) +def existing_not_empty_carts(existing_items: list[int]) -> list[int]: + carts = [] + + for i in range(20): + cart_id: int = client.post("/cart").json()["id"] + for item_id in faker.random_elements(existing_items, unique=False, length=i): + client.post(f"/cart/{cart_id}/add/{item_id}") + + carts.append(cart_id) + + return carts + + +@pytest.fixture() +def existing_not_empty_cart_id( + existing_empty_cart_id: int, + existing_items: list[int], +) -> int: + for item_id in faker.random_elements(existing_items, unique=False, length=3): + client.post(f"/cart/{existing_empty_cart_id}/add/{item_id}") + + return existing_empty_cart_id + + +@pytest.fixture() +def existing_item() -> dict[str, Any]: + return client.post( + "/item", + json={ + "name": f"Тестовый товар {uuid4().hex}", + "price": faker.pyfloat(min_value=10.0, max_value=100.0), + }, + ).json() + + +@pytest.fixture() +def deleted_item(existing_item: dict[str, Any]) -> dict[str, Any]: + item_id = existing_item["id"] + client.delete(f"/item/{item_id}") + + existing_item["deleted"] = True + return existing_item + + +def test_post_cart() -> None: + response = client.post("/cart") + + assert response.status_code == HTTPStatus.CREATED + assert "location" in response.headers + assert "id" in response.json() + + +@pytest.mark.parametrize( + ("cart", "not_empty"), + [ + ("existing_empty_cart_id", False), + ("existing_not_empty_cart_id", True), + ], +) +def test_get_cart(request, cart: int, not_empty: bool) -> None: + cart_id = request.getfixturevalue(cart) + + response = client.get(f"/cart/{cart_id}") + + assert response.status_code == HTTPStatus.OK + response_json = response.json() + + len_items = len(response_json["items"]) + assert len_items > 0 if not_empty else len_items == 0 + + if not_empty: + price = 0 + + for item in response_json["items"]: + item_id = item["id"] + price += client.get(f"/item/{item_id}").json()["price"] * item["quantity"] + + assert response_json["price"] == pytest.approx(price, 1e-8) + else: + assert response_json["price"] == 0.0 + + +@pytest.mark.parametrize( + ("query", "status_code"), + [ + ({}, HTTPStatus.OK), + ({"offset": 1, "limit": 2}, HTTPStatus.OK), + ({"min_price": 1000.0}, HTTPStatus.OK), + ({"max_price": 20.0}, HTTPStatus.OK), + ({"min_quantity": 1}, HTTPStatus.OK), + ({"max_quantity": 0}, HTTPStatus.OK), + ({"offset": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": 0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_price": -1.0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_price": -1.0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_quantity": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_quantity": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ], +) +def test_get_cart_list(query: dict[str, Any], status_code: int): + response = client.get("/cart", params=query) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + data = response.json() + + assert isinstance(data, list) + + if "min_price" in query: + assert all(item["price"] >= query["min_price"] for item in data) + + if "max_price" in query: + assert all(item["price"] <= query["max_price"] for item in data) + + quantity = sum(item["quantity"] for cart in data for item in cart["items"]) + + if "min_quantity" in query: + assert quantity >= query["min_quantity"] + + if "max_quantity" in query: + assert quantity <= query["max_quantity"] + + +def test_post_item() -> None: + item = {"name": "test item", "price": 9.99} + response = client.post("/item", json=item) + + assert response.status_code == HTTPStatus.CREATED + + data = response.json() + assert item["price"] == data["price"] + assert item["name"] == data["name"] + + +def test_get_item(existing_item: dict[str, Any]) -> None: + item_id = existing_item["id"] + + response = client.get(f"/item/{item_id}") + + assert response.status_code == HTTPStatus.OK + assert response.json() == existing_item + + +@pytest.mark.parametrize( + ("query", "status_code"), + [ + ({"offset": 2, "limit": 5}, HTTPStatus.OK), + ({"min_price": 5.0}, HTTPStatus.OK), + ({"max_price": 5.0}, HTTPStatus.OK), + ({"show_deleted": True}, HTTPStatus.OK), + ({"offset": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": 0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_price": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_price": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ], +) +def test_get_item_list(query: dict[str, Any], status_code: int) -> None: + response = client.get("/item", params=query) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + data = response.json() + + assert isinstance(data, list) + + if "min_price" in query: + assert all(item["price"] >= query["min_price"] for item in data) + + if "max_price" in query: + assert all(item["price"] <= query["max_price"] for item in data) + + if "show_deleted" in query and query["show_deleted"] is False: + assert all(item["deleted"] is False for item in data) + + +@pytest.mark.parametrize( + ("body", "status_code"), + [ + ({}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"price": 9.99}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"name": "new name", "price": 9.99}, HTTPStatus.OK), + ], +) +def test_put_item( + existing_item: dict[str, Any], + body: dict[str, Any], + status_code: int, +) -> None: + item_id = existing_item["id"] + response = client.put(f"/item/{item_id}", json=body) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + new_item = existing_item.copy() + new_item.update(body) + assert response.json() == new_item + + +@pytest.mark.parametrize( + ("item", "body", "status_code"), + [ + ("deleted_item", {}, HTTPStatus.NOT_MODIFIED), + ("deleted_item", {"price": 9.99}, HTTPStatus.NOT_MODIFIED), + ("deleted_item", {"name": "new name", "price": 9.99}, HTTPStatus.NOT_MODIFIED), + ("existing_item", {}, HTTPStatus.OK), + ("existing_item", {"price": 9.99}, HTTPStatus.OK), + ("existing_item", {"name": "new name", "price": 9.99}, HTTPStatus.OK), + ( + "existing_item", + {"name": "new name", "price": 9.99, "odd": "value"}, + HTTPStatus.UNPROCESSABLE_ENTITY, + ), + ( + "existing_item", + {"name": "new name", "price": 9.99, "deleted": True}, + HTTPStatus.UNPROCESSABLE_ENTITY, + ), + ], +) +def test_patch_item(request, item: str, body: dict[str, Any], status_code: int) -> None: + item_data: dict[str, Any] = request.getfixturevalue(item) + item_id = item_data["id"] + response = client.patch(f"/item/{item_id}", json=body) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + patch_response_body = response.json() + + response = client.get(f"/item/{item_id}") + patched_item = response.json() + + assert patched_item == patch_response_body + + +def test_delete_item(existing_item: dict[str, Any]) -> None: + item_id = existing_item["id"] + + response = client.delete(f"/item/{item_id}") + assert response.status_code == HTTPStatus.OK + + response = client.get(f"/item/{item_id}") + assert response.status_code == HTTPStatus.NOT_FOUND + + response = client.delete(f"/item/{item_id}") + assert response.status_code == HTTPStatus.OK diff --git a/hw3_own/test_websocket_chat.py b/hw3_own/test_websocket_chat.py new file mode 100644 index 00000000..248e7625 --- /dev/null +++ b/hw3_own/test_websocket_chat.py @@ -0,0 +1,60 @@ +import re +from fastapi.testclient import TestClient + +from shop_api.main import app + +USERNAME_RE = re.compile(r"^\[system\] :: your_name = (user-[0-9a-f]{4})$") + + +def _extract_username(system_msg: str) -> str: + """ + Из приветственного сообщения вида: + "[system] :: your_name = user-ab12" + достаём "user-ab12". + """ + m = USERNAME_RE.match(system_msg) + assert m, f"unexpected system greeting format: {system_msg!r}" + return m.group(1) + + +def test_websocket_broadcast_and_format(): + client = TestClient(app) + + # Подключаем двух пользователей к одной комнате и третьего — к другой + with ( + client.websocket_connect("/chat/room1") as ws1, + client.websocket_connect("/chat/room1") as ws2, + client.websocket_connect("/chat/room2") as ws3, + ): + # Приветственные сообщения с именами + u1 = _extract_username(ws1.receive_text()) + u2 = _extract_username(ws2.receive_text()) + u3 = _extract_username(ws3.receive_text()) + assert u1 != u2 and u1 != u3 and u2 != u3 # имена случайные и разные + + # user1 -> room1 + msg1 = "hello from 1" + ws1.send_text(msg1) + + # Должно прийти ТОЛЬКО второму участнику той же комнаты + got2 = ws2.receive_text() + assert got2 == f"{u1} :: {msg1}" + + # user3 -> room2 (не должен мешать room1) + ws3.send_text("ping from 3") + + # user2 -> room1 + msg2 = "hi from 2" + ws2.send_text(msg2) + + # Должно прийти первому участнику room1 + got1 = ws1.receive_text() + assert got1 == f"{u2} :: {msg2}" + + +def test_websocket_username_greeting_format(): + client = TestClient(app) + with client.websocket_connect("/chat/any-room") as ws: + greet = ws.receive_text() + # Проверяем точный формат приветствия и шаблон username + assert USERNAME_RE.match(greet), f"bad greeting: {greet!r}" From 76c11ddf52e80e87af64256e342c4df427ce4c96 Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Mon, 13 Oct 2025 02:01:04 +0300 Subject: [PATCH 5/9] =?UTF-8?q?=D0=A0=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20HW4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw4_own/.dockignore | 12 +++ hw4_own/Dockerfile | 15 ++++ hw4_own/README.md | 13 +++ hw4_own/__init__.py | 0 hw4_own/data/shop.db | Bin 0 -> 20480 bytes hw4_own/docker-compose.yml | 13 +++ hw4_own/requirements_hw4.txt | 12 +++ hw4_own/shop_api/__init__.py | 0 hw4_own/shop_api/core/db.py | 39 +++++++++ hw4_own/shop_api/core/models.py | 44 ++++++++++ hw4_own/shop_api/core/schemas.py | 49 +++++++++++ hw4_own/shop_api/core/storage.py | 137 +++++++++++++++++++++++++++++++ hw4_own/shop_api/main.py | 24 ++++++ hw4_own/shop_api/routers/cart.py | 76 +++++++++++++++++ hw4_own/shop_api/routers/chat.py | 83 +++++++++++++++++++ hw4_own/shop_api/routers/item.py | 79 ++++++++++++++++++ 16 files changed, 596 insertions(+) create mode 100644 hw4_own/.dockignore create mode 100644 hw4_own/Dockerfile create mode 100644 hw4_own/README.md create mode 100644 hw4_own/__init__.py create mode 100644 hw4_own/data/shop.db create mode 100644 hw4_own/docker-compose.yml create mode 100644 hw4_own/requirements_hw4.txt create mode 100644 hw4_own/shop_api/__init__.py create mode 100644 hw4_own/shop_api/core/db.py create mode 100644 hw4_own/shop_api/core/models.py create mode 100644 hw4_own/shop_api/core/schemas.py create mode 100644 hw4_own/shop_api/core/storage.py create mode 100644 hw4_own/shop_api/main.py create mode 100644 hw4_own/shop_api/routers/cart.py create mode 100644 hw4_own/shop_api/routers/chat.py create mode 100644 hw4_own/shop_api/routers/item.py diff --git a/hw4_own/.dockignore b/hw4_own/.dockignore new file mode 100644 index 00000000..3d100150 --- /dev/null +++ b/hw4_own/.dockignore @@ -0,0 +1,12 @@ +__pycache__/ +*.pyc +*.pyo +*.pyd +*.sqlite3 +*.db +.env +.venv/ +.git/ +.gitignore +data/ +tests/.pytest_cache/ diff --git a/hw4_own/Dockerfile b/hw4_own/Dockerfile new file mode 100644 index 00000000..40472257 --- /dev/null +++ b/hw4_own/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.12-slim + +WORKDIR /api + +RUN apt-get update -y + +COPY requirements_hw4.txt requirements.txt + +RUN pip install -r requirements.txt + +COPY . /api + +RUN mkdir -p /api/data && chmod -R 0777 /api/data + +ENTRYPOINT ["uvicorn", "shop_api.main:app", "--host", "0.0.0.0", "--port", "8080"] diff --git a/hw4_own/README.md b/hw4_own/README.md new file mode 100644 index 00000000..aad28c54 --- /dev/null +++ b/hw4_own/README.md @@ -0,0 +1,13 @@ +# ДЗ + +## Настроить сборку образов Docker и мониторинг с помощью Prometheus и Grafana + +Интегрировать Docker с Prometheus и Grafana в любой уже написанный в ДЗ сервис (по аналогии с тем, как в репе) + +По сути, если вы выполнили вторую домашку, то теперь для неё надо написать Dockerfile и настроить мониторинг. Если вторую домашку вы не делали, то можно взять сервис из [rest_example](../hw2/rest_example/main.py) + +Сдача через PR, так же нужно: + +1) Dockerfile для сборки сервиса +2) docker-compose.yml для локального разворачивания в Docker +3) Приложить скрин с парой Дашбордов в Grafana diff --git a/hw4_own/__init__.py b/hw4_own/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw4_own/data/shop.db b/hw4_own/data/shop.db new file mode 100644 index 0000000000000000000000000000000000000000..9b9a3802919cc67240305d651401645d9c8c5884 GIT binary patch literal 20480 zcmeI%O>Wab6bJBe;-rbA#Oy3~FS}T(Ku~p$>rO(18B-^z)Kz2}gDmBvi5-b{*GgQ7 z3%~)m02kl_h$RwZlMjd1Yee+7$1PLv#KE6JuhFB}+# zq1@IstCcQPRJ^xFass)_^S7jC-nNu9@!iujaXN$ar?8WFHM88rQ-2cBx#ig}EwA6W4XPC3fE3A8K7Pl=V+c|Dk`^zv*A~&oaOT z0SG_<0uX=z1Rwwb2tWV=5P-lx7O0g=>~Wz{}fB*y_009U<00Izz00bbg#{xM2@A2YdY7l?`1Rwwb2tWV=5P$##AOL}tfR;S* d{U7@Q0uX=z1Rwwb2tWV=5P$##Ah6d0zX1)3=0.117.1 +uvicorn>=0.24.0 +websockets>=15.0.1 +SQLAlchemy>=2.0.30 +aiosqlite>=0.20.0 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw4_own/shop_api/__init__.py b/hw4_own/shop_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw4_own/shop_api/core/db.py b/hw4_own/shop_api/core/db.py new file mode 100644 index 00000000..11b9f2a9 --- /dev/null +++ b/hw4_own/shop_api/core/db.py @@ -0,0 +1,39 @@ +from contextlib import asynccontextmanager +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import ( + AsyncEngine, + AsyncSession, + async_sessionmaker, + create_async_engine, +) +from sqlalchemy.orm import DeclarativeBase +import os + +DATABASE_URL = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///./data/shop.db") + + +class Base(DeclarativeBase): + pass + + +def make_engine(url: str = DATABASE_URL) -> AsyncEngine: + # echo=True for debug + return create_async_engine(url, future=True, echo=False) + + +engine: AsyncEngine = make_engine() +async_session: async_sessionmaker[AsyncSession] = async_sessionmaker( + bind=engine, expire_on_commit=False +) + + +@asynccontextmanager +async def lifespan_session() -> AsyncGenerator[AsyncSession, None]: + async with async_session() as session: + yield session + + +async def get_session() -> AsyncGenerator[AsyncSession, None]: + async with async_session() as session: + yield session diff --git a/hw4_own/shop_api/core/models.py b/hw4_own/shop_api/core/models.py new file mode 100644 index 00000000..74ecb5f1 --- /dev/null +++ b/hw4_own/shop_api/core/models.py @@ -0,0 +1,44 @@ +from sqlalchemy import Boolean, Float, ForeignKey, Integer, String, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from .db import Base + + +class Item(Base): + __tablename__ = "items" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + name: Mapped[str] = mapped_column(String(255), nullable=False) + price: Mapped[float] = mapped_column(Float, nullable=False) + deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) + + cart_links: Mapped[list["CartItem"]] = relationship( + back_populates="item", cascade="all, delete-orphan" + ) + + +class Cart(Base): + __tablename__ = "carts" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + + items: Mapped[list["CartItem"]] = relationship( + back_populates="cart", cascade="all, delete-orphan" + ) + + +class CartItem(Base): + __tablename__ = "cart_items" + __table_args__ = (UniqueConstraint("cart_id", "item_id", name="uq_cart_item"),) + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + cart_id: Mapped[int] = mapped_column( + ForeignKey("carts.id", ondelete="CASCADE"), nullable=False + ) + item_id: Mapped[int] = mapped_column( + ForeignKey("items.id", ondelete="CASCADE"), nullable=False + ) + quantity: Mapped[int] = mapped_column(Integer, nullable=False, default=0) + + cart: Mapped["Cart"] = relationship(back_populates="items") + item: Mapped["Item"] = relationship(back_populates="cart_links") diff --git a/hw4_own/shop_api/core/schemas.py b/hw4_own/shop_api/core/schemas.py new file mode 100644 index 00000000..f7547e01 --- /dev/null +++ b/hw4_own/shop_api/core/schemas.py @@ -0,0 +1,49 @@ +# from __future__ import annotations +from typing import Optional, Annotated +from pydantic import BaseModel, Field, ConfigDict + +ItemName = Annotated[str, Field(description="Наименование товара", min_length=1)] +ItemId = Annotated[int, Field(description="Идентификатор корзины", ge=0)] +ItemPrice = Annotated[float, Field(description="Цена товара", ge=0)] + +CartId = Annotated[int, Field(description="Идентификатор корзины")] + + +# ---- Item ---- +class ItemOut(BaseModel): + id: ItemId + name: ItemName + price: ItemPrice + deleted: bool = Field(description="Удален ли товар", default=False) + + +class ItemCreate(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPut(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPatch(BaseModel): + # Разрешаем частичное обновление ТОЛЬКО name/price; лишние поля → 422 + model_config = ConfigDict(extra="forbid") + + name: Optional[ItemName] = None + price: Optional[ItemPrice] = None + + +# ---- Cart ---- +class CartItemView(BaseModel): + id: ItemId + name: ItemName + quantity: int = Field(description="Количество товара в корзине", ge=0) + available: bool = Field(description="Доступен ли товар") + + +class CartView(BaseModel): + id: int + items: list[CartItemView] + price: float = Field(description="Общая сумма заказа", ge=0.0) diff --git a/hw4_own/shop_api/core/storage.py b/hw4_own/shop_api/core/storage.py new file mode 100644 index 00000000..992bfc94 --- /dev/null +++ b/hw4_own/shop_api/core/storage.py @@ -0,0 +1,137 @@ +from typing import Optional + +from fastapi import HTTPException, status +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from .schemas import ItemOut, CartItemView, CartView, ItemCreate, ItemPut, ItemPatch +from .models import Item, Cart, CartItem + + +# ---- Item helpers ---- +async def create_item(session: AsyncSession, data: ItemCreate) -> ItemOut: + item = Item(name=data.name, price=data.price, deleted=False) + session.add(item) + await session.flush() # populate PK + return ItemOut(id=item.id, name=item.name, price=item.price, deleted=item.deleted) + + +async def get_item_or_404(session: AsyncSession, item_id: int) -> Item: + result = await session.execute(select(Item).where(Item.id == item_id)) + item = result.scalar_one_or_none() + if item is None or item.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + return item + + +async def get_item_soft(session: AsyncSession, item_id: int) -> Optional[Item]: + result = await session.execute(select(Item).where(Item.id == item_id)) + return result.scalar_one_or_none() + + +async def put_item(session: AsyncSession, item_id: int, data: ItemPut) -> ItemOut: + item = await get_item_or_404(session, item_id) + item.name = data.name + item.price = data.price + await session.flush() + return ItemOut(id=item.id, name=item.name, price=item.price, deleted=item.deleted) + + +async def patch_item(session: AsyncSession, item_id: int, data: ItemPatch) -> ItemOut: + result = await session.execute(select(Item).where(Item.id == item_id)) + item = result.scalar_one_or_none() + if item is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if item.deleted: + raise HTTPException( + status_code=status.HTTP_304_NOT_MODIFIED, detail="Item deleted" + ) + + if data.name is not None: + item.name = data.name + if data.price is not None: + if data.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + item.price = data.price + + await session.flush() + return ItemOut(id=item.id, name=item.name, price=item.price, deleted=item.deleted) + + +async def delete_item(session: AsyncSession, item_id: int) -> dict: + result = await session.execute(select(Item).where(Item.id == item_id)) + item = result.scalar_one_or_none() + if item is not None: + item.deleted = True + await session.flush() + return {"ok": True} + + +# ---- Cart helpers ---- +async def cart_or_404(session: AsyncSession, cart_id: int) -> Cart: + result = await session.execute(select(Cart).where(Cart.id == cart_id)) + cart = result.scalar_one_or_none() + if cart is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Cart not found" + ) + return cart + + +async def create_cart(session: AsyncSession) -> int: + cart = Cart() + session.add(cart) + await session.flush() + return cart.id + + +async def add_to_cart(session: AsyncSession, cart_id: int, item_id: int) -> None: + # Check cart and item exist (item must not be deleted) + await cart_or_404(session, cart_id) + await get_item_or_404(session, item_id) + + # Find existing link + result = await session.execute( + select(CartItem).where(CartItem.cart_id == cart_id, CartItem.item_id == item_id) + ) + link = result.scalar_one_or_none() + if link is None: + link = CartItem(cart_id=cart_id, item_id=item_id, quantity=1) + session.add(link) + else: + link.quantity += 1 + await session.flush() + + +async def build_cart_view(session: AsyncSession, cart_id: int) -> CartView: + cart = await cart_or_404(session, cart_id) + + # Load links with joined items + result = await session.execute( + select(CartItem, Item) + .join(Item, CartItem.item_id == Item.id) + .where(CartItem.cart_id == cart.id) + ) + rows = result.all() + + items = [] + total = 0.0 + for link, item in rows: + name = item.name + available = not item.deleted + items.append( + CartItemView( + id=item.id, name=name, quantity=link.quantity, available=available + ) + ) + if available: + total += item.price * link.quantity + + return CartView(id=cart.id, items=items, price=total) diff --git a/hw4_own/shop_api/main.py b/hw4_own/shop_api/main.py new file mode 100644 index 00000000..7d916092 --- /dev/null +++ b/hw4_own/shop_api/main.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from fastapi import FastAPI + +from shop_api.core.db import Base, engine +from shop_api.routers.item import router as item +from shop_api.routers.cart import router as cart +from shop_api.routers.chat import router as chat + +app = FastAPI(title="Shop API (SQLAlchemy + SQLite)") + +@app.on_event("startup") +async def on_startup() -> None: + # Create tables if they don't exist + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + +app.include_router(item) +app.include_router(cart) +app.include_router(chat) + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, port=8001) diff --git a/hw4_own/shop_api/routers/cart.py b/hw4_own/shop_api/routers/cart.py new file mode 100644 index 00000000..2a45bb34 --- /dev/null +++ b/hw4_own/shop_api/routers/cart.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from typing import List, Optional + +from fastapi import APIRouter, Depends, Query, Response, status +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from shop_api.core.schemas import CartView +from shop_api.core.db import get_session +from shop_api.core.models import Cart +from shop_api.core import storage as crud + +router = APIRouter(prefix="/cart", tags=["cart"]) + + +@router.post("", status_code=status.HTTP_201_CREATED) +async def create_cart(response: Response, session: AsyncSession = Depends(get_session)): + cart_id = await crud.create_cart(session) + await session.commit() + response.headers["Location"] = f"/cart/{cart_id}" + return {"id": cart_id} + + +@router.get("/{cart_id}", response_model=CartView) +async def get_cart(cart_id: int, session: AsyncSession = Depends(get_session)) -> CartView: + return await crud.build_cart_view(session, cart_id) + + +@router.get("", response_model=List[CartView]) +async def list_carts( + offset: int = Query(0, ge=0, description="Смещение по списку (offset)"), + limit: int = Query(10, gt=0, description="Лимит количества (limit)"), + min_price: Optional[float] = Query( + None, ge=0.0, description="Мин. сумма корзины (включительно)" + ), + max_price: Optional[float] = Query( + None, ge=0.0, description="Макс. сумма корзины (включительно)" + ), + min_quantity: Optional[int] = Query( + None, ge=0, description="Мин. общее число товаров (включительно)" + ), + max_quantity: Optional[int] = Query( + None, ge=0, description="Макс. общее число товаров (включительно)" + ), + session: AsyncSession = Depends(get_session), +) -> List[CartView]: + # First gather candidate cart ids + res = await session.execute(select(Cart.id)) + ids = [row[0] for row in res.all()] + + views: List[CartView] = [] + for cid in ids: + v = await crud.build_cart_view(session, cid) + + if min_price is not None and v.price < min_price: + continue + if max_price is not None and v.price > max_price: + continue + + qsum = sum(it.quantity for it in v.items) + if min_quantity is not None and qsum < min_quantity: + continue + if max_quantity is not None and qsum > max_quantity: + continue + + views.append(v) + + return views[offset : offset + limit] + + +@router.post("/{cart_id}/add/{item_id}") +async def add_to_cart(cart_id: int, item_id: int, session: AsyncSession = Depends(get_session)): + await crud.add_to_cart(session, cart_id, item_id) + await session.commit() + return {"ok": True} diff --git a/hw4_own/shop_api/routers/chat.py b/hw4_own/shop_api/routers/chat.py new file mode 100644 index 00000000..6c3e1d5e --- /dev/null +++ b/hw4_own/shop_api/routers/chat.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import asyncio +import secrets # стандартная библиотека: https://docs.python.org/3/library/secrets.html +from collections import defaultdict + +from fastapi import APIRouter, WebSocket, WebSocketDisconnect + +router = APIRouter(tags=["chat"]) + + +class RoomManager: + # Решил реализовать в одном файле систему чатов, чтобы проще было проверять + def __init__(self) -> None: + # room -> set of websockets + self.rooms: dict[str, set[WebSocket]] = defaultdict(set) + # websocket -> username + self.usernames: dict[WebSocket, str] = {} + self._lock = asyncio.Lock() + + @staticmethod + def _gen_username() -> str: + # короткий случайный ник + return f"user-{secrets.token_hex(2)}" + + async def connect(self, room: str, ws: WebSocket) -> str: + await ws.accept() + username = self._gen_username() + async with self._lock: + self.rooms[room].add(ws) + self.usernames[ws] = username + await ws.send_text(f"[system] :: your_name = {username}") + return username + + async def disconnect(self, room: str, ws: WebSocket) -> None: + async with self._lock: + self.rooms[room].discard(ws) + self.usernames.pop(ws, None) + if not self.rooms[room]: + self.rooms.pop(room, None) + + async def broadcast( + self, room: str, text: str, sender: WebSocket | None = None + ) -> None: + async with self._lock: + targets = list(self.rooms.get(room, ())) + for ws in targets: + if ws is sender: + continue + try: + await ws.send_text(text) + except Exception: + try: + await self.disconnect(room, ws) + except Exception: + pass + + +manager = RoomManager() + + +@router.websocket("/chat/{chat_name}") +async def chat_ws(websocket: WebSocket, chat_name: str): + """ + Пользователи, подключённые к одному chat_name, получают сообщения друг друга. + Формат сообщения: "{username} :: {message}". + """ + username = await manager.connect(chat_name, websocket) + try: + while True: + # Ждём текст от клиента + msg = await websocket.receive_text() + # Бродкастим другим пользователям в комнате (без эха отправителю) + await manager.broadcast(chat_name, f"{username} :: {msg}", sender=websocket) + except WebSocketDisconnect: + await manager.disconnect(chat_name, websocket) + except Exception: + # Любая иная ошибка закрывает сокет и удаляет из комнаты + await manager.disconnect(chat_name, websocket) + try: + await websocket.close() + except Exception: + pass diff --git a/hw4_own/shop_api/routers/item.py b/hw4_own/shop_api/routers/item.py new file mode 100644 index 00000000..8e794adb --- /dev/null +++ b/hw4_own/shop_api/routers/item.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from typing import List, Optional + +from fastapi import APIRouter, Depends, HTTPException, Query, Response, status +from sqlalchemy import Select, and_, select +from sqlalchemy.ext.asyncio import AsyncSession + +from shop_api.core.schemas import ItemOut, ItemCreate, ItemPut, ItemPatch +from shop_api.core.db import get_session +from shop_api.core.models import Item +from shop_api.core import storage as crud + +router = APIRouter(prefix="/item", tags=["items"]) + + +@router.post("", status_code=status.HTTP_201_CREATED, response_model=ItemOut) +async def create_item(body: ItemCreate, session: AsyncSession = Depends(get_session)) -> ItemOut: + obj = await crud.create_item(session, body) + await session.commit() + return obj + + +@router.get("/{item_id}", response_model=ItemOut) +async def get_item(item_id: int, session: AsyncSession = Depends(get_session)) -> ItemOut: + item = await crud.get_item_or_404(session, item_id) + return ItemOut(id=item.id, name=item.name, price=item.price, deleted=item.deleted) + + +@router.get("", response_model=List[ItemOut]) +async def list_items( + offset: int = Query(0, ge=0, description="Смещение (offset)"), + limit: int = Query(10, gt=0, description="Количество (limit)"), + min_price: Optional[float] = Query(None, ge=0, description="Мин. цена"), + max_price: Optional[float] = Query(None, ge=0, description="Макс. цена"), + show_deleted: bool = Query(False, description="Показывать ли удалённые"), + session: AsyncSession = Depends(get_session), +) -> List[ItemOut]: + stmt: Select = select(Item) + conds = [] + if not show_deleted: + conds.append(Item.deleted.is_(False)) + if min_price is not None: + conds.append(Item.price >= min_price) + if max_price is not None: + conds.append(Item.price <= max_price) + if conds: + stmt = stmt.where(and_(*conds)) + stmt = stmt.offset(offset).limit(limit) + + res = await session.execute(stmt) + items = res.scalars().all() + return [ItemOut(id=i.id, name=i.name, price=i.price, deleted=i.deleted) for i in items] + + +@router.put("/{item_id}", response_model=ItemOut) +async def put_item(item_id: int, body: ItemPut, session: AsyncSession = Depends(get_session)) -> ItemOut: + obj = await crud.put_item(session, item_id, body) + await session.commit() + return obj + + +@router.patch("/{item_id}", response_model=ItemOut) +async def patch_item(item_id: int, body: ItemPatch, session: AsyncSession = Depends(get_session)): + try: + obj = await crud.patch_item(session, item_id, body) + except HTTPException as e: + if e.status_code == status.HTTP_304_NOT_MODIFIED: + return Response(status_code=status.HTTP_304_NOT_MODIFIED) + raise + await session.commit() + return obj + + +@router.delete("/{item_id}") +async def delete_item(item_id: int, session: AsyncSession = Depends(get_session)): + result = await crud.delete_item(session, item_id) + await session.commit() + return result From de01dbee1cb1c40ac3b6716e658f38842a4acf0f Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Mon, 13 Oct 2025 02:05:17 +0300 Subject: [PATCH 6/9] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20README.md=20=D0=B2=20HW4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw4_own/README.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/hw4_own/README.md b/hw4_own/README.md index aad28c54..26822ef7 100644 --- a/hw4_own/README.md +++ b/hw4_own/README.md @@ -1,13 +1,15 @@ -# ДЗ - -## Настроить сборку образов Docker и мониторинг с помощью Prometheus и Grafana - -Интегрировать Docker с Prometheus и Grafana в любой уже написанный в ДЗ сервис (по аналогии с тем, как в репе) - -По сути, если вы выполнили вторую домашку, то теперь для неё надо написать Dockerfile и настроить мониторинг. Если вторую домашку вы не делали, то можно взять сервис из [rest_example](../hw2/rest_example/main.py) - -Сдача через PR, так же нужно: - -1) Dockerfile для сборки сервиса -2) docker-compose.yml для локального разворачивания в Docker -3) Приложить скрин с парой Дашбордов в Grafana +## ДЗ + +За каждый пункт - 1 балл + +Внедрить во вторую домашку хранение данных в БД, для этого надо: +1) Добавить БД в docket-compose.yml (если БД - это отдельный сервис, если хотите использовать sqlite, то можно скипнуть этот шаг) +2) Переписать код на взаимодействие с вашей БД (если вы еще этого не сделали, если вы уже написали код с БД, подзравляю, вам остался только 3 пункт) +3) В свободной форме, напишите скрипты, которые просимулируют разные "проблемы" которые могут возникнуть в транзакциях (dirty read, not-repeatable read, serialize) и настраивая уровне изоляции покажите, что они действительно решаются (через SQLAlchemy например), то есть: +показать dirty read при read uncommited +показать что нет dirty read при read commited +показать non-repeatable read при read commited +показать что нет non-repeatable read при repeatable read +показать phantom reads при repeatable read +показать что нет phantom reads при serializable +*Тут зависит от того какую БД вы выбрали, разные БД могут поддерживать разные уровни изоляции \ No newline at end of file From e3a2d0fb502e713009f8463c7512b2646a112db0 Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sat, 25 Oct 2025 04:26:58 +0300 Subject: [PATCH 7/9] Added HW5 --- .github/workflows/hw5-tests.yml | 39 +++ hw5_own/Dockerfile | 13 + hw5_own/README.md | 5 + hw5_own/__init__.py | 0 hw5_own/docker-compose.yml | 34 +++ hw5_own/docs/dashboard_1.png | Bin 0 -> 72928 bytes hw5_own/docs/dashboard_2.png | Bin 0 -> 109184 bytes hw5_own/pytest.ini | 4 + hw5_own/requirements.txt | 9 + hw5_own/requirements_hw3.txt | 11 + .../provisioning/dashboards/dashboards.yml | 8 + .../dashboards/shop_api_overview.json | 66 ++++ .../dashboards/shop_api_routes.json | 51 ++++ .../provisioning/datasources/datasource.yml | 8 + hw5_own/settings/prometheus/prometheus.yml | 10 + hw5_own/shop_api/__init__.py | 0 hw5_own/shop_api/core/schemas.py | 49 +++ hw5_own/shop_api/core/storage.py | 142 +++++++++ hw5_own/shop_api/main.py | 25 ++ hw5_own/shop_api/routers/cart.py | 99 ++++++ hw5_own/shop_api/routers/chat.py | 83 +++++ hw5_own/shop_api/routers/item.py | 107 +++++++ hw5_own/test_homework5.py | 284 ++++++++++++++++++ hw5_own/test_websocket_chat.py | 60 ++++ 24 files changed, 1107 insertions(+) create mode 100644 .github/workflows/hw5-tests.yml create mode 100644 hw5_own/Dockerfile create mode 100644 hw5_own/README.md create mode 100644 hw5_own/__init__.py create mode 100644 hw5_own/docker-compose.yml create mode 100644 hw5_own/docs/dashboard_1.png create mode 100644 hw5_own/docs/dashboard_2.png create mode 100644 hw5_own/pytest.ini create mode 100644 hw5_own/requirements.txt create mode 100644 hw5_own/requirements_hw3.txt create mode 100644 hw5_own/settings/grafana/provisioning/dashboards/dashboards.yml create mode 100644 hw5_own/settings/grafana/provisioning/dashboards/shop_api_overview.json create mode 100644 hw5_own/settings/grafana/provisioning/dashboards/shop_api_routes.json create mode 100644 hw5_own/settings/grafana/provisioning/datasources/datasource.yml create mode 100644 hw5_own/settings/prometheus/prometheus.yml create mode 100644 hw5_own/shop_api/__init__.py create mode 100644 hw5_own/shop_api/core/schemas.py create mode 100644 hw5_own/shop_api/core/storage.py create mode 100644 hw5_own/shop_api/main.py create mode 100644 hw5_own/shop_api/routers/cart.py create mode 100644 hw5_own/shop_api/routers/chat.py create mode 100644 hw5_own/shop_api/routers/item.py create mode 100644 hw5_own/test_homework5.py create mode 100644 hw5_own/test_websocket_chat.py diff --git a/.github/workflows/hw5-tests.yml b/.github/workflows/hw5-tests.yml new file mode 100644 index 00000000..1094edf8 --- /dev/null +++ b/.github/workflows/hw5-tests.yml @@ -0,0 +1,39 @@ +name: "HW5 Tests" + +on: + pull_request: + branches: [ main ] + paths: [ 'hw5_own/**' ] + push: + branches: [ main ] + paths: [ 'hw5_own/**' ] + +jobs: + test-hw2: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.12", "3.13"] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + working-directory: hw5_own + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run tests + working-directory: hw5_own + env: + PYTHONPATH: ${{ github.workspace }}/hw5_own + run: | + pytest test_homework5.py -v + pytest test_websocket_chat.py -v diff --git a/hw5_own/Dockerfile b/hw5_own/Dockerfile new file mode 100644 index 00000000..2e62a48a --- /dev/null +++ b/hw5_own/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.12-slim + +WORKDIR /api + +RUN apt-get update -y + +COPY requirements_hw3.txt requirements.txt + +RUN pip install -r requirements.txt + +COPY . . + +ENTRYPOINT ["uvicorn", "shop_api.main:app", "--host", "0.0.0.0", "--port", "8080"] diff --git a/hw5_own/README.md b/hw5_own/README.md new file mode 100644 index 00000000..33e79328 --- /dev/null +++ b/hw5_own/README.md @@ -0,0 +1,5 @@ +# ДЗ + +1) Добиться 95% покрытия тестами вашей второй домашки - 1 балл + +2) Настроить автозапуск этих тестов в CI, если вы подключали сторонюю БД, то можно посмотреть вот [сюда](https://dev.to/kashifsoofi/integration-test-postgres-using-github-actions-3lln), чтобы поддержать тесты с ней в CI. По итогу у вас должен получится зеленый пайплайн - оценивается в еще 2 балла. diff --git a/hw5_own/__init__.py b/hw5_own/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw5_own/docker-compose.yml b/hw5_own/docker-compose.yml new file mode 100644 index 00000000..e6c0dab1 --- /dev/null +++ b/hw5_own/docker-compose.yml @@ -0,0 +1,34 @@ +services: + server: + build: + context: . + restart: always + ports: + - 8080:8080 + + grafana: + image: grafana/grafana:latest + ports: + - 3000:3000 + restart: always + volumes: + - ./settings/grafana/provisioning:/etc/grafana/provisioning + depends_on: + - prometheus + + + prometheus: + image: prom/prometheus:latest + volumes: + - ./settings/prometheus:/etc/prometheus + + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/usr/share/prometheus/console_libraries" + - "--web.console.templates=/usr/share/prometheus/consoles" + ports: + - 9090:9090 + restart: always + depends_on: + - server diff --git a/hw5_own/docs/dashboard_1.png b/hw5_own/docs/dashboard_1.png new file mode 100644 index 0000000000000000000000000000000000000000..12b7a4b13b5798739ba49296bd5137ce041c4d2a GIT binary patch literal 72928 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�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

4j+k&k9J5#Ey*2?i`8#Gn#B_*$lX02=X_H4 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 SMLkw~G%AXkPfO%2-u@3Z;8fWF literal 0 HcmV?d00001 diff --git a/hw5_own/docs/dashboard_2.png b/hw5_own/docs/dashboard_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4c249b975ae2faa32d2c70aa6d0a3a573431492b GIT binary patch literal 109184 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

)~u%{6F`#jzW7O8lV|I&4AP#%B(_$L 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 literal 0 HcmV?d00001 diff --git a/hw5_own/pytest.ini b/hw5_own/pytest.ini new file mode 100644 index 00000000..6fc8c304 --- /dev/null +++ b/hw5_own/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +addopts = -ra --cov=hw5_own --cov-report=term-missing --cov-report=xml:reports/coverage.xml --cov-fail-under=90 +testpaths = hw4_own/tests +python_files = test_*.py diff --git a/hw5_own/requirements.txt b/hw5_own/requirements.txt new file mode 100644 index 00000000..207dcf5c --- /dev/null +++ b/hw5_own/requirements.txt @@ -0,0 +1,9 @@ +# Основные зависимости для ASGI приложения +fastapi>=0.117.1 +uvicorn>=0.24.0 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw5_own/requirements_hw3.txt b/hw5_own/requirements_hw3.txt new file mode 100644 index 00000000..1593e6d3 --- /dev/null +++ b/hw5_own/requirements_hw3.txt @@ -0,0 +1,11 @@ +# Основные зависимости для ASGI приложения +fastapi>=0.117.1 +uvicorn>=0.24.0 +websockets>=15.0.1 +prometheus_fastapi_instrumentator>=7.1.0 + +# Зависимости для тестирования +pytest>=7.4.0 +pytest-asyncio>=0.21.0 +httpx>=0.27.2 +Faker>=37.8.0 diff --git a/hw5_own/settings/grafana/provisioning/dashboards/dashboards.yml b/hw5_own/settings/grafana/provisioning/dashboards/dashboards.yml new file mode 100644 index 00000000..f2f56c65 --- /dev/null +++ b/hw5_own/settings/grafana/provisioning/dashboards/dashboards.yml @@ -0,0 +1,8 @@ +apiVersion: 1 +providers: + - name: "shop-api" + type: file + disableDeletion: false + allowUiUpdates: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/hw5_own/settings/grafana/provisioning/dashboards/shop_api_overview.json b/hw5_own/settings/grafana/provisioning/dashboards/shop_api_overview.json new file mode 100644 index 00000000..9e029a74 --- /dev/null +++ b/hw5_own/settings/grafana/provisioning/dashboards/shop_api_overview.json @@ -0,0 +1,66 @@ +{ + "title": "Shop API — Overview", + "schemaVersion": 39, + "version": 1, + "time": { "from": "now-1h", "to": "now" }, + "panels": [ + { + "type": "timeseries", + "title": "RPS (requests/sec)", + "targets": [ + { + "expr": "sum(rate(http_requests_total[1m]))", + "legendFormat": "rps" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 } + }, + { + "type": "timeseries", + "title": "Error rate (%)", + "targets": [ + { + "expr": "100 * (sum(rate(http_requests_total{status=~\"5..\"}[5m])) / clamp_min(sum(rate(http_requests_total[5m])), 1e-9))", + "legendFormat": "5xx %" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 } + }, + { + "type": "timeseries", + "title": "Latency p95 (seconds)", + "description": "Если лейбл пути называется не 'handler', замените на 'path' в expr.", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))", + "legendFormat": "p95" + } + ], + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 } + }, + { + "type": "stat", + "title": "In-progress requests", + "targets": [ + { + "expr": "sum(http_requests_in_progress)", + "legendFormat": "inflight" + } + ], + "gridPos": { "h": 8, "w": 6, "x": 12, "y": 8 } + }, + { + "type": "bargauge", + "title": "Requests by status (5m rate)", + "options": { "displayMode": "gradient" }, + "targets": [ + { + "expr": "sum by (status) (rate(http_requests_total[5m]))", + "legendFormat": "{{status}}" + } + ], + "gridPos": { "h": 8, "w": 6, "x": 18, "y": 8 } + } + ], + "panelsState": {} +} diff --git a/hw5_own/settings/grafana/provisioning/dashboards/shop_api_routes.json b/hw5_own/settings/grafana/provisioning/dashboards/shop_api_routes.json new file mode 100644 index 00000000..495bdcc5 --- /dev/null +++ b/hw5_own/settings/grafana/provisioning/dashboards/shop_api_routes.json @@ -0,0 +1,51 @@ +{ + "title": "Shop API — Routes", + "schemaVersion": 39, + "version": 1, + "time": { "from": "now-1h", "to": "now" }, + "panels": [ + { + "type": "timeseries", + "title": "RPS by route", + "description": "Если вместо label 'handler' у вас 'path' — замените в expr.", + "targets": [ + { + "expr": "sum by (handler) (rate(http_requests_total[1m]))", + "legendFormat": "{{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 0 } + }, + { + "type": "timeseries", + "title": "Latency p95 by route", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum by (le, handler) (rate(http_request_duration_seconds_bucket[5m])))", + "legendFormat": "p95 {{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 8 } + }, + { + "type": "timeseries", + "title": "2xx / 4xx / 5xx by route (5m rate)", + "targets": [ + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"2..\"}[5m]))", + "legendFormat": "2xx {{handler}}" + }, + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"4..\"}[5m]))", + "legendFormat": "4xx {{handler}}" + }, + { + "expr": "sum by (handler) (rate(http_requests_total{status=~\"5..\"}[5m]))", + "legendFormat": "5xx {{handler}}" + } + ], + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 } + } + ], + "panelsState": {} +} diff --git a/hw5_own/settings/grafana/provisioning/datasources/datasource.yml b/hw5_own/settings/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 00000000..c9f4f3a9 --- /dev/null +++ b/hw5_own/settings/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,8 @@ +apiVersion: 1 +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + editable: true diff --git a/hw5_own/settings/prometheus/prometheus.yml b/hw5_own/settings/prometheus/prometheus.yml new file mode 100644 index 00000000..cb41e3c3 --- /dev/null +++ b/hw5_own/settings/prometheus/prometheus.yml @@ -0,0 +1,10 @@ +global: + scrape_interval: 10s + evaluation_interval: 10s + +scrape_configs: + - job_name: service-server + metrics_path: /metrics + static_configs: + - targets: + - server:8080 diff --git a/hw5_own/shop_api/__init__.py b/hw5_own/shop_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hw5_own/shop_api/core/schemas.py b/hw5_own/shop_api/core/schemas.py new file mode 100644 index 00000000..f7547e01 --- /dev/null +++ b/hw5_own/shop_api/core/schemas.py @@ -0,0 +1,49 @@ +# from __future__ import annotations +from typing import Optional, Annotated +from pydantic import BaseModel, Field, ConfigDict + +ItemName = Annotated[str, Field(description="Наименование товара", min_length=1)] +ItemId = Annotated[int, Field(description="Идентификатор корзины", ge=0)] +ItemPrice = Annotated[float, Field(description="Цена товара", ge=0)] + +CartId = Annotated[int, Field(description="Идентификатор корзины")] + + +# ---- Item ---- +class ItemOut(BaseModel): + id: ItemId + name: ItemName + price: ItemPrice + deleted: bool = Field(description="Удален ли товар", default=False) + + +class ItemCreate(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPut(BaseModel): + name: ItemName + price: ItemPrice + + +class ItemPatch(BaseModel): + # Разрешаем частичное обновление ТОЛЬКО name/price; лишние поля → 422 + model_config = ConfigDict(extra="forbid") + + name: Optional[ItemName] = None + price: Optional[ItemPrice] = None + + +# ---- Cart ---- +class CartItemView(BaseModel): + id: ItemId + name: ItemName + quantity: int = Field(description="Количество товара в корзине", ge=0) + available: bool = Field(description="Доступен ли товар") + + +class CartView(BaseModel): + id: int + items: list[CartItemView] + price: float = Field(description="Общая сумма заказа", ge=0.0) diff --git a/hw5_own/shop_api/core/storage.py b/hw5_own/shop_api/core/storage.py new file mode 100644 index 00000000..bc3c6cb9 --- /dev/null +++ b/hw5_own/shop_api/core/storage.py @@ -0,0 +1,142 @@ +from __future__ import annotations +from threading import ( + RLock, +) # стандартная библиотека Python: https://docs.python.org/3/library/threading.html +from typing import Optional +from fastapi import HTTPException, status +from .schemas import ( + ItemOut, + CartItemView, + CartView, + ItemCreate, + ItemPut, + ItemPatch, +) + +# ------------------------- +# In-memory хранилище + блокировки +# ------------------------- +_items_lock = RLock() +_carts_lock = RLock() + +_items: dict[int, ItemOut] = {} +_next_item_id = 1 + +# cart_id -> { item_id -> quantity } +_carts: dict[int, dict[int, int]] = {} +_next_cart_id = 1 + + +def new_item_id() -> int: + global _next_item_id + with _items_lock: + nid = _next_item_id + _next_item_id += 1 + return nid + + +def new_cart_id() -> int: + global _next_cart_id + with _carts_lock: + nid = _next_cart_id + _next_cart_id += 1 + return nid + + +def get_item_or_404(item_id: int) -> ItemOut: + with _items_lock: + item = _items.get(item_id) + if item is None or item.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + return item + + +def get_item_soft(item_id: int) -> Optional[ItemOut]: + with _items_lock: + return _items.get(item_id) + + +def cart_or_404(cart_id: int) -> dict[int, int]: + with _carts_lock: + cart = _carts.get(cart_id) + if cart is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Cart not found" + ) + return cart + + +def build_cart_view(cart_id: int) -> CartView: + with _carts_lock: + cart = _carts.get(cart_id, {}) + kv = list(cart.items()) + + items = [] + total = 0.0 + for item_id, qty in kv: + item = get_item_soft(item_id) + name = item.name if item else f"item:{item_id}" + available = bool(item and not item.deleted) + items.append( + CartItemView(id=item_id, name=name, quantity=qty, available=available) + ) + if available: + total += item.price * qty + + return CartView(id=cart_id, items=items, price=total) + + +def create_item(data: ItemCreate) -> ItemOut: + item_id = new_item_id() + item = ItemOut(id=item_id, name=data.name, price=data.price, deleted=False) + with _items_lock: + _items[item_id] = item + return item + + +def put_item(item_id: int, data: ItemPut) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = data.name + existing.price = data.price + return existing + + +def patch_item(item_id: int, data: ItemPatch) -> ItemOut: + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + # Пробрасываем семантику 304 на верхний уровень + raise HTTPException( + status_code=status.HTTP_304_NOT_MODIFIED, detail="Item deleted" + ) + + if data.name is not None: + existing.name = data.name + if data.price is not None: + if data.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = data.price + + return existing + + +def delete_item(item_id: int) -> dict: + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} diff --git a/hw5_own/shop_api/main.py b/hw5_own/shop_api/main.py new file mode 100644 index 00000000..788a41a9 --- /dev/null +++ b/hw5_own/shop_api/main.py @@ -0,0 +1,25 @@ +from fastapi import FastAPI +from shop_api.routers.item import router as item +from shop_api.routers.cart import router as cart +from shop_api.routers.chat import router as chat +from prometheus_fastapi_instrumentator import Instrumentator + + +app = FastAPI(title="Shop API") + +app.include_router(item) +app.include_router(cart) + +app.include_router(chat) + +Instrumentator().instrument(app).expose( + app, + endpoint="/metrics", + include_in_schema=False, +) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, port=8001) diff --git a/hw5_own/shop_api/routers/cart.py b/hw5_own/shop_api/routers/cart.py new file mode 100644 index 00000000..9e040b6f --- /dev/null +++ b/hw5_own/shop_api/routers/cart.py @@ -0,0 +1,99 @@ +from typing import List, Optional +from fastapi import APIRouter, Query, Response, status + +from shop_api.core.schemas import CartView +from shop_api.core.storage import ( + _carts, + _carts_lock, + new_cart_id, + cart_or_404, + build_cart_view, + get_item_or_404, +) + +router = APIRouter(prefix="/cart", tags=["cart"]) + + +@router.post("", status_code=status.HTTP_201_CREATED) +def create_cart(response: Response): + """ + POST /cart — RPC: создаёт пустую корзину, тело не принимает. + Возвращает 201 и JSON {"id": }, а также заголовок Location: /cart/{id}. + """ + cart_id = new_cart_id() + with _carts_lock: + _carts[cart_id] = {} + response.headers["Location"] = f"/cart/{cart_id}" + return {"id": cart_id} + + +@router.get("/{cart_id}", response_model=CartView) +def get_cart(cart_id: int) -> CartView: + """ + GET /cart/{id} — получить корзину по id. + """ + cart_or_404(cart_id) + return build_cart_view(cart_id) + + +@router.get("", response_model=List[CartView]) +def list_carts( + offset: int = Query(0, ge=0, description="Смещение по списку (offset)"), + limit: int = Query(10, gt=0, description="Лимит количества (limit)"), + min_price: Optional[float] = Query( + None, ge=0.0, description="Мин. сумма корзины (включительно)" + ), + max_price: Optional[float] = Query( + None, ge=0.0, description="Макс. сумма корзины (включительно)" + ), + min_quantity: Optional[int] = Query( + None, ge=0, description="Мин. общее число товаров (включительно)" + ), + max_quantity: Optional[int] = Query( + None, ge=0, description="Макс. общее число товаров (включительно)" + ), +) -> List[CartView]: + """ + GET /cart — список корзин с фильтрами и пагинацией. + + Фильтры: + • min_price/max_price — по суммарной стоимости корзины (включительно); + • min_quantity/max_quantity — по суммарному количеству позиций в корзине (включительно). + Порядок: фильтрация -> offset/limit. + """ + with _carts_lock: + ids = list(_carts.keys()) + + views: List[CartView] = [] + for cid in ids: + v = build_cart_view(cid) + + if min_price is not None and v.price < min_price: + continue + if max_price is not None and v.price > max_price: + continue + + qsum = sum(it.quantity for it in v.items) + if min_quantity is not None and qsum < min_quantity: + continue + if max_quantity is not None and qsum > max_quantity: + continue + + views.append(v) + + return views[offset : offset + limit] + + +@router.post("/{cart_id}/add/{item_id}") +def add_to_cart(cart_id: int, item_id: int): + """ + POST /cart/{cart_id}/add/{item_id} — добавить товар в корзину. + Если товар уже есть — увеличивает его количество. + """ + cart = cart_or_404(cart_id) + get_item_or_404(item_id) # проверка на товар + + with _carts_lock: + cart[item_id] = cart.get(item_id, 0) + 1 + + return {"ok": True} diff --git a/hw5_own/shop_api/routers/chat.py b/hw5_own/shop_api/routers/chat.py new file mode 100644 index 00000000..6c3e1d5e --- /dev/null +++ b/hw5_own/shop_api/routers/chat.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import asyncio +import secrets # стандартная библиотека: https://docs.python.org/3/library/secrets.html +from collections import defaultdict + +from fastapi import APIRouter, WebSocket, WebSocketDisconnect + +router = APIRouter(tags=["chat"]) + + +class RoomManager: + # Решил реализовать в одном файле систему чатов, чтобы проще было проверять + def __init__(self) -> None: + # room -> set of websockets + self.rooms: dict[str, set[WebSocket]] = defaultdict(set) + # websocket -> username + self.usernames: dict[WebSocket, str] = {} + self._lock = asyncio.Lock() + + @staticmethod + def _gen_username() -> str: + # короткий случайный ник + return f"user-{secrets.token_hex(2)}" + + async def connect(self, room: str, ws: WebSocket) -> str: + await ws.accept() + username = self._gen_username() + async with self._lock: + self.rooms[room].add(ws) + self.usernames[ws] = username + await ws.send_text(f"[system] :: your_name = {username}") + return username + + async def disconnect(self, room: str, ws: WebSocket) -> None: + async with self._lock: + self.rooms[room].discard(ws) + self.usernames.pop(ws, None) + if not self.rooms[room]: + self.rooms.pop(room, None) + + async def broadcast( + self, room: str, text: str, sender: WebSocket | None = None + ) -> None: + async with self._lock: + targets = list(self.rooms.get(room, ())) + for ws in targets: + if ws is sender: + continue + try: + await ws.send_text(text) + except Exception: + try: + await self.disconnect(room, ws) + except Exception: + pass + + +manager = RoomManager() + + +@router.websocket("/chat/{chat_name}") +async def chat_ws(websocket: WebSocket, chat_name: str): + """ + Пользователи, подключённые к одному chat_name, получают сообщения друг друга. + Формат сообщения: "{username} :: {message}". + """ + username = await manager.connect(chat_name, websocket) + try: + while True: + # Ждём текст от клиента + msg = await websocket.receive_text() + # Бродкастим другим пользователям в комнате (без эха отправителю) + await manager.broadcast(chat_name, f"{username} :: {msg}", sender=websocket) + except WebSocketDisconnect: + await manager.disconnect(chat_name, websocket) + except Exception: + # Любая иная ошибка закрывает сокет и удаляет из комнаты + await manager.disconnect(chat_name, websocket) + try: + await websocket.close() + except Exception: + pass diff --git a/hw5_own/shop_api/routers/item.py b/hw5_own/shop_api/routers/item.py new file mode 100644 index 00000000..acc511f6 --- /dev/null +++ b/hw5_own/shop_api/routers/item.py @@ -0,0 +1,107 @@ +from typing import List, Optional +from fastapi import APIRouter, HTTPException, Query, Response, status + +from shop_api.core.schemas import ItemOut, ItemCreate, ItemPut, ItemPatch +from shop_api.core.storage import _items, _items_lock, get_item_or_404, new_item_id + +router = APIRouter(prefix="/item", tags=["items"]) + + +@router.post("", status_code=status.HTTP_201_CREATED, response_model=ItemOut) +def create_item(body: ItemCreate) -> ItemOut: + """ + POST /item - добавление нового товара + """ + item_id = new_item_id() + obj = ItemOut(id=item_id, name=body.name, price=body.price, deleted=False) + with _items_lock: + _items[item_id] = obj + return obj + + +@router.get("/{item_id}", response_model=ItemOut) +def get_item(item_id: int) -> ItemOut: + """ + GET /item/{id} - получение товара по id + """ + return get_item_or_404(item_id) + + +@router.get("", response_model=List[ItemOut]) +def list_items( + offset: int = Query(0, ge=0, description="Смещение (offset)"), + limit: int = Query(10, gt=0, description="Количество (limit)"), + min_price: Optional[float] = Query(None, ge=0, description="Мин. цена"), + max_price: Optional[float] = Query(None, ge=0, description="Макс. цена"), + show_deleted: bool = Query(False, description="Показывать ли удалённые"), +) -> List[ItemOut]: + """ + GET /item - получение списка товаров с фильтрами и пагинацией + """ + with _items_lock: + items = list(_items.values()) + + if not show_deleted: + items = [i for i in items if not i.deleted] + if min_price is not None: + items = [i for i in items if i.price >= min_price] + if max_price is not None: + items = [i for i in items if i.price <= max_price] + + return items[offset : offset + limit] + + +@router.put("/{item_id}", response_model=ItemOut) +def put_item(item_id: int, body: ItemPut) -> ItemOut: + """ + PUT /item/{id} - замена товара по id (создание запрещено) + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None or existing.deleted: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + existing.name = body.name + existing.price = body.price + return existing + + +@router.patch("/{item_id}", response_model=ItemOut) +def patch_item(item_id: int, body: ItemPatch): + """ + PATCH /item/{id} - частичное обновление (разрешено менять всё кроме deleted) + Если товар удалён — 304 Not Modified. + """ + with _items_lock: + existing = _items.get(item_id) + if existing is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Item not found" + ) + if existing.deleted: + return Response(status_code=status.HTTP_304_NOT_MODIFIED) + + if body.name is not None: + existing.name = body.name + if body.price is not None: + if body.price < 0: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail="Invalid price", + ) + existing.price = body.price + + return existing + + +@router.delete("/{item_id}") +def delete_item(item_id: int): + """ + DELETE /item/{id} - мягкое удаление (deleted=True), идемпотентно + """ + with _items_lock: + existing = _items.get(item_id) + if existing is not None: + existing.deleted = True + return {"ok": True} diff --git a/hw5_own/test_homework5.py b/hw5_own/test_homework5.py new file mode 100644 index 00000000..60a1f36a --- /dev/null +++ b/hw5_own/test_homework5.py @@ -0,0 +1,284 @@ +from http import HTTPStatus +from typing import Any +from uuid import uuid4 + +import pytest +from faker import Faker +from fastapi.testclient import TestClient + +from shop_api.main import app + +client = TestClient(app) +faker = Faker() + + +@pytest.fixture() +def existing_empty_cart_id() -> int: + return client.post("/cart").json()["id"] + + +@pytest.fixture(scope="session") +def existing_items() -> list[int]: + items = [ + { + "name": f"Тестовый товар {i}", + "price": faker.pyfloat(positive=True, min_value=10.0, max_value=500.0), + } + for i in range(10) + ] + + return [client.post("/item", json=item).json()["id"] for item in items] + + +@pytest.fixture(scope="session", autouse=True) +def existing_not_empty_carts(existing_items: list[int]) -> list[int]: + carts = [] + + for i in range(20): + cart_id: int = client.post("/cart").json()["id"] + for item_id in faker.random_elements(existing_items, unique=False, length=i): + client.post(f"/cart/{cart_id}/add/{item_id}") + + carts.append(cart_id) + + return carts + + +@pytest.fixture() +def existing_not_empty_cart_id( + existing_empty_cart_id: int, + existing_items: list[int], +) -> int: + for item_id in faker.random_elements(existing_items, unique=False, length=3): + client.post(f"/cart/{existing_empty_cart_id}/add/{item_id}") + + return existing_empty_cart_id + + +@pytest.fixture() +def existing_item() -> dict[str, Any]: + return client.post( + "/item", + json={ + "name": f"Тестовый товар {uuid4().hex}", + "price": faker.pyfloat(min_value=10.0, max_value=100.0), + }, + ).json() + + +@pytest.fixture() +def deleted_item(existing_item: dict[str, Any]) -> dict[str, Any]: + item_id = existing_item["id"] + client.delete(f"/item/{item_id}") + + existing_item["deleted"] = True + return existing_item + + +def test_post_cart() -> None: + response = client.post("/cart") + + assert response.status_code == HTTPStatus.CREATED + assert "location" in response.headers + assert "id" in response.json() + + +@pytest.mark.parametrize( + ("cart", "not_empty"), + [ + ("existing_empty_cart_id", False), + ("existing_not_empty_cart_id", True), + ], +) +def test_get_cart(request, cart: int, not_empty: bool) -> None: + cart_id = request.getfixturevalue(cart) + + response = client.get(f"/cart/{cart_id}") + + assert response.status_code == HTTPStatus.OK + response_json = response.json() + + len_items = len(response_json["items"]) + assert len_items > 0 if not_empty else len_items == 0 + + if not_empty: + price = 0 + + for item in response_json["items"]: + item_id = item["id"] + price += client.get(f"/item/{item_id}").json()["price"] * item["quantity"] + + assert response_json["price"] == pytest.approx(price, 1e-8) + else: + assert response_json["price"] == 0.0 + + +@pytest.mark.parametrize( + ("query", "status_code"), + [ + ({}, HTTPStatus.OK), + ({"offset": 1, "limit": 2}, HTTPStatus.OK), + ({"min_price": 1000.0}, HTTPStatus.OK), + ({"max_price": 20.0}, HTTPStatus.OK), + ({"min_quantity": 1}, HTTPStatus.OK), + ({"max_quantity": 0}, HTTPStatus.OK), + ({"offset": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": 0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_price": -1.0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_price": -1.0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_quantity": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_quantity": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ], +) +def test_get_cart_list(query: dict[str, Any], status_code: int): + response = client.get("/cart", params=query) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + data = response.json() + + assert isinstance(data, list) + + if "min_price" in query: + assert all(item["price"] >= query["min_price"] for item in data) + + if "max_price" in query: + assert all(item["price"] <= query["max_price"] for item in data) + + quantity = sum(item["quantity"] for cart in data for item in cart["items"]) + + if "min_quantity" in query: + assert quantity >= query["min_quantity"] + + if "max_quantity" in query: + assert quantity <= query["max_quantity"] + + +def test_post_item() -> None: + item = {"name": "test item", "price": 9.99} + response = client.post("/item", json=item) + + assert response.status_code == HTTPStatus.CREATED + + data = response.json() + assert item["price"] == data["price"] + assert item["name"] == data["name"] + + +def test_get_item(existing_item: dict[str, Any]) -> None: + item_id = existing_item["id"] + + response = client.get(f"/item/{item_id}") + + assert response.status_code == HTTPStatus.OK + assert response.json() == existing_item + + +@pytest.mark.parametrize( + ("query", "status_code"), + [ + ({"offset": 2, "limit": 5}, HTTPStatus.OK), + ({"min_price": 5.0}, HTTPStatus.OK), + ({"max_price": 5.0}, HTTPStatus.OK), + ({"show_deleted": True}, HTTPStatus.OK), + ({"offset": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"limit": 0}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"min_price": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"max_price": -1}, HTTPStatus.UNPROCESSABLE_ENTITY), + ], +) +def test_get_item_list(query: dict[str, Any], status_code: int) -> None: + response = client.get("/item", params=query) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + data = response.json() + + assert isinstance(data, list) + + if "min_price" in query: + assert all(item["price"] >= query["min_price"] for item in data) + + if "max_price" in query: + assert all(item["price"] <= query["max_price"] for item in data) + + if "show_deleted" in query and query["show_deleted"] is False: + assert all(item["deleted"] is False for item in data) + + +@pytest.mark.parametrize( + ("body", "status_code"), + [ + ({}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"price": 9.99}, HTTPStatus.UNPROCESSABLE_ENTITY), + ({"name": "new name", "price": 9.99}, HTTPStatus.OK), + ], +) +def test_put_item( + existing_item: dict[str, Any], + body: dict[str, Any], + status_code: int, +) -> None: + item_id = existing_item["id"] + response = client.put(f"/item/{item_id}", json=body) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + new_item = existing_item.copy() + new_item.update(body) + assert response.json() == new_item + + +@pytest.mark.parametrize( + ("item", "body", "status_code"), + [ + ("deleted_item", {}, HTTPStatus.NOT_MODIFIED), + ("deleted_item", {"price": 9.99}, HTTPStatus.NOT_MODIFIED), + ("deleted_item", {"name": "new name", "price": 9.99}, HTTPStatus.NOT_MODIFIED), + ("existing_item", {}, HTTPStatus.OK), + ("existing_item", {"price": 9.99}, HTTPStatus.OK), + ("existing_item", {"name": "new name", "price": 9.99}, HTTPStatus.OK), + ( + "existing_item", + {"name": "new name", "price": 9.99, "odd": "value"}, + HTTPStatus.UNPROCESSABLE_ENTITY, + ), + ( + "existing_item", + {"name": "new name", "price": 9.99, "deleted": True}, + HTTPStatus.UNPROCESSABLE_ENTITY, + ), + ], +) +def test_patch_item(request, item: str, body: dict[str, Any], status_code: int) -> None: + item_data: dict[str, Any] = request.getfixturevalue(item) + item_id = item_data["id"] + response = client.patch(f"/item/{item_id}", json=body) + + assert response.status_code == status_code + + if status_code == HTTPStatus.OK: + patch_response_body = response.json() + + response = client.get(f"/item/{item_id}") + patched_item = response.json() + + assert patched_item == patch_response_body + + +def test_delete_item(existing_item: dict[str, Any]) -> None: + item_id = existing_item["id"] + + response = client.delete(f"/item/{item_id}") + assert response.status_code == HTTPStatus.OK + + response = client.get(f"/item/{item_id}") + assert response.status_code == HTTPStatus.NOT_FOUND + + response = client.delete(f"/item/{item_id}") + assert response.status_code == HTTPStatus.OK diff --git a/hw5_own/test_websocket_chat.py b/hw5_own/test_websocket_chat.py new file mode 100644 index 00000000..248e7625 --- /dev/null +++ b/hw5_own/test_websocket_chat.py @@ -0,0 +1,60 @@ +import re +from fastapi.testclient import TestClient + +from shop_api.main import app + +USERNAME_RE = re.compile(r"^\[system\] :: your_name = (user-[0-9a-f]{4})$") + + +def _extract_username(system_msg: str) -> str: + """ + Из приветственного сообщения вида: + "[system] :: your_name = user-ab12" + достаём "user-ab12". + """ + m = USERNAME_RE.match(system_msg) + assert m, f"unexpected system greeting format: {system_msg!r}" + return m.group(1) + + +def test_websocket_broadcast_and_format(): + client = TestClient(app) + + # Подключаем двух пользователей к одной комнате и третьего — к другой + with ( + client.websocket_connect("/chat/room1") as ws1, + client.websocket_connect("/chat/room1") as ws2, + client.websocket_connect("/chat/room2") as ws3, + ): + # Приветственные сообщения с именами + u1 = _extract_username(ws1.receive_text()) + u2 = _extract_username(ws2.receive_text()) + u3 = _extract_username(ws3.receive_text()) + assert u1 != u2 and u1 != u3 and u2 != u3 # имена случайные и разные + + # user1 -> room1 + msg1 = "hello from 1" + ws1.send_text(msg1) + + # Должно прийти ТОЛЬКО второму участнику той же комнаты + got2 = ws2.receive_text() + assert got2 == f"{u1} :: {msg1}" + + # user3 -> room2 (не должен мешать room1) + ws3.send_text("ping from 3") + + # user2 -> room1 + msg2 = "hi from 2" + ws2.send_text(msg2) + + # Должно прийти первому участнику room1 + got1 = ws1.receive_text() + assert got1 == f"{u2} :: {msg2}" + + +def test_websocket_username_greeting_format(): + client = TestClient(app) + with client.websocket_connect("/chat/any-room") as ws: + greet = ws.receive_text() + # Проверяем точный формат приветствия и шаблон username + assert USERNAME_RE.match(greet), f"bad greeting: {greet!r}" From 96064889d8ad7b4d45d8455519b1a07e582c2edd Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sat, 25 Oct 2025 04:28:08 +0300 Subject: [PATCH 8/9] Fixed HW5 pytest.ini --- hw5_own/pytest.ini | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 hw5_own/pytest.ini diff --git a/hw5_own/pytest.ini b/hw5_own/pytest.ini deleted file mode 100644 index 6fc8c304..00000000 --- a/hw5_own/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[pytest] -addopts = -ra --cov=hw5_own --cov-report=term-missing --cov-report=xml:reports/coverage.xml --cov-fail-under=90 -testpaths = hw4_own/tests -python_files = test_*.py From d1556d4ece7078de2d4e907731a2551bd659ed0b Mon Sep 17 00:00:00 2001 From: Dan Sukhorukov Date: Sat, 25 Oct 2025 04:31:43 +0300 Subject: [PATCH 9/9] Fix requirements.txt --- hw5_own/requirements.txt | 2 ++ hw5_own/requirements_hw3.txt | 11 ----------- 2 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 hw5_own/requirements_hw3.txt diff --git a/hw5_own/requirements.txt b/hw5_own/requirements.txt index 207dcf5c..1593e6d3 100644 --- a/hw5_own/requirements.txt +++ b/hw5_own/requirements.txt @@ -1,6 +1,8 @@ # Основные зависимости для ASGI приложения fastapi>=0.117.1 uvicorn>=0.24.0 +websockets>=15.0.1 +prometheus_fastapi_instrumentator>=7.1.0 # Зависимости для тестирования pytest>=7.4.0 diff --git a/hw5_own/requirements_hw3.txt b/hw5_own/requirements_hw3.txt deleted file mode 100644 index 1593e6d3..00000000 --- a/hw5_own/requirements_hw3.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Основные зависимости для ASGI приложения -fastapi>=0.117.1 -uvicorn>=0.24.0 -websockets>=15.0.1 -prometheus_fastapi_instrumentator>=7.1.0 - -# Зависимости для тестирования -pytest>=7.4.0 -pytest-asyncio>=0.21.0 -httpx>=0.27.2 -Faker>=37.8.0