From 1cc58a797bd7a19b412c53af59c1f8ed9eaa89e9 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:28:58 +0300 Subject: [PATCH 01/56] Create README.md --- SerovAA/README.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 SerovAA/README.md diff --git a/SerovAA/README.md b/SerovAA/README.md new file mode 100644 index 0000000..9192853 --- /dev/null +++ b/SerovAA/README.md @@ -0,0 +1,50 @@ +# Password Generator - Microservices Demo + +## Architecture +- **Nginx**: Reverse proxy and static frontend server +- **Frontend**: HTML/JS UI served by Nginx +- **Backend (Flask)**: API endpoint for generating password tasks +- **Worker (Python)**: Long-running password generation service +- **Redis**: Task queue and result storage + +## Run + +docker compose up -d + +## How it works +- Frontend submits generation request to backend API +- Backend creates task in Redis and returns task_id +- Worker picks up task from Redis queue +- Worker generates password (simulated 2s delay) +- Frontend polls for result and displays password + +---- +## Проверка работоспособности + +### Клонируем репозиторий +1. git clone https://github.com/SoftwareEngineering2026/Practice105.git +2. cd Practice105/SerovAA/ + +### Создаём структуру и файлы (скопируй вышеуказанные файлы) + +### Запускаем +docker compose up -d + +### Проверяем +curl http://localhost:8080/api/generate -X POST -H "Content-Type: application/json" -d '{"length": 16, "use_digits": true, "use_special": true}' + +### Останавливаем +docker compose down + +---- +## Особенности решения: + +✅ Одна точка входа — Nginx на порту 8080 + +✅ Все сервисы в одной сети Docker + +✅ Worker выполняет "длительные задачи" (generation с delay) + +✅ Готово к запуску одной командой docker compose up + +✅ Полностью микросервисный (frontend, backend, worker, redis) From a9cd5fb77d462129126294cb423d3fdf3d1b423d Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:29:43 +0300 Subject: [PATCH 02/56] Create docker-compose.yml --- SerovAA/password-generator/docker-compose.yml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SerovAA/password-generator/docker-compose.yml diff --git a/SerovAA/password-generator/docker-compose.yml b/SerovAA/password-generator/docker-compose.yml new file mode 100644 index 0000000..960b21f --- /dev/null +++ b/SerovAA/password-generator/docker-compose.yml @@ -0,0 +1,41 @@ +version: '3.8' + +services: + nginx: + image: nginx:alpine + ports: + - "8080:80" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./frontend:/usr/share/nginx/html + depends_on: + - backend + networks: + - app-network + + backend: + build: ./backend + environment: + - REDIS_HOST=redis + depends_on: + - redis + networks: + - app-network + + worker: + build: ./worker + environment: + - REDIS_HOST=redis + depends_on: + - redis + networks: + - app-network + + redis: + image: redis:alpine + networks: + - app-network + +networks: + app-network: + driver: bridge From 0a19ad3f95783f9ec6273930f71095cde124a082 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:30:26 +0300 Subject: [PATCH 03/56] Create worker.py --- SerovAA/password-generator/worker/worker.py | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 SerovAA/password-generator/worker/worker.py diff --git a/SerovAA/password-generator/worker/worker.py b/SerovAA/password-generator/worker/worker.py new file mode 100644 index 0000000..0e057c1 --- /dev/null +++ b/SerovAA/password-generator/worker/worker.py @@ -0,0 +1,37 @@ +import redis +import json +import random +import string +import os +import time + +redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) + +def generate_password(length, use_digits, use_special): + chars = string.ascii_letters + if use_digits: + chars += string.digits + if use_special: + chars += '!@#$%^&*()' + return ''.join(random.choice(chars) for _ in range(length)) + +while True: + task_id = redis_client.brpop('password_tasks')[1].decode() + + # Simulate long processing + time.sleep(2) + + task_data = json.loads(redis_client.get(f"task:{task_id}")) + try: + password = generate_password( + task_data['length'], + task_data['use_digits'], + task_data['use_special'] + ) + task_data['status'] = 'completed' + task_data['password'] = password + except Exception as e: + task_data['status'] = 'failed' + task_data['error'] = str(e) + + redis_client.set(f"task:{task_id}", json.dumps(task_data)) From 89da594861c3f44065f86d2b96afce1ff1659ad2 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:30:53 +0300 Subject: [PATCH 04/56] Create Dockerfile --- SerovAA/password-generator/worker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SerovAA/password-generator/worker/Dockerfile diff --git a/SerovAA/password-generator/worker/Dockerfile b/SerovAA/password-generator/worker/Dockerfile new file mode 100644 index 0000000..d55b117 --- /dev/null +++ b/SerovAA/password-generator/worker/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY worker.py . +CMD ["python", "worker.py"] From dc0fd82d6027bedc970557ab59c81d43ae2fafe6 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:31:11 +0300 Subject: [PATCH 05/56] Create requirements.txt --- SerovAA/password-generator/worker/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 SerovAA/password-generator/worker/requirements.txt diff --git a/SerovAA/password-generator/worker/requirements.txt b/SerovAA/password-generator/worker/requirements.txt new file mode 100644 index 0000000..785cc92 --- /dev/null +++ b/SerovAA/password-generator/worker/requirements.txt @@ -0,0 +1 @@ +redis==5.0.1 From 4f47f17b4948fb3d93b2a1db422d2b7faf08c3fe Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:31:43 +0300 Subject: [PATCH 06/56] Create nginx.conf --- SerovAA/password-generator/nginx/nginx.conf | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SerovAA/password-generator/nginx/nginx.conf diff --git a/SerovAA/password-generator/nginx/nginx.conf b/SerovAA/password-generator/nginx/nginx.conf new file mode 100644 index 0000000..8b8e9a7 --- /dev/null +++ b/SerovAA/password-generator/nginx/nginx.conf @@ -0,0 +1,26 @@ +events { + worker_connections 1024; +} + +http { + upstream backend { + server backend:5000; + } + + server { + listen 80; + + # Frontend + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + # Backend API + location /api/ { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + } +} From 4476115e447cf97a3731e741b2810c21748fb889 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:32:17 +0300 Subject: [PATCH 07/56] Create index.html --- .../password-generator/frontend/index.html | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 SerovAA/password-generator/frontend/index.html diff --git a/SerovAA/password-generator/frontend/index.html b/SerovAA/password-generator/frontend/index.html new file mode 100644 index 0000000..c5e87cf --- /dev/null +++ b/SerovAA/password-generator/frontend/index.html @@ -0,0 +1,73 @@ + + + + Password Generator + + + +

🔐 Password Generator

+ +
+
+
+ + + + +
+ Password: -
+ Task ID: -
+ Status: Idle +
+ + + + From ffc595e42eeef1c3a9d87ae1eccc6a313b7e9db8 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:33:08 +0300 Subject: [PATCH 08/56] Create Dockerfile --- SerovAA/password-generator/backend/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SerovAA/password-generator/backend/Dockerfile diff --git a/SerovAA/password-generator/backend/Dockerfile b/SerovAA/password-generator/backend/Dockerfile new file mode 100644 index 0000000..6113261 --- /dev/null +++ b/SerovAA/password-generator/backend/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY app.py . +CMD ["python", "app.py"] From 2020f087aa30ee995c3f79942f958e34f14cc3a3 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:33:28 +0300 Subject: [PATCH 09/56] Create app.py --- SerovAA/password-generator/backend/app.py | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 SerovAA/password-generator/backend/app.py diff --git a/SerovAA/password-generator/backend/app.py b/SerovAA/password-generator/backend/app.py new file mode 100644 index 0000000..9b1c62c --- /dev/null +++ b/SerovAA/password-generator/backend/app.py @@ -0,0 +1,36 @@ +from flask import Flask, request, jsonify +import redis +import uuid +import json +import os + +app = Flask(__name__) +redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) + +@app.route('/api/generate', methods=['POST']) +def generate(): + data = request.json + task_id = str(uuid.uuid4()) + + task_data = { + 'status': 'pending', + 'length': data['length'], + 'use_digits': data['use_digits'], + 'use_special': data['use_special'] + } + + redis_client.set(f"task:{task_id}", json.dumps(task_data)) + redis_client.lpush('password_tasks', task_id) + + return jsonify({'task_id': task_id}) + +@app.route('/api/result/', methods=['GET']) +def result(task_id): + task_data = redis_client.get(f"task:{task_id}") + if task_data: + task = json.loads(task_data) + return jsonify(task) + return jsonify({'status': 'not_found'}), 404 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) From edcdb6381019c08b8271c61b10697232dfd7da82 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:33:48 +0300 Subject: [PATCH 10/56] Create requirements.txt --- SerovAA/password-generator/backend/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 SerovAA/password-generator/backend/requirements.txt diff --git a/SerovAA/password-generator/backend/requirements.txt b/SerovAA/password-generator/backend/requirements.txt new file mode 100644 index 0000000..bf804e5 --- /dev/null +++ b/SerovAA/password-generator/backend/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.3.3 +redis==5.0.1 From 06364488049c991a12dc7ded9e09f4a22d30ef2c Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:35:22 +0300 Subject: [PATCH 11/56] Create ci.yml --- .../.github/workflows/ci.yml | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 SerovAA/password-generator/.github/workflows/ci.yml diff --git a/SerovAA/password-generator/.github/workflows/ci.yml b/SerovAA/password-generator/.github/workflows/ci.yml new file mode 100644 index 0000000..c45ed54 --- /dev/null +++ b/SerovAA/password-generator/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI Pipeline + +on: + pull_request: + branches: [ main, master ] + +jobs: + test-backend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install backend dependencies + working-directory: СеровАА/backend + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run backend tests + working-directory: СеровАА + run: | + python -m pytest tests/test_backend.py -v --tb=short + + test-worker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install worker dependencies + working-directory: СеровАА/worker + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run worker tests + working-directory: СеровАА + run: | + python -m pytest tests/test_worker.py -v --tb=short + + # Необязательная проверка: собрать Docker Compose (без запуска) + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker images + working-directory: СеровАА + run: docker compose build From 72da0618507484dd4896accfceebfb9d4e9d08ba Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:36:16 +0300 Subject: [PATCH 12/56] Create test_backend.py --- .../password-generator/tests/test_backend.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SerovAA/password-generator/tests/test_backend.py diff --git a/SerovAA/password-generator/tests/test_backend.py b/SerovAA/password-generator/tests/test_backend.py new file mode 100644 index 0000000..49e95eb --- /dev/null +++ b/SerovAA/password-generator/tests/test_backend.py @@ -0,0 +1,26 @@ +import pytest +import json +from backend.app import app + +@pytest.fixture +def client(): + app.config['TESTING'] = True + with app.test_client() as client: + yield client + +def test_generate_endpoint_returns_task_id(client): + response = client.post('/api/generate', + json={'length': 10, 'use_digits': True, 'use_special': False}) + assert response.status_code == 200 + data = json.loads(response.data) + assert 'task_id' in data + assert len(data['task_id']) > 0 + +def test_result_endpoint_for_nonexistent_task(client): + response = client.get('/api/result/nonexistent-id-123') + assert response.status_code == 404 + +def test_generate_with_invalid_json(client): + response = client.post('/api/generate', data='invalid', content_type='application/json') + # Flask вернёт 400 или 500 — в зависимости, но главное не 200 + assert response.status_code != 200 From dadb8b9ac8e0fb0f43d5195b67b207272427b2a7 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:36:52 +0300 Subject: [PATCH 13/56] Create test_worker.py --- .../password-generator/tests/test_worker.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 SerovAA/password-generator/tests/test_worker.py diff --git a/SerovAA/password-generator/tests/test_worker.py b/SerovAA/password-generator/tests/test_worker.py new file mode 100644 index 0000000..3d137e3 --- /dev/null +++ b/SerovAA/password-generator/tests/test_worker.py @@ -0,0 +1,24 @@ +import pytest +from worker.worker import generate_password + +def test_generate_password_default(): + pwd = generate_password(12, True, True) + assert len(pwd) == 12 + # должна содержать хотя бы одну букву и одну цифру (если digits true) + assert any(c.isalpha() for c in pwd) + assert any(c.isdigit() for c in pwd) + +def test_generate_password_no_digits(): + pwd = generate_password(8, use_digits=False, use_special=False) + assert len(pwd) == 8 + assert not any(c.isdigit() for c in pwd) + assert not any(c in '!@#$%^&*()' for c in pwd) + +def test_generate_password_only_letters(): + pwd = generate_password(10, use_digits=False, use_special=False) + assert pwd.isalpha() + +def test_generate_password_with_special(): + pwd = generate_password(15, use_digits=False, use_special=True) + specials = set('!@#$%^&*()') + assert any(c in specials for c in pwd) From 032fb294b1a256e8d49f3f7a3ea57bbc69c7ca07 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:37:35 +0300 Subject: [PATCH 14/56] Create requirements-dev.txt --- SerovAA/password-generator/requirements-dev.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 SerovAA/password-generator/requirements-dev.txt diff --git a/SerovAA/password-generator/requirements-dev.txt b/SerovAA/password-generator/requirements-dev.txt new file mode 100644 index 0000000..acdca76 --- /dev/null +++ b/SerovAA/password-generator/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest==7.4.3 +pytest-cov==4.1.0 From dfe0e8ae26439389b3f44a9c05ebf24d1134ae3d Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:38:09 +0300 Subject: [PATCH 15/56] Update README.md --- SerovAA/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SerovAA/README.md b/SerovAA/README.md index 9192853..de8a03f 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -36,6 +36,20 @@ curl http://localhost:8080/api/generate -X POST -H "Content-Type: application/js ### Останавливаем docker compose down +## CI/CD Pipeline + +Проект использует **GitHub Actions** для автоматической проверки при pull request в `main` ветку. + +### Что проверяется: +- ✅ Корректность API (backend тесты) +- ✅ Генерация паролей (worker тесты) +- ✅ Сборка Docker образов (docker compose build) + +### Как запустить тесты локально: +```bash +pip install pytest +pytest tests/ + ---- ## Особенности решения: From 4925e67654590a272b9bd472ba490f90c5321591 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:51:54 +0300 Subject: [PATCH 16/56] Create docker-compose.yml --- SerovAA/docker-compose.yml | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SerovAA/docker-compose.yml diff --git a/SerovAA/docker-compose.yml b/SerovAA/docker-compose.yml new file mode 100644 index 0000000..960b21f --- /dev/null +++ b/SerovAA/docker-compose.yml @@ -0,0 +1,41 @@ +version: '3.8' + +services: + nginx: + image: nginx:alpine + ports: + - "8080:80" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./frontend:/usr/share/nginx/html + depends_on: + - backend + networks: + - app-network + + backend: + build: ./backend + environment: + - REDIS_HOST=redis + depends_on: + - redis + networks: + - app-network + + worker: + build: ./worker + environment: + - REDIS_HOST=redis + depends_on: + - redis + networks: + - app-network + + redis: + image: redis:alpine + networks: + - app-network + +networks: + app-network: + driver: bridge From 6b07ab3d86ce2a94630c2ea5dafe7cc0c8b9b815 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:52:12 +0300 Subject: [PATCH 17/56] Create requirements-dev.txt --- SerovAA/requirements-dev.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 SerovAA/requirements-dev.txt diff --git a/SerovAA/requirements-dev.txt b/SerovAA/requirements-dev.txt new file mode 100644 index 0000000..acdca76 --- /dev/null +++ b/SerovAA/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest==7.4.3 +pytest-cov==4.1.0 From 3428104bca3c4066a707a18781eb539413da4984 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:52:53 +0300 Subject: [PATCH 18/56] Create worker.py --- SerovAA/worker/worker.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 SerovAA/worker/worker.py diff --git a/SerovAA/worker/worker.py b/SerovAA/worker/worker.py new file mode 100644 index 0000000..0e057c1 --- /dev/null +++ b/SerovAA/worker/worker.py @@ -0,0 +1,37 @@ +import redis +import json +import random +import string +import os +import time + +redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) + +def generate_password(length, use_digits, use_special): + chars = string.ascii_letters + if use_digits: + chars += string.digits + if use_special: + chars += '!@#$%^&*()' + return ''.join(random.choice(chars) for _ in range(length)) + +while True: + task_id = redis_client.brpop('password_tasks')[1].decode() + + # Simulate long processing + time.sleep(2) + + task_data = json.loads(redis_client.get(f"task:{task_id}")) + try: + password = generate_password( + task_data['length'], + task_data['use_digits'], + task_data['use_special'] + ) + task_data['status'] = 'completed' + task_data['password'] = password + except Exception as e: + task_data['status'] = 'failed' + task_data['error'] = str(e) + + redis_client.set(f"task:{task_id}", json.dumps(task_data)) From 5af2c2c849a2bed9ace5a3b1c998cebe3f1678c0 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:53:11 +0300 Subject: [PATCH 19/56] Create requirements.txt --- SerovAA/worker/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 SerovAA/worker/requirements.txt diff --git a/SerovAA/worker/requirements.txt b/SerovAA/worker/requirements.txt new file mode 100644 index 0000000..785cc92 --- /dev/null +++ b/SerovAA/worker/requirements.txt @@ -0,0 +1 @@ +redis==5.0.1 From 651c36fac1bb754a3318680ccdd619d431c4941a Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:53:23 +0300 Subject: [PATCH 20/56] Create Dockerfile --- SerovAA/worker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SerovAA/worker/Dockerfile diff --git a/SerovAA/worker/Dockerfile b/SerovAA/worker/Dockerfile new file mode 100644 index 0000000..d55b117 --- /dev/null +++ b/SerovAA/worker/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY worker.py . +CMD ["python", "worker.py"] From 0fb6a518e1334b2b0c3498e406e85057528571de Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:54:23 +0300 Subject: [PATCH 21/56] Create test_backend.py --- SerovAA/tests/test_backend.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SerovAA/tests/test_backend.py diff --git a/SerovAA/tests/test_backend.py b/SerovAA/tests/test_backend.py new file mode 100644 index 0000000..49e95eb --- /dev/null +++ b/SerovAA/tests/test_backend.py @@ -0,0 +1,26 @@ +import pytest +import json +from backend.app import app + +@pytest.fixture +def client(): + app.config['TESTING'] = True + with app.test_client() as client: + yield client + +def test_generate_endpoint_returns_task_id(client): + response = client.post('/api/generate', + json={'length': 10, 'use_digits': True, 'use_special': False}) + assert response.status_code == 200 + data = json.loads(response.data) + assert 'task_id' in data + assert len(data['task_id']) > 0 + +def test_result_endpoint_for_nonexistent_task(client): + response = client.get('/api/result/nonexistent-id-123') + assert response.status_code == 404 + +def test_generate_with_invalid_json(client): + response = client.post('/api/generate', data='invalid', content_type='application/json') + # Flask вернёт 400 или 500 — в зависимости, но главное не 200 + assert response.status_code != 200 From 62d37705a0dacbdbbf2915f486e9a1372299606f Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:54:40 +0300 Subject: [PATCH 22/56] Create test_worker.py --- SerovAA/tests/test_worker.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 SerovAA/tests/test_worker.py diff --git a/SerovAA/tests/test_worker.py b/SerovAA/tests/test_worker.py new file mode 100644 index 0000000..3d137e3 --- /dev/null +++ b/SerovAA/tests/test_worker.py @@ -0,0 +1,24 @@ +import pytest +from worker.worker import generate_password + +def test_generate_password_default(): + pwd = generate_password(12, True, True) + assert len(pwd) == 12 + # должна содержать хотя бы одну букву и одну цифру (если digits true) + assert any(c.isalpha() for c in pwd) + assert any(c.isdigit() for c in pwd) + +def test_generate_password_no_digits(): + pwd = generate_password(8, use_digits=False, use_special=False) + assert len(pwd) == 8 + assert not any(c.isdigit() for c in pwd) + assert not any(c in '!@#$%^&*()' for c in pwd) + +def test_generate_password_only_letters(): + pwd = generate_password(10, use_digits=False, use_special=False) + assert pwd.isalpha() + +def test_generate_password_with_special(): + pwd = generate_password(15, use_digits=False, use_special=True) + specials = set('!@#$%^&*()') + assert any(c in specials for c in pwd) From a84b658df88e77781fe71cd4c450783c152ff3db Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:55:03 +0300 Subject: [PATCH 23/56] Create nginx.conf --- SerovAA/nginx/nginx.conf | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SerovAA/nginx/nginx.conf diff --git a/SerovAA/nginx/nginx.conf b/SerovAA/nginx/nginx.conf new file mode 100644 index 0000000..8b8e9a7 --- /dev/null +++ b/SerovAA/nginx/nginx.conf @@ -0,0 +1,26 @@ +events { + worker_connections 1024; +} + +http { + upstream backend { + server backend:5000; + } + + server { + listen 80; + + # Frontend + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + # Backend API + location /api/ { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + } +} From 12b5306ee387ccf0b893c923c36a69b723222912 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:55:28 +0300 Subject: [PATCH 24/56] Create index.html --- SerovAA/frontend/index.html | 73 +++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 SerovAA/frontend/index.html diff --git a/SerovAA/frontend/index.html b/SerovAA/frontend/index.html new file mode 100644 index 0000000..c5e87cf --- /dev/null +++ b/SerovAA/frontend/index.html @@ -0,0 +1,73 @@ + + + + Password Generator + + + +

🔐 Password Generator

+ +
+
+
+ + + + +
+ Password: -
+ Task ID: -
+ Status: Idle +
+ + + + From 53caba2a9b26c2c5d9c85ca21d73626cab8233a1 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:55:59 +0300 Subject: [PATCH 25/56] Create Dockerfile --- SerovAA/backend/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SerovAA/backend/Dockerfile diff --git a/SerovAA/backend/Dockerfile b/SerovAA/backend/Dockerfile new file mode 100644 index 0000000..6113261 --- /dev/null +++ b/SerovAA/backend/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY app.py . +CMD ["python", "app.py"] From b72784843510f3cc0c8dbf38fcaae2cc3595159d Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:56:15 +0300 Subject: [PATCH 26/56] Create app.py --- SerovAA/backend/app.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 SerovAA/backend/app.py diff --git a/SerovAA/backend/app.py b/SerovAA/backend/app.py new file mode 100644 index 0000000..9b1c62c --- /dev/null +++ b/SerovAA/backend/app.py @@ -0,0 +1,36 @@ +from flask import Flask, request, jsonify +import redis +import uuid +import json +import os + +app = Flask(__name__) +redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) + +@app.route('/api/generate', methods=['POST']) +def generate(): + data = request.json + task_id = str(uuid.uuid4()) + + task_data = { + 'status': 'pending', + 'length': data['length'], + 'use_digits': data['use_digits'], + 'use_special': data['use_special'] + } + + redis_client.set(f"task:{task_id}", json.dumps(task_data)) + redis_client.lpush('password_tasks', task_id) + + return jsonify({'task_id': task_id}) + +@app.route('/api/result/', methods=['GET']) +def result(task_id): + task_data = redis_client.get(f"task:{task_id}") + if task_data: + task = json.loads(task_data) + return jsonify(task) + return jsonify({'status': 'not_found'}), 404 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) From 25eedc59011a3fc74aa1eeca8846cc3bf3fe4838 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:56:30 +0300 Subject: [PATCH 27/56] Create requirements.txt --- SerovAA/backend/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 SerovAA/backend/requirements.txt diff --git a/SerovAA/backend/requirements.txt b/SerovAA/backend/requirements.txt new file mode 100644 index 0000000..bf804e5 --- /dev/null +++ b/SerovAA/backend/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.3.3 +redis==5.0.1 From e10e86c0db06c1c77ff543002d2eadb0d474ef2c Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:57:48 +0300 Subject: [PATCH 28/56] Create ci.yml --- SerovAA/.github/workflows/ci.yml | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 SerovAA/.github/workflows/ci.yml diff --git a/SerovAA/.github/workflows/ci.yml b/SerovAA/.github/workflows/ci.yml new file mode 100644 index 0000000..c45ed54 --- /dev/null +++ b/SerovAA/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI Pipeline + +on: + pull_request: + branches: [ main, master ] + +jobs: + test-backend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install backend dependencies + working-directory: СеровАА/backend + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run backend tests + working-directory: СеровАА + run: | + python -m pytest tests/test_backend.py -v --tb=short + + test-worker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install worker dependencies + working-directory: СеровАА/worker + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run worker tests + working-directory: СеровАА + run: | + python -m pytest tests/test_worker.py -v --tb=short + + # Необязательная проверка: собрать Docker Compose (без запуска) + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker images + working-directory: СеровАА + run: docker compose build From 04e37d0fe3258a29805fa391215266fefee0bd2a Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:57:59 +0300 Subject: [PATCH 29/56] Delete SerovAA/password-generator directory --- .../.github/workflows/ci.yml | 64 ---------------- SerovAA/password-generator/backend/Dockerfile | 6 -- SerovAA/password-generator/backend/app.py | 36 --------- .../backend/requirements.txt | 2 - SerovAA/password-generator/docker-compose.yml | 41 ----------- .../password-generator/frontend/index.html | 73 ------------------- SerovAA/password-generator/nginx/nginx.conf | 26 ------- .../password-generator/requirements-dev.txt | 2 - .../password-generator/tests/test_backend.py | 26 ------- .../password-generator/tests/test_worker.py | 24 ------ SerovAA/password-generator/worker/Dockerfile | 6 -- .../worker/requirements.txt | 1 - SerovAA/password-generator/worker/worker.py | 37 ---------- 13 files changed, 344 deletions(-) delete mode 100644 SerovAA/password-generator/.github/workflows/ci.yml delete mode 100644 SerovAA/password-generator/backend/Dockerfile delete mode 100644 SerovAA/password-generator/backend/app.py delete mode 100644 SerovAA/password-generator/backend/requirements.txt delete mode 100644 SerovAA/password-generator/docker-compose.yml delete mode 100644 SerovAA/password-generator/frontend/index.html delete mode 100644 SerovAA/password-generator/nginx/nginx.conf delete mode 100644 SerovAA/password-generator/requirements-dev.txt delete mode 100644 SerovAA/password-generator/tests/test_backend.py delete mode 100644 SerovAA/password-generator/tests/test_worker.py delete mode 100644 SerovAA/password-generator/worker/Dockerfile delete mode 100644 SerovAA/password-generator/worker/requirements.txt delete mode 100644 SerovAA/password-generator/worker/worker.py diff --git a/SerovAA/password-generator/.github/workflows/ci.yml b/SerovAA/password-generator/.github/workflows/ci.yml deleted file mode 100644 index c45ed54..0000000 --- a/SerovAA/password-generator/.github/workflows/ci.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: CI Pipeline - -on: - pull_request: - branches: [ main, master ] - -jobs: - test-backend: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install backend dependencies - working-directory: СеровАА/backend - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - - - name: Run backend tests - working-directory: СеровАА - run: | - python -m pytest tests/test_backend.py -v --tb=short - - test-worker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install worker dependencies - working-directory: СеровАА/worker - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - - - name: Run worker tests - working-directory: СеровАА - run: | - python -m pytest tests/test_worker.py -v --tb=short - - # Необязательная проверка: собрать Docker Compose (без запуска) - docker-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Build Docker images - working-directory: СеровАА - run: docker compose build diff --git a/SerovAA/password-generator/backend/Dockerfile b/SerovAA/password-generator/backend/Dockerfile deleted file mode 100644 index 6113261..0000000 --- a/SerovAA/password-generator/backend/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM python:3.11-slim -WORKDIR /app -COPY requirements.txt . -RUN pip install -r requirements.txt -COPY app.py . -CMD ["python", "app.py"] diff --git a/SerovAA/password-generator/backend/app.py b/SerovAA/password-generator/backend/app.py deleted file mode 100644 index 9b1c62c..0000000 --- a/SerovAA/password-generator/backend/app.py +++ /dev/null @@ -1,36 +0,0 @@ -from flask import Flask, request, jsonify -import redis -import uuid -import json -import os - -app = Flask(__name__) -redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) - -@app.route('/api/generate', methods=['POST']) -def generate(): - data = request.json - task_id = str(uuid.uuid4()) - - task_data = { - 'status': 'pending', - 'length': data['length'], - 'use_digits': data['use_digits'], - 'use_special': data['use_special'] - } - - redis_client.set(f"task:{task_id}", json.dumps(task_data)) - redis_client.lpush('password_tasks', task_id) - - return jsonify({'task_id': task_id}) - -@app.route('/api/result/', methods=['GET']) -def result(task_id): - task_data = redis_client.get(f"task:{task_id}") - if task_data: - task = json.loads(task_data) - return jsonify(task) - return jsonify({'status': 'not_found'}), 404 - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000) diff --git a/SerovAA/password-generator/backend/requirements.txt b/SerovAA/password-generator/backend/requirements.txt deleted file mode 100644 index bf804e5..0000000 --- a/SerovAA/password-generator/backend/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Flask==2.3.3 -redis==5.0.1 diff --git a/SerovAA/password-generator/docker-compose.yml b/SerovAA/password-generator/docker-compose.yml deleted file mode 100644 index 960b21f..0000000 --- a/SerovAA/password-generator/docker-compose.yml +++ /dev/null @@ -1,41 +0,0 @@ -version: '3.8' - -services: - nginx: - image: nginx:alpine - ports: - - "8080:80" - volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf - - ./frontend:/usr/share/nginx/html - depends_on: - - backend - networks: - - app-network - - backend: - build: ./backend - environment: - - REDIS_HOST=redis - depends_on: - - redis - networks: - - app-network - - worker: - build: ./worker - environment: - - REDIS_HOST=redis - depends_on: - - redis - networks: - - app-network - - redis: - image: redis:alpine - networks: - - app-network - -networks: - app-network: - driver: bridge diff --git a/SerovAA/password-generator/frontend/index.html b/SerovAA/password-generator/frontend/index.html deleted file mode 100644 index c5e87cf..0000000 --- a/SerovAA/password-generator/frontend/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Password Generator - - - -

🔐 Password Generator

- -
-
-
- - - - -
- Password: -
- Task ID: -
- Status: Idle -
- - - - diff --git a/SerovAA/password-generator/nginx/nginx.conf b/SerovAA/password-generator/nginx/nginx.conf deleted file mode 100644 index 8b8e9a7..0000000 --- a/SerovAA/password-generator/nginx/nginx.conf +++ /dev/null @@ -1,26 +0,0 @@ -events { - worker_connections 1024; -} - -http { - upstream backend { - server backend:5000; - } - - server { - listen 80; - - # Frontend - location / { - root /usr/share/nginx/html; - try_files $uri $uri/ /index.html; - } - - # Backend API - location /api/ { - proxy_pass http://backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - } - } -} diff --git a/SerovAA/password-generator/requirements-dev.txt b/SerovAA/password-generator/requirements-dev.txt deleted file mode 100644 index acdca76..0000000 --- a/SerovAA/password-generator/requirements-dev.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest==7.4.3 -pytest-cov==4.1.0 diff --git a/SerovAA/password-generator/tests/test_backend.py b/SerovAA/password-generator/tests/test_backend.py deleted file mode 100644 index 49e95eb..0000000 --- a/SerovAA/password-generator/tests/test_backend.py +++ /dev/null @@ -1,26 +0,0 @@ -import pytest -import json -from backend.app import app - -@pytest.fixture -def client(): - app.config['TESTING'] = True - with app.test_client() as client: - yield client - -def test_generate_endpoint_returns_task_id(client): - response = client.post('/api/generate', - json={'length': 10, 'use_digits': True, 'use_special': False}) - assert response.status_code == 200 - data = json.loads(response.data) - assert 'task_id' in data - assert len(data['task_id']) > 0 - -def test_result_endpoint_for_nonexistent_task(client): - response = client.get('/api/result/nonexistent-id-123') - assert response.status_code == 404 - -def test_generate_with_invalid_json(client): - response = client.post('/api/generate', data='invalid', content_type='application/json') - # Flask вернёт 400 или 500 — в зависимости, но главное не 200 - assert response.status_code != 200 diff --git a/SerovAA/password-generator/tests/test_worker.py b/SerovAA/password-generator/tests/test_worker.py deleted file mode 100644 index 3d137e3..0000000 --- a/SerovAA/password-generator/tests/test_worker.py +++ /dev/null @@ -1,24 +0,0 @@ -import pytest -from worker.worker import generate_password - -def test_generate_password_default(): - pwd = generate_password(12, True, True) - assert len(pwd) == 12 - # должна содержать хотя бы одну букву и одну цифру (если digits true) - assert any(c.isalpha() for c in pwd) - assert any(c.isdigit() for c in pwd) - -def test_generate_password_no_digits(): - pwd = generate_password(8, use_digits=False, use_special=False) - assert len(pwd) == 8 - assert not any(c.isdigit() for c in pwd) - assert not any(c in '!@#$%^&*()' for c in pwd) - -def test_generate_password_only_letters(): - pwd = generate_password(10, use_digits=False, use_special=False) - assert pwd.isalpha() - -def test_generate_password_with_special(): - pwd = generate_password(15, use_digits=False, use_special=True) - specials = set('!@#$%^&*()') - assert any(c in specials for c in pwd) diff --git a/SerovAA/password-generator/worker/Dockerfile b/SerovAA/password-generator/worker/Dockerfile deleted file mode 100644 index d55b117..0000000 --- a/SerovAA/password-generator/worker/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM python:3.11-slim -WORKDIR /app -COPY requirements.txt . -RUN pip install -r requirements.txt -COPY worker.py . -CMD ["python", "worker.py"] diff --git a/SerovAA/password-generator/worker/requirements.txt b/SerovAA/password-generator/worker/requirements.txt deleted file mode 100644 index 785cc92..0000000 --- a/SerovAA/password-generator/worker/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -redis==5.0.1 diff --git a/SerovAA/password-generator/worker/worker.py b/SerovAA/password-generator/worker/worker.py deleted file mode 100644 index 0e057c1..0000000 --- a/SerovAA/password-generator/worker/worker.py +++ /dev/null @@ -1,37 +0,0 @@ -import redis -import json -import random -import string -import os -import time - -redis_client = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379, db=0) - -def generate_password(length, use_digits, use_special): - chars = string.ascii_letters - if use_digits: - chars += string.digits - if use_special: - chars += '!@#$%^&*()' - return ''.join(random.choice(chars) for _ in range(length)) - -while True: - task_id = redis_client.brpop('password_tasks')[1].decode() - - # Simulate long processing - time.sleep(2) - - task_data = json.loads(redis_client.get(f"task:{task_id}")) - try: - password = generate_password( - task_data['length'], - task_data['use_digits'], - task_data['use_special'] - ) - task_data['status'] = 'completed' - task_data['password'] = password - except Exception as e: - task_data['status'] = 'failed' - task_data['error'] = str(e) - - redis_client.set(f"task:{task_id}", json.dumps(task_data)) From 6c73ba922e36d36796197aaf32e2d193bd16f150 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:58:17 +0300 Subject: [PATCH 30/56] Update README.md --- SerovAA/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SerovAA/README.md b/SerovAA/README.md index de8a03f..4ac54d0 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -51,6 +51,7 @@ pip install pytest pytest tests/ ---- + ## Особенности решения: ✅ Одна точка входа — Nginx на порту 8080 From d30b8b079508b492d138b1747cde733dabe263ea Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:58:32 +0300 Subject: [PATCH 31/56] Update README.md --- SerovAA/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 4ac54d0..cacc8cb 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -50,8 +50,6 @@ docker compose down pip install pytest pytest tests/ ----- - ## Особенности решения: ✅ Одна точка входа — Nginx на порту 8080 From 68fa672cdd2d8720cc4907e9a45f21274b3e92e8 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:59:00 +0300 Subject: [PATCH 32/56] Update README.md From c09e3aeffd2da8bd9adb83f9b7fc597e6ca66120 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:59:11 +0300 Subject: [PATCH 33/56] Update README.md --- SerovAA/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index cacc8cb..548120f 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -48,7 +48,7 @@ docker compose down ### Как запустить тесты локально: ```bash pip install pytest -pytest tests/ +pytest tests/''' ## Особенности решения: From addfc4bc5a7608a4a27a8d36db865f5f07483991 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 18:59:24 +0300 Subject: [PATCH 34/56] Update README.md --- SerovAA/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 548120f..6a761dc 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -48,7 +48,7 @@ docker compose down ### Как запустить тесты локально: ```bash pip install pytest -pytest tests/''' +pytest tests/``` ## Особенности решения: From 9e808a576212ea22aaf4ae24ac54d9c44eeab578 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:00:00 +0300 Subject: [PATCH 35/56] Update README.md --- SerovAA/README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 6a761dc..8671778 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -50,14 +50,11 @@ docker compose down pip install pytest pytest tests/``` +---- ## Особенности решения: -✅ Одна точка входа — Nginx на порту 8080 - -✅ Все сервисы в одной сети Docker - -✅ Worker выполняет "длительные задачи" (generation с delay) - -✅ Готово к запуску одной командой docker compose up - -✅ Полностью микросервисный (frontend, backend, worker, redis) +- ✅ Одна точка входа — Nginx на порту 8080 +- ✅ Все сервисы в одной сети Docker +- ✅ Worker выполняет "длительные задачи" (generation с delay) +- ✅ Готово к запуску одной командой docker compose up +- ✅ Полностью микросервисный (frontend, backend, worker, redis) From 8e8b8597a527d04bdf9e5e7bd13be07db4b62b6e Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:00:12 +0300 Subject: [PATCH 36/56] Update README.md --- SerovAA/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 8671778..b97580a 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -46,9 +46,9 @@ docker compose down - ✅ Сборка Docker образов (docker compose build) ### Как запустить тесты локально: -```bash +bash pip install pytest -pytest tests/``` +pytest tests/ ---- ## Особенности решения: From 952c57240d80a5d6ee75895d49523e49cb9504c4 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:00:24 +0300 Subject: [PATCH 37/56] Update README.md --- SerovAA/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index b97580a..c5d7f94 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -46,9 +46,9 @@ docker compose down - ✅ Сборка Docker образов (docker compose build) ### Как запустить тесты локально: -bash +''bash pip install pytest -pytest tests/ +pytest tests/'' ---- ## Особенности решения: From c10e6f3d3fc4655a12ece8fa899347f89b1b6f9c Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:00:39 +0300 Subject: [PATCH 38/56] Update README.md --- SerovAA/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index c5d7f94..8c1663d 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -46,9 +46,9 @@ docker compose down - ✅ Сборка Docker образов (docker compose build) ### Как запустить тесты локально: -''bash +'''bash pip install pytest -pytest tests/'' +pytest tests/''' ---- ## Особенности решения: From 19bbb652e8f5f670299decb5e7c2f8a2e9e28390 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:01:14 +0300 Subject: [PATCH 39/56] Update README.md --- SerovAA/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 8c1663d..8d5dd3f 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -46,9 +46,9 @@ docker compose down - ✅ Сборка Docker образов (docker compose build) ### Как запустить тесты локально: -'''bash -pip install pytest -pytest tests/''' +- bash +- pip install pytest +- pytest tests/ ---- ## Особенности решения: From a45350df714d7d2abbd1a26aeb4cd39973bb3795 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:07:29 +0300 Subject: [PATCH 40/56] Update ci.yml --- SerovAA/.github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SerovAA/.github/workflows/ci.yml b/SerovAA/.github/workflows/ci.yml index c45ed54..f454988 100644 --- a/SerovAA/.github/workflows/ci.yml +++ b/SerovAA/.github/workflows/ci.yml @@ -1,6 +1,8 @@ name: CI Pipeline on: + push: + branches: [ main, master ] pull_request: branches: [ main, master ] From 2716fc0224416a691356dd0d3e7311e109ceb173 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:08:37 +0300 Subject: [PATCH 41/56] Update ci.yml --- SerovAA/.github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SerovAA/.github/workflows/ci.yml b/SerovAA/.github/workflows/ci.yml index f454988..a9aaa55 100644 --- a/SerovAA/.github/workflows/ci.yml +++ b/SerovAA/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: python-version: '3.11' - name: Install backend dependencies - working-directory: СеровАА/backend + working-directory: SerovAA/backend run: | python -m pip install --upgrade pip pip install -r requirements.txt @@ -27,7 +27,7 @@ jobs: run: pip install pytest pytest-cov - name: Run backend tests - working-directory: СеровАА + working-directory: SerovAA run: | python -m pytest tests/test_backend.py -v --tb=short @@ -42,7 +42,7 @@ jobs: python-version: '3.11' - name: Install worker dependencies - working-directory: СеровАА/worker + working-directory: SerovAA/worker run: | python -m pip install --upgrade pip pip install -r requirements.txt @@ -51,7 +51,7 @@ jobs: run: pip install pytest pytest-cov - name: Run worker tests - working-directory: СеровАА + working-directory: SerovAA run: | python -m pytest tests/test_worker.py -v --tb=short @@ -62,5 +62,5 @@ jobs: - uses: actions/checkout@v4 - name: Build Docker images - working-directory: СеровАА + working-directory: SerovAA run: docker compose build From 8e4e519cd7e5041303a21160390dd1399295d9a1 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:22:40 +0300 Subject: [PATCH 42/56] Create ci.yml --- .github/workflows/ci.yml | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a9aaa55 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +name: CI Pipeline + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + test-backend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install backend dependencies + working-directory: SerovAA/backend + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run backend tests + working-directory: SerovAA + run: | + python -m pytest tests/test_backend.py -v --tb=short + + test-worker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install worker dependencies + working-directory: SerovAA/worker + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Install dev dependencies + run: pip install pytest pytest-cov + + - name: Run worker tests + working-directory: SerovAA + run: | + python -m pytest tests/test_worker.py -v --tb=short + + # Необязательная проверка: собрать Docker Compose (без запуска) + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker images + working-directory: SerovAA + run: docker compose build From f1d664c1f92bd331b412b4f601c4b619efd9a760 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:32:04 +0300 Subject: [PATCH 43/56] Delete SerovAA/.github/workflows directory --- SerovAA/.github/workflows/ci.yml | 66 -------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 SerovAA/.github/workflows/ci.yml diff --git a/SerovAA/.github/workflows/ci.yml b/SerovAA/.github/workflows/ci.yml deleted file mode 100644 index a9aaa55..0000000 --- a/SerovAA/.github/workflows/ci.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: CI Pipeline - -on: - push: - branches: [ main, master ] - pull_request: - branches: [ main, master ] - -jobs: - test-backend: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install backend dependencies - working-directory: SerovAA/backend - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - - - name: Run backend tests - working-directory: SerovAA - run: | - python -m pytest tests/test_backend.py -v --tb=short - - test-worker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install worker dependencies - working-directory: SerovAA/worker - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - - - name: Run worker tests - working-directory: SerovAA - run: | - python -m pytest tests/test_worker.py -v --tb=short - - # Необязательная проверка: собрать Docker Compose (без запуска) - docker-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Build Docker images - working-directory: SerovAA - run: docker compose build From 3248d6332e224605cfb9c55265c1edb92834c949 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:36:42 +0300 Subject: [PATCH 44/56] Update ci.yml --- .github/workflows/ci.yml | 67 +++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9aaa55..80a5b67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,58 +9,69 @@ on: jobs: test-backend: runs-on: ubuntu-latest + services: + redis: + image: redis:alpine + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 + - uses: actions/setup-python@v5 with: python-version: '3.11' - - - name: Install backend dependencies + - name: Install dependencies working-directory: SerovAA/backend - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - + run: pip install -r requirements.txt + - name: Install pytest + run: pip install pytest - name: Run backend tests working-directory: SerovAA run: | - python -m pytest tests/test_backend.py -v --tb=short + # Ждём Redis (хотя healthcheck уже есть, на всякий случай) + sleep 2 + PYTHONPATH=. python -m pytest tests/test_backend.py -v --tb=short + env: + REDIS_HOST: localhost # чтобы backend точно знал, где Redis test-worker: runs-on: ubuntu-latest + services: + redis: + image: redis:alpine + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 + - uses: actions/setup-python@v5 with: python-version: '3.11' - - - name: Install worker dependencies + - name: Install dependencies working-directory: SerovAA/worker - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install dev dependencies - run: pip install pytest pytest-cov - + run: pip install -r requirements.txt + - name: Install pytest + run: pip install pytest - name: Run worker tests working-directory: SerovAA run: | - python -m pytest tests/test_worker.py -v --tb=short + sleep 2 + PYTHONPATH=. python -m pytest tests/test_worker.py -v --tb=short + env: + REDIS_HOST: localhost - # Необязательная проверка: собрать Docker Compose (без запуска) docker-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Build Docker images working-directory: SerovAA run: docker compose build From cca7fe203d645b8772c814fb5f20295b90a0f648 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:43:32 +0300 Subject: [PATCH 45/56] Update worker.py --- SerovAA/worker/worker.py | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/SerovAA/worker/worker.py b/SerovAA/worker/worker.py index 0e057c1..5b150af 100644 --- a/SerovAA/worker/worker.py +++ b/SerovAA/worker/worker.py @@ -15,23 +15,22 @@ def generate_password(length, use_digits, use_special): chars += '!@#$%^&*()' return ''.join(random.choice(chars) for _ in range(length)) -while True: - task_id = redis_client.brpop('password_tasks')[1].decode() - - # Simulate long processing - time.sleep(2) - - task_data = json.loads(redis_client.get(f"task:{task_id}")) - try: - password = generate_password( - task_data['length'], - task_data['use_digits'], - task_data['use_special'] - ) - task_data['status'] = 'completed' - task_data['password'] = password - except Exception as e: - task_data['status'] = 'failed' - task_data['error'] = str(e) - - redis_client.set(f"task:{task_id}", json.dumps(task_data)) +# Этот код будет выполняться ТОЛЬКО при запуске worker.py как скрипта, +# но НЕ при импорте из тестов +if __name__ == "__main__": + while True: + task_id = redis_client.brpop('password_tasks')[1].decode() + time.sleep(2) # имитация долгой обработки + task_data = json.loads(redis_client.get(f"task:{task_id}")) + try: + password = generate_password( + task_data['length'], + task_data['use_digits'], + task_data['use_special'] + ) + task_data['status'] = 'completed' + task_data['password'] = password + except Exception as e: + task_data['status'] = 'failed' + task_data['error'] = str(e) + redis_client.set(f"task:{task_id}", json.dumps(task_data)) From 0fa9b97c253c482509c1f72ecd77814a2a239be3 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:49:38 +0300 Subject: [PATCH 46/56] Update README.md --- SerovAA/README.md | 97 +++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 8d5dd3f..6c7fca5 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -1,60 +1,73 @@ -# Password Generator - Microservices Demo +# Password Generator — микросервисное веб-приложение -## Architecture -- **Nginx**: Reverse proxy and static frontend server -- **Frontend**: HTML/JS UI served by Nginx -- **Backend (Flask)**: API endpoint for generating password tasks -- **Worker (Python)**: Long-running password generation service -- **Redis**: Task queue and result storage +## Описание проекта -## Run +Генератор паролей с микросервисной архитектурой. +Состоит из пяти компонентов: +- **Nginx** — обратный прокси и точка входа (порт 8080) +- **Frontend** — статический HTML/JS интерфейс +- **Backend (Flask)** — API для создания задач генерации паролей +- **Worker** — фоновый сервис, выполняющий длительную генерацию +- **Redis** — брокер задач и хранилище результатов + +## Запуск + +bash docker compose up -d +Приложение будет доступно по адресу: http://localhost:8080 + +## Остановить: -## How it works -- Frontend submits generation request to backend API -- Backend creates task in Redis and returns task_id -- Worker picks up task from Redis queue -- Worker generates password (simulated 2s delay) -- Frontend polls for result and displays password +bash +docker compose down ----- -## Проверка работоспособности +## Взаимодействие сервисов +Пользователь вводит параметры пароля (длина, цифры, спецсимволы) и нажимает «Generate». -### Клонируем репозиторий -1. git clone https://github.com/SoftwareEngineering2026/Practice105.git -2. cd Practice105/SerovAA/ +Frontend отправляет POST-запрос на /api/generate в Backend. -### Создаём структуру и файлы (скопируй вышеуказанные файлы) +Backend создаёт задачу в Redis и возвращает task_id. -### Запускаем -docker compose up -d +Worker забирает задачу из очереди, генерирует пароль (с имитацией задержки 2 сек) и сохраняет результат. -### Проверяем -curl http://localhost:8080/api/generate -X POST -H "Content-Type: application/json" -d '{"length": 16, "use_digits": true, "use_special": true}' +Frontend каждую секунду опрашивает /api/result/ и отображает пароль. -### Останавливаем -docker compose down +## Проверка работоспособности (curl) +Создать задачу на генерацию пароля: + +bash +curl -X POST http://localhost:8080/api/generate \ + -H "Content-Type: application/json" \ + -d '{"length": 16, "use_digits": true, "use_special": true}' +Получить результат по task_id (подставьте полученный идентификатор): + +bash +curl http://localhost:8080/api/result/ ## CI/CD Pipeline +При создании pull request в ветку main автоматически запускается GitHub Actions workflow: + +- Установка зависимостей для Backend и Worker +- Запуск тестов (pytest) для обоих сервисов +- Проверка сборки Docker Compose + +Статус CI: https://github.com/SoftwareEngineering2026/Practice106/actions/workflows/ci-serovaa.yml/badge.svg + +## Локальный запуск тестов +* bash +* pip install pytest +* pytest tests/ + +## Особенности реализации +✅ Единая точка входа — Nginx (порт 8080) -Проект использует **GitHub Actions** для автоматической проверки при pull request в `main` ветку. +✅ Все сервисы общаются через внутреннюю сеть Docker -### Что проверяется: -- ✅ Корректность API (backend тесты) -- ✅ Генерация паролей (worker тесты) -- ✅ Сборка Docker образов (docker compose build) +✅ Длительные задачи вынесены в отдельный Worker (не блокируют Backend) -### Как запустить тесты локально: -- bash -- pip install pytest -- pytest tests/ +✅ Полностью микросервисная архитектура ----- -## Особенности решения: +✅ Запуск одной командой docker compose up -- ✅ Одна точка входа — Nginx на порту 8080 -- ✅ Все сервисы в одной сети Docker -- ✅ Worker выполняет "длительные задачи" (generation с delay) -- ✅ Готово к запуску одной командой docker compose up -- ✅ Полностью микросервисный (frontend, backend, worker, redis) +✅ Автоматическое CI-тестирование при Pull Request From 52ee81a39e01c716020b87400bbceee3e441e2c0 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:49:59 +0300 Subject: [PATCH 47/56] Update README.md --- SerovAA/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 6c7fca5..72a5ada 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -14,13 +14,13 @@ ## Запуск bash -docker compose up -d +- docker compose up -d Приложение будет доступно по адресу: http://localhost:8080 ## Остановить: bash -docker compose down +- docker compose down ## Взаимодействие сервисов Пользователь вводит параметры пароля (длина, цифры, спецсимволы) и нажимает «Generate». From 39658c5a7c0007c93e69b62acd1b5e7e746a15fd Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:50:07 +0300 Subject: [PATCH 48/56] Update README.md --- SerovAA/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SerovAA/README.md b/SerovAA/README.md index 72a5ada..c6c2b27 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -15,6 +15,7 @@ bash - docker compose up -d + Приложение будет доступно по адресу: http://localhost:8080 ## Остановить: From 4f10ac5434f139b198c21363c17ef24d3bccaac4 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:56:08 +0300 Subject: [PATCH 49/56] Update README.md --- SerovAA/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index c6c2b27..950f8b8 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -25,13 +25,9 @@ bash ## Взаимодействие сервисов Пользователь вводит параметры пароля (длина, цифры, спецсимволы) и нажимает «Generate». - Frontend отправляет POST-запрос на /api/generate в Backend. - Backend создаёт задачу в Redis и возвращает task_id. - Worker забирает задачу из очереди, генерирует пароль (с имитацией задержки 2 сек) и сохраняет результат. - Frontend каждую секунду опрашивает /api/result/ и отображает пароль. ## Проверка работоспособности (curl) From b5cf90e9bbce8139738eba6f8c9cce1118ec572b Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 19:56:25 +0300 Subject: [PATCH 50/56] Update README.md --- SerovAA/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index 950f8b8..a9de0c5 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -24,11 +24,11 @@ bash - docker compose down ## Взаимодействие сервисов -Пользователь вводит параметры пароля (длина, цифры, спецсимволы) и нажимает «Generate». -Frontend отправляет POST-запрос на /api/generate в Backend. -Backend создаёт задачу в Redis и возвращает task_id. -Worker забирает задачу из очереди, генерирует пароль (с имитацией задержки 2 сек) и сохраняет результат. -Frontend каждую секунду опрашивает /api/result/ и отображает пароль. +- Пользователь вводит параметры пароля (длина, цифры, спецсимволы) и нажимает «Generate». +- Frontend отправляет POST-запрос на /api/generate в Backend. +- Backend создаёт задачу в Redis и возвращает task_id. +- Worker забирает задачу из очереди, генерирует пароль (с имитацией задержки 2 сек) и сохраняет результат. +- Frontend каждую секунду опрашивает /api/result/ и отображает пароль. ## Проверка работоспособности (curl) Создать задачу на генерацию пароля: From 2f2e78392ea5aa6510252390160dca42ceab0a08 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:00:42 +0300 Subject: [PATCH 51/56] Update README.md --- SerovAA/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SerovAA/README.md b/SerovAA/README.md index a9de0c5..e35d0e1 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -58,13 +58,8 @@ curl http://localhost:8080/api/result/ ## Особенности реализации ✅ Единая точка входа — Nginx (порт 8080) - ✅ Все сервисы общаются через внутреннюю сеть Docker - ✅ Длительные задачи вынесены в отдельный Worker (не блокируют Backend) - ✅ Полностью микросервисная архитектура - ✅ Запуск одной командой docker compose up - ✅ Автоматическое CI-тестирование при Pull Request From c34a17caef7ea5b6719a51a79f9c20bb59af5a9f Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:01:26 +0300 Subject: [PATCH 52/56] Update README.md --- SerovAA/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SerovAA/README.md b/SerovAA/README.md index e35d0e1..a9de0c5 100644 --- a/SerovAA/README.md +++ b/SerovAA/README.md @@ -58,8 +58,13 @@ curl http://localhost:8080/api/result/ ## Особенности реализации ✅ Единая точка входа — Nginx (порт 8080) + ✅ Все сервисы общаются через внутреннюю сеть Docker + ✅ Длительные задачи вынесены в отдельный Worker (не блокируют Backend) + ✅ Полностью микросервисная архитектура + ✅ Запуск одной командой docker compose up + ✅ Автоматическое CI-тестирование при Pull Request From f365627c8ae369d0bbcb2e99f4dc7ccdd7b45c00 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:13:12 +0300 Subject: [PATCH 53/56] Create success.png --- SerovAA/screenshots/success.png | 1 + 1 file changed, 1 insertion(+) create mode 100644 SerovAA/screenshots/success.png diff --git a/SerovAA/screenshots/success.png b/SerovAA/screenshots/success.png new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/SerovAA/screenshots/success.png @@ -0,0 +1 @@ + From 9a9668102b1834a621450dc123df4f925462cd46 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:13:47 +0300 Subject: [PATCH 54/56] Add files via upload --- SerovAA/screenshots/success.png | Bin 1 -> 88166 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/SerovAA/screenshots/success.png b/SerovAA/screenshots/success.png index 8b137891791fe96927ad78e64b0aad7bded08bdc..de3ee935f3408ac7b7f772102fae3450a842f596 100644 GIT binary patch literal 88166 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�pGJtx#nl#`- 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 literal 1 Icmd-A000XB3jhEB From ef9b3939c3fa2caf54589ed98ac52029aad72895 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:14:54 +0300 Subject: [PATCH 55/56] Add files via upload --- SerovAA/screenshots/errors.png | Bin 0 -> 86963 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SerovAA/screenshots/errors.png diff --git a/SerovAA/screenshots/errors.png b/SerovAA/screenshots/errors.png new file mode 100644 index 0000000000000000000000000000000000000000..40d630217eddae05b6fd6dba71488d8207b9ca1a GIT binary patch literal 86963 zcmdqIXH-*L7dDD|5CMUsf*@6;2?&UE5D<|PklwrW5_$^+0>_F{rAzNM^j?F4^d>C< zLQyH91*9cFNVuE#c)s!dynpVW%NUHkc9OmJT64`c%k#|jQAbOahKiYrjEsy1r1o5o zjEtN>Ms}s-+Ew5aN0iWA;Bv`VPxTpDPtp; zoBQJb5=f8hHyPP^A?UfHL7>(40xV?Y=)7;QIP!%n;XTOO9OmGhZ-S7B_{h{UsMhkp zWzcZte#>$E+27WTr61@W?is^Y@1s-(erIYT9=MOMz(<;VbkeJ=yk^&&FVgK^+>F?IGOyz<~bu_r)$rLgK$0vax3~bboIC3Fq9V z_|yKKEgi zoG~#Vwc8`#DF|;)tO}@i256?H_Tb=|iTsA@4jL&)?CQ|Qs4V|_47wxAQs=|Oq-bJR zR%I0UPOBnEOP_$DI=_Bv)L^n8yw+ieiSf_in|l~EW;`XVr&A9~2Zx8JtlI@j+Kr_b z0?bX59tS++NsX_x(nL8NFc9McbPLs!^pYav_xD>zW*AUE=NiC|twjVl^ZO-h%+*sL z7p@qNY7}bt+R^@*UF3Z_!Z|SH^U;jSg(TAbY*_&&#*}NNj6$1DzG3TChWtr0x+E~F z!Z_p%Sbp_Em%lXtisZRjg334ZW1i%x*rCEgG2`Z z2=O0-DVxsO5JQD?SG@*)2E(7Y{oWq#!5)ni|I^{11@q~qZ&AOS$j^ZHNDBFAIIDfQ zO2e$P{q?*7jPl!?aIh1Nc=`@KB--_-zo+Bxi36P(Nn@E!DKj^SD!_30kGi-|mh@+v zOH3*(o2(8NvpqRl!aCe?!+_qrb>o`-PHq+kM}Pns_ywP!qeuP-z(Yj&HtsxVpxn2! zcw@2il$kNfS>b%FKphga^vOrwdv7mIa`#G4Pag{-L&UFZM7|~cvj>!F>$ZR3)# z10(Ht40yYF?;ZQG)9nG+{eGHV>3<*p=RP$-R8-V(aAy6Ix~X-rH$Wi z)3UYNxfG;7^7`kOp}mcQ41knP?(F8IP`LKtD&}fn@Y`Yg-Z7UtWMx$SCVpwl8+DCy zUVMCC#{Y3ZO*%ew{KX9QpAkHO77AG*^ti}3W6$yRuEdHTibv4~iB)n{`*M*ACnmY~ z?rFILnuKcgx9$f<@$4D1naYOof$wI5kBo9WJtO34v39o6^KS{W$XkpYRg1#y>r-nF z#JHXVPtVL`2s4t}o!y>^G#|uJ_453AY17|bp^Oom4H$+-jfohnc@eMMbIeXBnOfCVNkUBA{baopxRJ3Z7HERgH zKc*+Gd52blal)U<%HSz)r=!z3=#h#m#D0XsTqeoio zwY(!DW5-0-gWOp_^omD9g;pHZXbfp8p!*FLK;M+rpF)zZzJ&YclBl?_@8=!7O5?#MPys z-)2^lSr~A|Z0H>2T|rdxZrH@ESU7n@xHGX>ZuL0E3ba@}c3Wj*GK^z#c4>rGV{Uz+ z`J=1e7lfo_KKb5N5`BpEt03m1(e0j zv--R$_ArkKd7@R>p0lcdMD>#_XTMJVU|GCoWNIF7cBo+;gv7P<1BpXqrYRH*LZl(1 z+Sc0ffx|cZD3Fy776xL&F6whlCd=8brR*A7OewcT6K)!f8lJOjiiM`w=uSWKcl*Je zv}cIAeMCb|opSOmR4{wd*e3Q#WxuJ&V+W>SHTCH6ex$p&eWCceFel&9TicZD#>WSd zNr@gIuT4RbP`<-b%7{59no|eZ`K@^W+3&Kv_wLbfgY5dEQLRT?+@R3uv+W`GbA?^v z3A3z6dk5RUlb5{BNw9pdjoQ&VVKpv%91$UVi=6I1D>^gpS5Bi{~U0wmEK?YI9IXODI{-_RHcZIeto?!kuIi~-m zFf3oIpp)MiQq)i2DojtpO*%$zDJYJ2s_Vg`&wWavi`6%!MVL(?pCr^bAC2{>o&Nd} zNbxo$#lCS~cIUDd-deaK!dEt1hA`(O=<8`+><3(ntVPng_k1w}2Jy#^N!!_n ziAcd@@Gm=>rDG;WK%n3e>C>O)FoBJ|n4rIi@rOeqY-$NRo|EFczkzAWsddry`HRb0 z;up4zn-#;f2B8COMouF^o!MvHpzsE$`Qk0*rS10JvMO56HNMj&Pxu?}T&`3J0av9o zF3+P3XUbFVfwskK9g7S5Eo`SK9&Yq$@h+;(b0?9DJo;Eo7gi3~m!Olfnsh)De|A)G zX=6TU&Atu=F+Xw6>B!9a*ZJnyKk&9W&zcFWSgP;PVGp)lc902PJQj$sw8~%SZn3l~ ze$=eb-=B#Jv9#rRz*S$<+o$HTB#5e}jb^xc+Ai;Z++Z9Jalr}5O|8WBQc=2>e?r2J z)Jni>zCN5k1#?<_`2RA))qAWZ~`M(rC=)429B}X+5fyMF6mx~aonDmb>lYX z8YrKX#jLNgS3HC%u?Q6S(?y^Deo9NM%C2~;{ryUhL02D7HR5%}dHU~;hQzVbo=u&m ztk;{!$$m>m?h4k*>Z?ce2A;12G~$QVV@%8UV4U=GUnYc0tZu!-XF7Cf+-){ypd zrc?2j|9YDqWqd$vY4P2yl2Fi`RR0{Nv$RdILTHY1mhIV9PD%}iRwlHJpG zLtpZFu3WG4$=9iJA^Z_CqC-QxPTM5LAMfwnY0F*u;xjw=M|;U0C$iyHROGC?OT!dra5sS91F-YP>Vq3@bm;!De|Jveb#DIcrCTgjC57d z{SRiX>L2^U#7JqjDLyj6UV)smu0AQ(Iz1pa=?8%FKKfyd>%cMXZv(5S3Xyt$pWJ5iO<|FqACO$hZ|iFb|^U3$8?{1y7E zXZ5u7+U4`N95EX4uU#pa7#UcEv$qoti##%Oig|Vu2Ojcu%iP#6O=5oZGTCTXHdg?0 zGJqO0A5_!dNAxh?l(%4E+xG>jo5dSe$&Wl7=tIj`f4P?#XHc2v&nEG|-)bWaebndc zRvJ7&dZ&~X?0@I7CrAo>OV%a2vK96AlE}r@S6?NAI;;bAE6fz)uyOG|W^b%U!%Bt!*zD+=3^)p8 zS?L$EOYd;b6H?D#HMlZ|Y1a5UCAQ1vW2qx$tBRXdu%v3&)E8qT(@43Rh*;%42uYEGFI|l z9UV93t+4Tym_D3G-!zjKXqIiC~=0>X+8hSd%I$1naxF@i-d1U22mFKRl zY1OI&J1eXoOL5sMEYEU6X?{P>bUOMXAW#q4doG7U;ymXID)O1tDSgGZm+fK%Iz7Uy z&h&Y;vh+&z3h7PeISI?Q^zOtZ$1pmvhlv56AN1=aQ5)ZXa;i(oXpV4!tf)3gF?n?C zd7qz+@saJ+NRmzPNi zQ-O!Kd)%@eh0`Z(27%U6-eRI$C7!aYwTMZZxX*#;f=j zbH}kQ5&j34wbbK}cEZiXYdagMgZUPC_=uZa5(+S34zMZd(8(2{ci{dXO6oD)l`mzsQ(qgf@Yzq7-j{t2F|5xv&> z+w+wB%gc03=^m5{hJku@6ygRB=C=GBgQ%gys=5a8>M-9R*=RkSQDkwJjx^i%OX08f z7wK@QJVAj&D2m{ZOJ8L^8n%Ple)EBC@&9OVi*_tW7vQZ!43e}xCZk?qrwjVbPx)ti z$X}lwHn=`^D^HV3?h-aPk8LXFaX2$B#uhroY}9d6aGk4Z?)Y~qIYkayhL^;4`ay?` zPro+*mf_-ZO#0nY;dYPad{m>=w5Yi!g0)4@5wwr3lozy&D)1E55|u@LN?9Iit!i_O z@!YW3T&o=2Jbk+wmJnll#XGg$X56e0q__UOB6HmIQsYU)(CLFfFNk;}>2sJzr7Wy7 z?>3M6{^UP1OeaodvX2oA!)WdNQzomImkVxLcddw^aWa zC6DOx3Y*C}ToC zNnDViy3dW_l#23CBv0@b3M`hds$?kNVwT_PH-2m>G)M;6s~zJGidu@)5#%MdGWE~G#HB1qZykUQjZWcyp~JjeP5WJ484UUk1| zgg9uwtV&ncj$!+kj8a{)W)d+o!Ef)at>i;w6r~;gopB=@&1Yiv2{rn!aebzwDpOQ| zhxYR=c1aX$vl>^dt`{M{?nrDxvmb?n$J^G zjeYQQ{YH-Ey zhAb3o_4_QnZF)WDXN0P(5=V&DGar;_ZZpyThVrbjbfW2oYK zl;#+KtFxBc^LS*EpVe3{Z~`aJqE?H5oCeLimMQCr@D}-Z^Qx0|k!*h$kBrT%OkAX& zn(syzaz=rWnX4TL2?iBMrt=E7RMn0wUK@j5vQO+dl14qgBilXfn}OXpyj?nYr|+=G zILN|lKzk`8F?kTAej<*sAvlG}36`dX_#)Up33rklCxkmQ$1@@Gxy;kiE@5b!r56FACRH~0DyI#5Yr#+cwODe)NFp!X_1gTUZ>0rr21D5=-=ZL4oksea*|!zU%WaD?7X`WYx}X2o!qSs)xNdeUMzajV{iP z8sY-=)jKVb51fa}d9`_)e&sULIR1-#@t6|6;3G3`cAHm+4gHtQ)V{WE{AzZ5kEGgH zmL7|Ex<)m!Y@YS)%-Nh|8;wkr zmvaS`0x^%k-EcaAufKO?yob#YeVyvacab60*n}dj)bbA>c)3B|-a(d%|3WNJy#;h_ zIybh1qC@Q>tXL1ta^+q)jj;e8w~pL?2S6#>Yf8VbI4$JnN(yaPojJ3-ON_%IWDSF( zH#U>94>z1l6_+>07ALl0#r{2|2?d8@um)IFLAb&0B`_L6C+>PAQs_V(G;->KHX;_t zPFKeqb-f5ZT|+BDcizqE`6TuVkFevjE#*`r;|o7w+SYU?70z$Qm}(qP39a3fM+xfI zEY0vwr6<*UH9Oi1$Z?c75yWc`XT&TzmKKB)urhJ81v4!I3|rsZLhcNO<=fdlOt^{} z9Pu}HE{$=2I1*ljC>RilF+37XpvQ+v_T~!Gy;_)7Fo@Tq7k7B&rmtPVmI1$WuAZ<0 z&+0(Ws_qdQw{ih*n`xGFPt>-&YW(43qX^XfO`&#RTk@<5u`S>CIqyL0c{NtaV}DfH{0tWzo)GYTho?bf#Fp$qx6D$C9(p&V)7or-? zy8p>9ApLyXA$eBZyM$#B@eOa)#r%B6Xj zK)*}sss3egQnqz`BYD8TGaXJ#v&mPYDEAI$mh<-dK-1Q98t{+r3&oj>X_H!u@$o4% zwe7vF_o#yX>n6B@AQ{Dc?o>CA%y(X-$vD)Wm7NR#a1?-a?L{vr{A~d|<}3UoATe-WFS_;7u~8Y<(jY_hND%)zcuW((4ps!d03NldM>ldFq4p`E z`8e<>^ry0&ZzW(HTmT@g*Rjds_#m%lpy4wm)twqm?cs=Nd&Zv?T!n0Al>?KE8}I_^ z5d4l;Of3gK8SH2+oO@Br5rGh&ZChuMS58yG z&9w3a+_ceOGpXKozjQdWjCD#UGm9;c(cCD(z2Rh2U<1h0rZ?nV*3-D5qecn~F0(b; z=SX0)we1LMp4(T29*^vMJ~Zyg&Du~fxIUx2QeN`q|A?w zq`pYgz6T`7)0gO)%j?@)>0g;4Xt1rZjSsKAU+wI3#`Tw;zO;_u5?qP45zxm6s0nwGsQa%o2HU)2LsLPd??AeLgg*&8~ zSE=^7E_dzh8%L=i*$SfLFRQqX_sYjK>?~L`Nh^=jQ8V&Lh^dFy=WP@J%aK7gZzI35BJ}UQQ(Hv+AFm zZT^Y6#fuD7?w=;d0&P%v|KdU~r%pV2#GX{>ZoTmvS z+W*jyfJn5B0+peM&3Tc#>=BUhxt^+(K>fo8o0)?uOYica*xqqsuMP}=8(Q8U z09%<^%=u{yw-^AnUO*5h{3ts=x%^Y*nXvAa+c=F009#M=+E$&WDR;N{>))P!@aW{Z z;+D4W%b4=C)~Di0Ar}fpApfUSp9doY1u$K+7yug>s!G`t|Fx#m>gV$M4}J23M`gx3 z3c$EO3w~<8D`5s+>$`wr@t0QA+n<_2he%@C%o8|dNH5dPn{k&$_@0-k)0zdAND z7Q(*-JYz%yo%ONF0c@BcX=OR&-S3uY(pWScbwO8M{5?3iMu;@M;0HP~y^jAW{@c{f3tr-NMZ3Fn-|0tit>j21~0+2Auj}JU=4AmoWc`IcZ+CXA$ z!HXG*J$sJ}4V|t(PKf=#pln@xo3Po5LjNPz)|!@YZBTJb2Mxwqv~81=t8U|$utmaw zI3(-f+WG58m6DPdj{~E(^L@pz=YO;LOYk3lC1%chx2cEqgmfw>dl2N52Usc^%t$K(qD0W(}oprn5BX(B{FLt4{dQ49~Aj z;NDv|cc0(5ol(QXp&j+_>XTj2NGT}yQ*e^H3~VjrBm2*6fO65wmaghFD&-QcLPteL zY698;3@uIY5U`cWRX62pD~HCX_!1f}G!m$fq%zpH%Bata`*O8rD$@cfI6ljW=k z)TR+*hS%USzVe2tsi~)t5ORQtDZb!RSPZwh^(Us`8?A1LJcWseg~4S8hb_5^odN(x zqYjd;`2Okd6wV{x1OP7pK8bH|8;kbB&WWd1eNKwgT}hu2EPRowx6iNo{SQ-lSEJ@F zQ6kLh@m5zhqd&m;6k4|x4G-HArnLa^7S7_Bx8!jRH0g26O*H3T22a;F{Y2JQ(hn{N z_xR!3Z^oXNg!QraMZkK#kb)~3((E#2R+T-?AT;OpVcNuf0lR2xL-kWt;iSi@LVo#jO$zenI?FB-G38Uox^`m0;RDUr`t|o~t*FZI&Aok}qa%O3@3&eI_nG7OckU zc18T!Tv`5agEMwg$FE9`Nw+ z>@ExA>yrv8YV6~Tg%5pBk~wUvk@SMOG1gN(KK7PDdebPz8Uh&JJ|l(`3)Mk~Nlju-6{6u3TU~e<8D~qi3=1p(1^e=P{7j86k-w zsMR?TN#Za(fan0ZFwUJsoEXryyjT#)&>(vXq9d^Ja@J4Z@$d0oF^&6+v{5=IC;sd! z8-+{n+AV(T;=D zKt0se?c7ZkJ_~c?cKck$9*fsYTuu8cBK72l?a}V|^JUMxIPn-p_&&=a`q&IyhgP>~ zDI2%Y0iBzbD>ZWH8E+oQjSf+Fh1eG7@f;ck7KqI3>DS?oxIu_a^9`F~hu;q+9nUw; zxAnMLPxKPH+oK|>P^BZxOOnszlIP7B@oboIFV?Td$05^F4|OI&m3JX>GNbfOs-SrK zCi9xgm^PtaJ{c`NXHoIWyQR-Q^MnOGr_^X0TAD%8^fbCNB&6<+q5vr}rAJy!#9L9p zTwmuQ5?tRqU^!);m?u;_R6#MWwTQW^Ku-*(q~h? zF6}oFtZ+w$sG$hG2#MAwqem7okU8`Yi3%`F(#B&yyL^gq72-gVz{Rcw^1kT;?+;mS zs8*dZAy&gSFWb#we++j?qjpD&tc83Rlo9Dhn7N2L>*Ve;{R6O7|zw4gK=r5L{mTc?7rkE zVB@f|Q^I&L)bZ9`!cPESIFyVliB8vhcrV0+1~kzt95CpAxP}mIlb?#3CM0FJTHGgp z(rIvkp*h-qZjYvp8$rxmG3y-Iw{!|-tqa8gHm_E22wNkJ`^WnT^^<2QENiA>nxOTd zLT%TNFNk&Pq^%5V{rQZ;ohJ;`X7?*9k}H*grOtYPFF7S(6KrhxD*)V7@K3eQ33JNA zFE>sBO{cLoBAfn$P|H$OF-Nj7{A0vN)8djlri2fv)F?ilGRP~TZ;4!z%ie<{F=NAW zC(;~!l(5Wh@5#fSWwpnAV)+jn>ZwEF0j_ ziVu>u;{PCl4N!1TWrvxl?3S#<{&r!+tgO*U)R?z1uvC&u80sHuM)$izmtVbepGcXf zH~isg2CR|fXL>Q)%sk%4LUYcTp|2V)Td+TwyByYszTzvet8dV*r0VP}01}ao z;`(d+GgQ>#hF3kYz3$g8B~}7-=hYr}#kfHq27ZN!*Xnjk@D*1n&1( z3D>@G>|a9?u7eAz;|tslUrD!4ZqBH)opHg~68s@?n$QdcNqwJ+X1Y5*56>on)9K3X zjz6PkA0&&q$@%jWEr@D&-W1^wO?_$p8eoS9ec9_@XT&bA*$Xf@)dK;}1v-bAXhPLtKk{@qzP;lFiFr%50zpx*It6%*M6IRj4z0OV=-m>LN0eY zA=qJ>%;WoWw$n<3*WFbQTv&NaMn?dT3SQgBAI!&I6asO$gIN|}a<-E0@uu;{eK@Mn z>ZI0F(1aEYAsr4&;UZ?0OwZyVu!bih1Wd^{Q>rH9biF3ju?oLa7EtGJK3I0(W{SVg zh;E#OUI;Lwfo87J+sTpJGaXKnb0g?>OPD+ZUQ_~bm0EOt)VaM5L2?mBIAZZ~0mMc1 zHvD|~=pjL}udOILJGg^~YD>fr9?PPjgeHyma6vapW$JyRT4x%EpqljZe%>*@*9zDy zO5||d@>wEO^ee@Mv@~@1Ezy<|3)ecjPXN+$YGXGRzqS$HR9aeFeC-39_@bL_?T=LS&~ajNN$9Q%kmh4Dskkr7jc#vx+X8OlW%AbbJsobz`Js}(SAkWk@9D4HM5zcjxO)SOu}QQUsV zd>qD@Ps79aV`G$RaLl>D8se(9)yQ1C9h^kXQl9GBnV-rz$9LDiSbm+*-1_h_y|9)- zZb^UgrU5Ol&_5^WmQ4}A!ua9%$E;ex+7FFlX}cMcER^N?5c$%RDkWen zeMM+P1(c~#QX{kbry220Y*)DEWJXgTe{HXJ+TOed6yL0mdJO`~jX-^HvVUAC?DSYo&z&(?IJR3q9Lj2a|d&T~)10X}}k zEDv)7%;r8RJyd`qPexder%!SPZI$wFYET($1tjAY0*JIIidf#;@V@0S=d*aC`su>M zB*6cqn7Z`gw-h?n_?NjA6gtaWhaK8iw=lfc3JQjNP9`aebCr}-V5CNZBx^FCVSH>8 zP@s@+0eI{08#eHK7H7ePwVnL@$hI;n^BBU|LHg00Z(Thamuhc9vLks^wu)^P z4xly5?uY<$4^>?zyxSC30P=tj*P`cFH?I%$>%Fe(n_?O`m3xA)E@`&~3Y>~X=CJh< z20dEQI?h$4bH~B|IB=Ze#G)fggfpc%`P5)QKfb3Xm}F1z&} zgv7jcDNMrL+Xa!w@IrR#3eT3ipPE%`Vr04XGXi+kp$}htr5*8*t}*GzHqUt*fj#_L zTjM(H{I%=WoE2M0!NM)8iS0KYXV|snKowpj|Abe&oKuLWoDsL7Qzc$2j}@n_@ieFh643Hn!3zG)4G%Gb{p^_Bc z#|Vd!Ke``)<| zM^M)@h=)8Xp)RD8qGe!J6uwm320c{+r3W-OOF2*AG{XxC&=RK-?^KM}6I3J3%|}_n zjJ+p;iW##aDw)MRgXbF`(?s3h%FIKQDFwpe3)jQjnkz8`+&5c)7o>(LLfudYb0h5p zkT6w}5naUhes`f*9>Ex4qg}?^52R;)OHNB}-S^4FTxfN$IU@LM&gBf9jNLq1OYYoV z;U0TXzI&NiY%4Id)PEf6x{^>r?6b7$dMJ`+wuRN0KoFBZ2CVAb)0U zq6k2ixFDZ6kKAqWOQKlyXQ%m*Y;4;_lB?N!7x2>N`Wf4h<4QQ+UiFK8qx>Id^Ryll znUy(?1G&;~Dzo=ZHUeF(li%885ZJev#@e9eI~OcqgH&jk zYg8=YK(^gN4jR;C%Fj1wi4yAd1JieyWr8z*txf6Fb_bX~;;CSlQDcEofR`)BGLW6# zCOH!lQR8hCf^xTzX(hF!sksIA#7Z?_cGVk*W84T~#a6{u!ujdi2KzggIVZ0W&H__ztb81{- z*P?W_G(KbwZg)k)TnCOz)|00|IluA#HrWG|$Yc~MIf4w)F8l8Txmjo7N))jVJX{py zEVSaSA+Tmxq|qTw{gYxNg^C%3vIx4#c`Eg}eD6aREd~AU+$s~7V>V=-(i;V7? zDE}#h|1ZlS@=M*%5#cxiBfYxn5FYPR5#~G68k7v(V$!Z@X+bZ)ThB7jS>nm9!~JKF zK@0qEH=^kXe9dlo^6S$EHgR?Iu&$m^^Aou&(A2i#EqbujBJHlci6|o?KMQ{cnW-&= z*H&p^FFr2wC!Ff_I=Vm7^2uh;A3IOtY1qo64PrA!ZWJ@LbxuWmY&`hrVsHwAZ1z**x4RyjiKMyCqhaRM1RrwiXx#@v5{kcdy;XBQ^EyRfmG{KU*_Te}^VG z+;@Y}BcVPCWB9wqEigw17QXh(ro?8@c<*wietP{`jsuyA?h>7`LDW4G0EpGnd=kaA zWF73CfefZ>T?S>gq!j_pZ-JIxo#!pAIQvG*wEn$oo?xV%RrnXV>y!+-(H^$bx~TVh zt4-RTkZwjSG>Vcq(}XqYWt;ClJ%CjgcA?*z#fW#jnJSNVXmhpb*3iq7KNr(26F13z zuIYEoGMmp}3FHNykIBw;G263f|zGBf8-Nx%W z+n21TC>ni9f0j9db=-2)n$yw!%&&0bGQq`}rTb2)wuT&f+<Zb>7UR{5C{gQUH6b z6&)7PEKzh?2JRe{4D9N>rA|vKUh}KGCmb%TIV`I%?xUacp4NlUvshLqgnqH3qrKjm zP|*`B2rK+ubE}S=d2z&g{3)2-{3R0G*)2e%ef_`I8u5IZjaI%qX*%>3;sM)tG&*d|jIVebTQO@j$g4Zl>4jjn zpKJeivpvzJU_hX#6yB{^1$pyzGu8ZacKFJ4wlm~CS9Sn&3%f&AOMc%0M*n0R7VUW# z{ErZtP)nJsf0P*=Qk~qd)s}Z zB^(3cPAQLy1B}z;6imKCq?>{i=*!7KPI`5_6fgqQm;$hrt%U{j+~{z)`55+G!*H>S3tiVwI+b<(N!gs07X~K+$sEDs?1OPifiW6oKfAj*uD*^UdS*D8d(jApr z!W6z6>wx*N2YvsNA@O}nA@-`*0l$b%=d!zPFPidTDDY{*B-iJimixZ)uYD&W;YklY z#e>Ddr^Koe%qej%!f!n^cGjen@dMI+YG2sXkl5^de(Fz-=-#-UX&N`ZJob>Q z*}d)*y*PH79CX{LcuEH~o9*H=6MepUoepg8rq?Cu9e-0i-yMg&SAtSc<>ofIqNTB< z;);V9pWjv>pL*Q58tXuSl)u{i9q9JjmYbW~)Jo%f!UBTR^pmwxD{Sm_srL}Gi8x#666f(0`*}sJ}Hl|qc5Oqgl&?`DXT{k>Yd%uWH zEB_FoP`$LTASeU3GYltxclX{n)aKqpi;>#skVC_|+enyO7o~&jizz zhI-?C0G6c)homM0YDh|}5q0&aZ5b+8zsjAU!>-m}8w$8|7Y|EZIeJ z+%TzxSvgzSbzo;5M;X`4*=;M{SQ>xOMJh>dct#5HA-##EM zMEGX}q5>4Z$j5o+Ar_N($R!NzmQ|7xz?2bCiD#lWFN^<}jIE`3%KlBlGt$n5+*qc; zGZTaV5bd7%uDAGoYm9aATcBdh#Jw!KUGb?;1o^@~04w0sC zi?d_gB##z-p7gR_-`EU5!wIer`e%%uo&?cVYP=NiZyqxN><)`$p_;qZcl~!E<@&7q zt-*^TzsE|o$Kko*Z)(GKg9(8eGPzt^nYYP_2ytF+K2yEr)7f)*u2L0u6gHloq=xea zXe`EBQjyQC6553;g^4|zbZjhf`FlC@2 z*AQ7M!#QxC#hU%{Q`wXOhz4p79%zA@Y+cJIJDX|-JNaYhOf9oHa#J}%iav)`O|BSm z|D>TYU}Lm-?&_LWa2he($Yw9+CQdF06WH3he~OuDJg2p*>%2->mfkA0j$SmY*<^CrdDhI)(9el@VK?Ta---tkCA(6kr?gH zwFY=|pG>uBiH+SW$SYf~A7M@MO+b2S$#@_6yF0btp^u=h?~=`j9)bAOYe)9H+93C0 z?}Kz}1*`ZoRc+1_SK7DgTUX$fbt$d}zSbbeRGc94*dtb;8S5n|{8QXOqw)-^@W$1i z<6bI8ez5BOWv*0x-&tLgPUAY)%2ucehV&>?H=^L5&X$>$)*&T8!&5z-^~oP-q9Nu& zo7=IoE}sKY#?jrE>v;C%8m!0p;yq0`C6&}c<`~yrNW9sRaW=FUt@b1qD{E^lv?RDC zxf<%`PVEoSaqWo6zLpj^0;*+R+{{3vFL*u@>QdIR0}YLF8a<1@U;6%X?XC*dJ2+9F z6jZ8&-`O9WDW8_DSQ21_xOPhnbi&|nKQ$#bcqUf7FidB zFw{3ZEbHsDGz^YLg5*5-%8yp^?(Tl|r<|(m*wXkYaMXfL+lR>3pC-~T7P;Kx*rJd9 zVkVC5OOVb4Ua({q*U`#XYuv<2ps(=Jf(T+t{#j~r3e}9GFJTT774m)~TO~ku36{)% z3V7R7|2oI(A9TE&->OtT*@iBb-uxz2Q;7|}S8eo9M|-ThN6onBi}7IyMgw`h7l~@b z&YrH}*bMGkg;H^J=!lF@((iyLdX24Xwd*sg4kq$`jpFn_*^O_>0TzAoqWZB?^tbRZ zP;hbhl2bgnKA50|?~EE6ylHTU8a|u)Fn@;#mzvfma86^Fa`qj#ENhU-z9-dFDN2e{ z#w*`|dQ7i+OK5vR(EMq6<84gVh49i$NwD z%n;tmhIeN>QC-7h1)Y_J&fT4?JWq#o)8v=z*+ztggV6gmVBBk|ci)T+-9B1cZB-g7 zk;mAFYzp`+rpO#NI1u)Z;{9BUc@)HX#?pR!75Rdf!bA3F(HGt2u;Ezv^ z8w5RG*hzt%+l85|k*be0N!-QO>pXPxz@c5dxL$L%eZ*|l${~~cOa|+7~1@h$cT%;!Q?``__l={05tyMfAKkDjsZ zXpHv`bWHh_$@VQuYI)q+nj7pIkm*_iSPH|d%b$0*(YvPvOsk=LvGndyvgdoHJCz|> zDT~f018)qNFymw%uE6n2<4af0pV0wF!kRMg%R)6|7bglVci7mD6__3h7rNjPtm@af zdYvI@rtnBdzI4BH9m zy+{B!uX6FZZVXy@8Vjqh!btb|ba_c&i~E^U$=y!Y&o`e;sp;j}(yhYE4D+>e3Z#gA zGP#Kfhuskkv2%@kaj~%l*;-Qbqi+72Z*N}LOvYNz0V}lvvugCFM04*MG?&q70#Xm?d*+cGl2NPFg1rf*{yJ+n3kTs#gdIpo(<8k zfUkZ8G$Bh@HPK6qV5e!VQQ$#BnSrG*TTfSbM$g*iF<=*k^adZb-JlBOD=|X0y64N+ zeXb`6Y)RbyOhh8j_V*jy6hv55OuD{BWuD5w>7^p#9Ksr{+d92Fl0J9NR+xb3C>A^| z5_^PA=m=`3_@8cs61Q^Lh=@p#HkWB{bWYzJoHDn04m)^9kb6gWyOBxRsrhpt{_CR# zT%4_)Ej?SEKL4$vzD;S!fTc9~;fWeYz@g!OEn>5yEl8|mQGPrwJ#1ynL~Bha=XDTgGF!J2Py3<97uCfR+|XRwK2pF%ETGBD5GU9l)&8`n;`xL;IIj zW$Ap9w}Qm}F*o{noscy4Wohqr-81S_ZjhC$L_nI%aaz5%+S~W#n%;Nx3W4J2y`gdn zCK@Q%IVZ9G2aWQbF_uY9GkNf<_#rX9Fv5qdM-5?f<}%GsC!-nZ_3Xr8h`or;hUAI> z*NKA9Zk*%8eT?7}c_ll_1fYOLm-gs6KY)ln5A74eLR29&$T!+9i zOmgn9u(CvCd78+I3vptzL=@YiU%^k_<^i?Wwi+b&)(0joz{_jmuk$*BG>RVZqrH7{ z*lCjv7kJ$L=Cbq|`M9Va>l1S{=Z7K^}D;`FF2jQU2e-0CdE{s|zx`|? zMl*S=@ZxOYOAFTej6QG+z&T+?e4eR zcd$5UbX#aIFdjzs-VVFd^{L&h%<)^ZRHzmp@HHmT(NT3n#4{k+2toTB2i_S%+@E_i zUX}k#%4%pss)r}XF!;o2dkQz5UeBjR<%xRCvHJ4=VedVon%bgvVLXZ+LBN6{AYcJ$ z0wPViihu#>gh&_Zp-JzFihv?Ty7Vp(O6VP;B3%dqN$5p7p+kTKlHAQXdhdIG+&kVo z#`}HW7Vx`K-C-e5P*P>irkeKiF?STXDJ57Pn}9r3!+O=s%iHfD4#gSs-+AofJZfyF}D3hD8r_lwM>%Lj*h(OxUd zw>Xli1~q}|qouXG&NW{(X)S~>DG4_B6}7<0u3TWO7KIYCzNrgR826AfFOPqnLR=3J zGHU3CX|4k*E7?euGS;UA0Ozr&OIL(U^8iDv=As~u$EGx-_^J3)uR9arK}P^M z&lQ|yQ?z)~u64CkSmP1%D6p>9&Rm6srAj~gYJExKR`&abaKqw=F)!$B_Svx2VT0Ix zBBC|baAoCgcK((&o;LWQ5XNH3L};o;uV;}F61os%1s#+hD*#WugWKt!6v=bCn%n3142^W9{*~CjbJVnLXg@q{|5$ zdJF}nVHO{DHQCpVD)&_c*bD+*|9D2)YP13=>j`+R7-wE2k|bFK-}#%6(Wv`#42Xq( zWF9PkF^hFd#_>G35#M{^^?-NfP?o28Z<&*9bW~C6ujd5Ejk*_xnm!F)3AGm`8XexM z2#*#oF?^7?mz~!h&!{J6xnDt$aC~7)6wnd7$q9)%o3I8aj?b)I#Of zbPO`f;&g1pF;ejUD05_)zx!N~;BhUDmAUvisL{3wF~aTzCBCH{6II&E#ZLk{9?)%m}BqdFuvS zy`Y1yBqLt)LlQ#x27!6^$t7Bh3xbpW5|1yx&#oLpHEy#nKin#i0yURI$g## zyniFpSAB|sX;06Jkwsqn`?1Ls?v=1X>|L2^0?z1-DJ_X;j#6PK64X~MQ$;xf{8DqQ z5WG44e#Ho^_UUp~StmdhP^R}&a1jBoy-ml_0J6PTK{|czQ@##EQ{1NWTQ<*1SibXE zalvvc#v1z6pac3EI(IASO2p5Dc-d;#^*bdB^Yw=}$3VWnwsNm=>0o0$QvhtO6GzZg zvz&Sy`kqMVH}exTxVNIMqIMuG+VS3-J-9kf_fmY^O$kQ&Ue#ACnT`y~!X}6lOv#>h zBy~1>xu1L2+h=VcuTeU`wzv;%uK|9TYmMFGHVU}~C!8)HbuGR8^1Y4<nqO# z9xTw-vSuyhK`ZA~8Heryp~(s6Ul z0J`_enXO)lZe?tuP|g%I>(lZ=@MI#O4E-%90nI9T)-W~RAHjNkVaxLcR_I3DPkq&GLZsljH zSWr!nTLLGITBC!;6#&uGBkn8#Uk1gsgbr=Ft0mh|1OzD!{&aYhE|P1)^lzlAafhWW;rPd-IK;8W$W# zvXgolaGOrC4At9u+YowjB4#GJeC{#3>oTWD` z7ocOTaOIX}Wfw^)g{(OMu>71ad94zelMyHgiE+`<cszAfqfss$cczM&BzW;f~GQ`1c{4((g;^L?h2O^~k{#BpB*RxJVI6RsdU2aqkO9qYyEO_1l z{=NS=&`#8-qC|PjZyjl1V+?BOpWg~)xN|V2G=4kKxwqz<@zrjt`)7f}a4h*}P5kI{ zj?%@6faDi7O*x&a4xMA_G13|fvH_QeT;Ha$8sLEK3*+6tIFjJ!rXjW0AH%;V#4>#2o3<+tBP7@2dli-5-~ir1Li&^1i& zj~WvrODm27wal1pM?zOAPoviZRsn_8Wc^{m11WOs1S#4oVYNaRXfE?~HW8NFd3cR9 z+M?G{s~2H~_g*OiJYQ2lCkPxc!x0s>y_vs*5A*B@z<|`>F`O6lS#RM3&ei>UO(B3O z;Dq!#Bw3uX3p=$HJtmqm)*Z4^ekFn0YyZm>snR?23!C@KtjUjhQjG4o|P_{j(t`{E&#WVq<@uUDe?i zY>qv7!niYOERFTHLsvTBeX5C$&IP=eO{uR>a)TN>j>EzL|AL?PBPx)r&5|iAR-Rk< zsc$(E67>VowLOC@axho-bE@ z_p`GhsH%Kcj_0X6$5EnHd29;bws}@E>tUqK{ZlZWw6$kneNwfra@vn?ewJI16R&>n zcc&<)%UnbsQo35#Cb`tPb=d0F^u=54hU|Ut*Jgv2nfK-bVGPW#QjWda0o3P!Y>kIY zhhOWAD4Bb2*{{`aSO)}0Wmpai0IfV(4MljBu0>Nb=hOSlMd*OiEQFbA2E5c zoDyiWJD9u{H1DG);ASHWFAt3B%xdCWTnrYpcQ*F?B*O5lI&XSj{lvK2--oWPpZd}v zzqYu5IEt7t-sGCaRC#|&!)@+h2Y?VOq=^1`y>EpnUT%ZtOK(THhn_{xS|8$~P$24d zC;_vbYVUViY&7CdU zm8~HYo}mVe@RgHwW&n-g>feVhcgEU^0pI_R%j42Xed)F4{XmQbsQSZ;?Z-anAX%ms zn{{I)S|vlB`@Md}?{^6u?$uj$wSK~6-Pt64*3RhJ=Vx0~!<51mK7G7NMR5$QdP@mP z+r7<(Oh6w-ga(uIvCwuFvu&z-@T95RvlSUF(Mzp#l3P-0pO}@E_XbX9+?6Pudct(* z+m-6}guUfi;Y3HTZqS9%tI8!iM{08ExeO^4D|_y>&%W}AEEjPauj}tjKbN4}OT@)n zk!?GSl-KUx@WtQ?FzOR2m2@=4K%~wvK%B_8^)y8yclN4szM7eY5p*f;eOR%#U_=6~ z_I8_HK=VT*As1q;k22SfrP5c%!V-IBWs2724OPIIvWN?K+bEbmNO#P$!zeK(cz}98`m@2`fRI)hWym_tEswMv+99S*UA@4)AUhnC4n|}(udZ8mACKmf2crM#dHUD!5`1&v7#r(f=kp8PkL;n+z2m+%4=o6`Y8vt#u*4e zLb+Xpjo?6}iv$+#G?PyeR+A_tqo~p(W1H%#=ZY)M4(G!B*kL& zcN`^6UHpWH1xj=Y9ylk6*m5%=2mO1oojirx*>xxhrc>VGvL$5%w?=OhX3 zKoo>a3IDiFY0mOne96H;EkHfGHY&ntmJM&(kLVkE*MDefyd)fI-L?oRVV4DGkQ2y+ zKXJriQyO9wsAoZx@C`!Ok2M*?mdFq-j&+rOb02{rxKY|kp0xXFP62!&V1|8d*egp8Gwe4%%r%oBT`dGIJgU~Z=ufA4U*ivL7|Kp zacVf74|lzTDBlQ&M14@a2Sj=HB1&pZt{Ss`i>5QeG(jWb4>6TWz554C)96^?BXFWb@8Z$s-$rMsW?jZ7|7%-xvVQ{ z%F9&Tuc$zrthc<-@<##G8BQ=;z$;ai(o_~8TP3+NOhX>{pT(eC7}p(PnhzNs+q|HC zj6n&zX!p^h;u@|dfeGWW=JzjAWHo<0BUaUA5AwLD9Xe22q@n>+BL9{5;S9uK?W}P} zU`iS1CA+3wy^Eq(q}-Xes1d85sO6^R6Ay>lL;wY6nje zck>Mg%mc!_-NwU<8hq{Jt| zbs}h&k}5TX1X){lr22wia$+)q6h+Kp=5ju2%8T>e3sv>;oE;oD=!+04DKP&-@jPBU z{_eTF`p+{IFj#O}ayhDXG$q3~kp8=Q$(dap)QP|$k&0$Oz?3wOgVrZp6~HKvZc;@| zu3KJ@ni{wsC20_QTUzd~9oOhA8nthK#*aqJV=$QPcHsbiwfe{Ke8W&+cJNUgLgRxJ zKTm62)mv#|Y>({uQkcJf2M;Z-PzZ#$IE|!>iM-vgVk-APy+$vDeD5^Hmfqb8#f{oy z!VZ|jXVzupu&cpg3J>)zzYl#HMS4REycUa4jC^w`J3p>xJX)%GsM zUL{2BTdE>ICqL8{fi@N|>wXt_t#~TpcZ*-PkRZy zGs?2|kMT5q?jONEVFuG|{-6T#`J;lS?bWPpY;4%rUBwPmcFc^jn+X}XZ3xBLX;KKhhKwhWvf0XIy{I6jO|4%6W|5GCJcz_oChq&aVV<~qAmRN1RgeITi z2C)=Vg%%+iF&?TpAp(o$8s2XuhteY0WaL@?j8Dw^XU0Q#;Ks=`>JhyuNZQFHF2@aq z(cdcM1ry>=v@8EENE7!&%6b@XK|R3}1-oT_1EnL4f+A$BUI}>l4%GeW(pMMfKhyv7 zI{cBYVrBd;vtJ zIkw^fZ@Pci@VRlTnCddij|g0qg4vkU>hF@7ZyWf(Q8H9fIsjpAZ!r1HF5W*F!ufYP zuY^~~s1y_AN#hM8w;zrs=YBsR72Xj_X4&KFCrX$DA)Mcl?h1SjALv+Ot6WALmAx1s zPfmvZ#7G3~J{Wvi?PrlYX>_G1qwAAP_=lft7+E#d*jUenXH}C+^2TQ(0;j+2ldSr+ z3D?SvcsY#F#VG)`V!+7ybFfXkBqUz#y?Rgo7VZf8hfrmFKu%$mTJlMCj5i9_I_wen zqia+qD+qzZXQp3L=!b;Hc;3eJ&nH@u>uhrtG~W#w6VIvYJo|Ca_CBQ(%u;)_9UGa% zGqH$VVeI9l9v0;y5FFF}pHjm0IZSsVLt4s>LWS8_eq+MTr84SKvIw1LZXhr|?VlY> zb5n(zWY5Az3Qh>MN<24=aqZIRI#PerVkBuCZQ44-BQR1|XI0eyaQ3sfUi`h7roV>v z$yw0nt3j(VF`l}*1k}VvzmIN*CTM#bLh!$qY}$Yjb1jmv{_dkO5}=DR7Zd(XK5<=( z=@6b4yI(+I%YfzjbubmKd<5o?CNzK){g=0s!89Z#;zNb&;{F0ZznZC0SV#ZON4IiXNtf^|3oFX187P(EOqmBi;R^nw87Q4 z3sN~28b-bGkT=SCsIFb1z3t`9oK{ziv)`io5T%}E3oa3k>Yod35$PI z1^M%l86Y%3}*-5Je4^_36189wss7ghS61rOHZujwsnu=E~fG+AgF8Q*S!4ic`|- zw;H?d>o&aM%%5h?0VP3Jx2c$f zk6=7Na$@hedrA?Qnk8RQsQ{6GzzPT)$Ws)K2G+{b;!l^lbEM-XOI{owA1TN>9?f!T zm*sN5TjILvj2fJR1kqfzSVaaZ7$yiy@B`NE~Yy#d6k=s6d zdBDD=Z1}M#AI6+TzPzg?p-LZUxGglXo98or|hDnjX~anQh1a ztQbJkH}W|)tg(1&4@HS#zNHo;7tsB2){R0L7OXB4hfg38DUxbh!}#eG!cM{n8#%r8 z5F+|4EhGXv=lpfMtETtz+|<(a7>}R*o|HiUQN0-)SLcf^DlMPrl1knmxVRQShjT8r z@p9#3_|4@q{!7lwikjh^@UtEunpsq&-W>az3aqxv_m@z@jf!YG5|6}Hxw2OPFO3bk zt}OJMS@~%I!G|i9Tu&m*R#52d$CYz(UQ_~{&N3OrId~hs3Tr`v$vpJi^H}UYJ@zC( zt)r%2r37Reu*tj4H9%S>U&aRHwzwVaUydUVyD3Y$K&wA;J--~PT#Am9mtIPJ*hQy0@)mLyx zfKOuLUdw=79x^yyv&>vi-Se>aR~DYGo+K>8IZ2Zo6ox`B?KOB zb&jLj?Bk}rtlpNZ1GDv->|v}Ohc7C~5yzm5)4;w-MY_~^yj-DA-gW{6XH>*M^1&%` z8L!b+WAkRAF{X#|7@Yf%Py3sX@$JKaP`kEFdzc_Bw;a(fN_ zxu%BRhg!+ypwbiDZUQGPu_Riq;hq{F<)=SaBSU2Ax=Bm#aie?sozRR`I27m1!=(y$AE~Nx!0za?zz0CF zxrgfz&(MWfMIQBSor#8_vETTCE_N}59MZ2K(%$96p?Ywv`C3lGJ3KExGlEjo`{&x> zugvgE=l>eZ-M}X9fnGFYO8muem&PV{$~dbbT_Eh&4F+px6NN5;>kpXN#^|Pt))+nU zx6;A%iLoQ3l?{fo$J?l_C9#c%YT}O-ga;|IOZ>784X4y(Px_g>j!$xig`R`mh zm@;@JOJ4!f#G+}_o@3*0GXdgXBStrdL*-?@J!tr?aroXrc2WbRqBkq#XMpj2VYXB2v(dwa`dYOxHXuW6E>+rJHyugrP_$fi~@? z8{y!Dlj6%~jgCp6l0fZqmWsuGy2}5k|FRHDAi#M%AWojQ*&(t~%1qSFii|ehzH8W+ABh zC}(7^V>6Vy5Ro1zR^&unx~pC=l^LZsHIJ;l{wEVuX>3Ob`Le8{y`x(fxZfpKZ+b)X zBV5&PGSH;HcE*yidTp@Es;m8*(0nW}+|$o8Qo%=Lqa(MY(ro!FXbofSSJn5dr`Lbt zQt_3EbluvovxKky?o|OhPZ#gq3(izi?P=Hv2zUP67@_6W(Kd85H51GCDL~vN0?5;r z?^rN2O9FP(TG7)KK?&z=wA zRo{P$e_!LP$jML^$>^O7;A}L!!CZ0GFsp#y1xhMQPiUbCyq#`p3ZTRg23f&fd&wpW z$*1c~D;7i)CJhx=kBkoKD#LX-p`#*-mPe=yXWgxNR-0D<|8SWeo{blf0KmWged;ogLV}SB41a%l8#$y zfs|)Z4d)YV0z+sq!&kt+CE~?V`t*S)N1}c+06%P8sv`G9){vuZ2C`@WU7&TIJ|4rs z%xINU-8To7hp&2v$_8#Y4sFV`!n*L~I>{U}`2H6IEoV7)AM`xYFuYR4g}xt`SpNwj zW*bxGVj8D{I$!$JTt=?fi4x}1m!~aGC0Sai(h{m?wM}K;cNP9^A^$D^eeuX4 z2gW2)l#6_x@J9P+&!rL5rvq45t~$l#m(b$R9*kf@@bauUO+Cf=B^Of_~)V-SBRtMN=9Rgd-~8XjpOsp zaCM;-Fp4kcd@zO{`~-J{O@7@of>TOYek^$TwV%a`bYLyaJ@sX6U#sD~ZCqyUXfT4@ zgLK%f!%6H0zm)Ia_H=6I<%_x~PC*b~wMJ3N57v}gnFr)dZu9~>9~5@aKYf6^LtJ6m zoxzT^_)PMi_T2rkjn&MLr@zwqI)}87c#4Yrk1+caItYix%yfdh?wL0^SauFuQ0S?di^ZFCwa23c`M2NEKM5Ad#6^T z&mo&6P}qPtb6=d7oI4wHgqYg6JNgG$T5K(qnPa2(z@f}4G#RxBrPFi1ysyWOH8Z~~ z^NyJo=7(yx@g%42qTUD%!L;d75WCD#MYwpHG;;~KNCAfcvsZ6?0xg^ave>LL$Ppz5vUQvfTz?smk7sw`vwZnY@MB3sEf`{-{UHJ!#ihry~7&@n||C#|G#$aYIVX!iJy(` zEAX-~g!Jl6h2B9{cF(#%y^yI&PWkWsc)-ge;HU&oyWbt~DnQ`(p84^yKt383*~OYw?5{K^UHvh?zKx2}ha(gvVViQT~rkRipjOiwV#f1A3k8N|agHawE zyP$UE2VYIcOZF42G$s!pZ{+K@75*`V&rNCQwRdzHU>5;1pa)>IoBeey9-xg5(~>tl zMIgHNi1FHY^@uD*AT<&)sFDv-Y8b$#D}>*V*J(;Q4R0)|ZQGMsZO@XCpHs2%bAt^r zZlek$R4QCz;%7mYfEP@6{s=IO(0u7iMB-md?e*lZTIW&F-0mUO%}+nJJDKIQoCx`Y z476!#9}hE)-!+faC&1X##<~v>V@Ddvl)5N)+25VR+^+$yhk;CiSWNgiSH6EtuwMxOWFKw&^^2#HVoNdw>}!bKL|M;{H8TOox+IXT^Itm- zQRO&KVAwbpkY#g-`gFUoF-CwquQ~hTpVja(tzhK%_E4L;O&Tc!ged~w_?P52^WAwM zqv@-gu}MjV)FfEq)I|JTV8>c}+dt1`e*E`tG;mi@*rW>gn;BR+^w`IPIcbQV<+p(0 zJALeNlGzWOk*ok2LPhTh}r*1s+0bgajj2l?&+=_CtH>c_%+f4}{>*I(T{e*2Ff zPvh?i|8top_@7Lv%1C-JN zU__j=ps~Tcv!J>V@n#(G;@w>jo+A$<0+ibOo7|kaBISh@+|MtB@}x1dN>QXcU_PwW zv{41%QSQ7gCZ>lgHH{^9U(O@@>cDeNwSj`=?Elo_Rmavr8MQmUNUeF3*MfoO`qXi@ zRlgZ6(|R||?=y=pIRMl3#5h4O#RnnviS_i&&5@sg0D;Xl2Fl`5 ztSqwiZW0s2r)a)-&H#MA#~&ZW#Y=lk#>A8>s}v>sL?r*(wuI0yS+(>v731+2E6szM zU;nWr@}0VvWW8f$mVqKoX4%%nzczn4@cXlegTm(j+`94c1P!xfi}Anh&j-i=fN}iy z!*>;M2KxO0^4y}n*1Mw|)OUs3+PTF4yGu#tV}W?XM|8{(A7WiOD8^%pY}9@mG%&IQ zznW4ywsnbD!j^LL5FIZtk=M?^Uf|^8o)4pWl>(U$gNsUL(EzI>9>`|Yz=7g zKmGLTQF|w>Na$zd>O***nm3SPs?lS8d}FkUtnT!F(t7nbPdd$m_pUvmmf@p5(-GX0#gCqI%H# zNd%WYcf5dgz@MXH8cpXy;J9d`FvjySs$2op=;(Rm*lF-_4KG$J79+1&9v&*>+;O%{i)DPH}zmL4+bE0_n7YnTUN$?=Ynbb zr0n_Sg2dWZNAPZjzz?;fnKS-}bNtkyTN=ssn}V$#D~ndmq88akRp%hFWea}f2r9r7 zy?87LkS!#m3IDwTpk$$EiWkY}CvQW*NU9S#O5FbQr)K|Z_r=7OaRRISKyFfc_)>P7 zEK1+T=5t@VY9|_ecC4k* zIqgeB=q}Ab4s*Efz*z=1xyKr<$qw@fw8va$E%awab#jOVWH&NR6CIno#36h9&h%xh zl5O9o@DIP+KK=R8u#4x>cTjH0-4uAY{28Jr2A<1_wVhl=2iDq!iH%~u{379ri4G5d`t8$49TkzOj+fmwhep4f$0=w|o&vw0|o@~-?;gU|1+4row`DRBY0)cH0*>W6D znp&ogWWbL)xCrn|Q~CiWsq1w)Z`KR_qDoEb5%T`~_DlT`f_sJgvJ55G=2u8Fs499sTxXq{KmGnwjS5?Wd~fT{l;Wqcb%6;1e;V0(#1Oe&qDdq8&Wm} zrM^~@f&I$uQ5}D+)V>~^?O*Fm$KX^D?tt4RCReYF&)YXEQd=J}k>M0+!>>$=#X>2P z0)B^A2>8Qn?&XxAGu6*$9z}47sr?+QvBNKjFkc+dj;V6+4yPQDnOc)`xuSTNgZ3Ap zhc&%M?-Fp0X|Rl9?<@KRFB`E(4)K&`@7i?#n*8;q z9meXjOo`ka3IWe<4;uPYD*;dH!wnQMPzU^dS92gZ6=`i zIov2Tv}k1l%me!Rm8r}_@@&d}kBf}&J%{zT-z^oFc9*IAd<8Xc z-n>ao2W03Sz&}kFov5IX^=VA)j`=5Q7vUFw07ajmjLdw4DLNIp_VVZ;#l zDNAtGZ}#&9qo^+JHee)0D)_CqzF$M$xsTicLW1t&M2}~E@3(KONG6(>`1f$M+uh`y zTZ@;3G{28`_*-Azw}|9bOxWjh7)xQXUDY}GHN}odx0K>ZUV-8l9ui*@xrD?^DZJTj#vO4Vd@>E zG*ZP4@luXM8z^el87@STKbahEx(1{ahm71y_;4vwEm64Swgx9S2}p6Wd$B*HFjbPl8Xi6Z7$O5OdoHbduehY1-IGc&{a_W;HV3*iZH7(n0a?gx#ZSo0L66Uf!! zSgv(pHs`aoqH*TvQX^_?@9anc0Dj!9I7p3+Yzm8@2rEVkSpd0#f=n7bKpRc6s^&04 zd|#R@5&-trR#wM)GFi+!9Y$V*#0&YSK(WRAAX1MxCA+bRq!yz<4Tyk|doM=vl0W4} zDMq>(d4s%{e`TnVM7t<16x@mgfG0kdr;H`bk=`9^BCo(^WBGiDw^h*Q)L7!NJQ+si!l!tCU&dIEX7bXUo# zIE!Kn{PvzB3u?BiJW59si8EjyBDr`G%vh&*ad^>}b-_~m@YtOV?>U5KU=8jUVl{k* z>nq+-D;Zd$erhW7dN2m!Y_7jEb?LgNNxmhYkTE z6>95OYcyI9msWP-&W!~T$ZYk*;@vT?#Id}sKr|(tjbbW%cy*YnS;@KXys;&H)EJH& z1aoE19W*||tMjMe=Ihdo_A=C~AOn-MBhJ0u#w}~VNN_4>t3$IV7w8tq7O|$p=$^H% zh6&B#Qsy*_?WH?C6%?~ds*vrN=FCM4DnneH$D>)ZjLba_+2x;~qYCXSudHC3^Sw4A zbpUxmu6 ze=7eN2%zo7h6;D|pg7S-#c-sd}oBiC=27?cm#r3J2UN$?L|ph^W>Vkf|RqB_?Qmh}GF# zZ@cZ#0rkrKrIe8xU4{gvPOj9|;qtyl^>D#|)`m1yt z#&k^rvr~f(Ksb;m$|8DZ<=X_HGkgT%+?RRW)zPI9FgE7$V z$P^X=Y9@lSzfsDP6OiW@0VF;YrRd(kA>;Ss{(#Y~d1{5=B7y9^mcR@I~mu;aQpiBAWX+`Nsr$jH%L{?v`oP+#28E57wn5wH)5uwN@Sl0e{(i1acZyPpPo z+eMpd$#Bitp189HMGG3Mv-ID3do^mOCUx`_4l)viOmh__OL1K6IQ-&eb;8%&E$DcG zPQsVbi3!tYKf+LqGCiTAonX}BSk4JsdWb>7D-EbkCPi?w(v+2<@+i3b0iI+z>!*<+ zY1q=zvbP5$dRsXpPOU^m;0a5&0$0~!JoM6J4EL-Z4uN75qgd$ypWSGM<7WaDsmAd_ z_-ikQBdH6UxHYF6@sGsU$>pPUGg40Dn<=+7uH~~MLTqFu^A9spHaADcANl0ErBU73!(dUYbt?has;DSdJ+2fy__0{*`x};viuqP6i;le`}tJD zaKeb3X=Q+RsYzb3$L#^Pq&mV?O|CeOj`=KKt=adXgQGR%RD`%g!hRxcM~`Po;vz7u zq!SOJ{!eMO>(vZ^^rweB1xtdcfpUuG!2^O)S?qxy( zkknz|LT9Zng3I7KWeR&o71)Jp9I|<3y2}X0-}9cW2gKI%p0+2PaLu-6UN%nH&#?3X ze`YuM8vcOYrH|)?qgd=3ua#TU*(Rq^K!x@jUOIPJcaJuJ;Y6EhOLvs%{M6!`ri^De z!a+OdkjYoD+=GXg=OmJY9{D5rI|KPUhga{%fx1c<;V@G|{F%BvN4%}{&=){pEEfyV z)`!i9&2Pxhub63JlPQc2KJ)U@rv%|Qb2E<+8>#s5sdgNd3TWL8W)-KE9&@==mxLrZxS`2{soEWp*5K6h+EK(` zM4>`K)zAzjT^6_5x!}zsRU;u(arAVj%(HO^d{;WbzLVsKChm90NRC}pe6W>ZdbYl4 zj=E8q>)1`6YiV|JN+}*Y5iHz+maEzSAXobI$NR13+lp>YB8F2@cPc26bCkyT#MH>x z+VM#s;niYd%njVYed<>7*>;?hGcx~8SqbZf%a`p}A4&dwIFtPJcGCD$H*a^nlCtDv zan~jp4?CA@w1D~D?q_R-UB2GL6MXoU{MVN;IiY!}Zw7zFmWUA^CR`t_@G%++D-Y?> z)pGb*)zs5F{OEuwJkP$S&tuqpuj8H3{Xw@RmzHN&RwfSKTi2wNUuhJ>hue3Y$H>gy zL1i2K@JK$<;57QI=h1gY2li*0EyV*?p^H9aRmJmBH5%^eZ5cbG^tg8fdR)8KwRP2p zYBXe);@89@CJr;mNDIvU;IG8Bjj(yo%`Ea_wGx+1?=SSs+sKnW;ERzRqyLSz_W+7& z>B2=ZD+(M1L3b zV3c>^%bQ z-v5R6m5d=27*Y?3^^QA);HigupTunjYD%2}Su!X;)915$5yME{l+yBn=uY||kjgTF zaQ9yX3TPT{_XFWr3OnI>QU70tjzVw?|E3puwtAgv%rNzQjk_i}i!TT{#Z>~)7AcSv z)oug*bzlFR3-%|OGv0@4K3r468C@&?c-C=uW=Qs2s>iKZ%+Bv%5~jm@H!*Q>LEI_g zSV5+;%uM5+dFZTd#=$3z9T&L}!Y0XZs(L00p6(43c=Qnbzy@SdK zUp0udnbA$`v~K)ZnrO1TY1l=jYw0E)r!rb}b7V-phlrCR5Dxz7=t)#-DZZZm^0RPa zx$lIr^yYZp)Lq|?g-0i_sx+l_(H|KLP4;pA#$#z7e9qdd#D$qUQzIeS@U(v>^>bEw z&3PlfPT(X_zaQa+q&9Y+C!>lsM~Lc2NH%Wr1I%|2?0}p;47z@Gs8;8LP$t zRxFRbJ++CNig#zY~Q+!y z)oGFGw^6H4EG0;|=zp5Lg$V23+MIF4DdEm)pZ_=#3M9&LO^rd8#qgZ^Re9?lySa&f zi^y=C5|Xf*c9y#`F&tLmTsHq}~3;f=Hd`Hu6T(3*nvmRuX|7ytIo@4x?3MUTgloSD7fT3?7G z5~|tUj&G0~A<64C;r#+va++BC!DQR-`lI>Hz@--$l`$N%$(27e^stqKl^&dqTVwj> z#D8mR>!HXjxnY2X--CId&!1AXI*L5zz$Pc!LZG@XW~1Y(g`e8x%$wl@f6e}KqLt8S zB7wzhZ@Yqzquc~eqJTG&gqhNO4GF1NxB&Q8&Ot?}Kf(BczmVXKwKqf05-Kd*>`ij6zccY*GHytCL_0;Qq>RtTS`d_~JU;l#_;pF^3e8M&V z6+UnHU!iV%r=H}~YRKrU1e3Zg&F%wNI}0BRgzgu0%-64(6`!ve;i_3dJ5@bB4-UL} z#QIF0oHVtuaI#vK>w)ueL-#rKDQt9v{zTIR%98x-oGy@#g3!>9vEo7+PtN#nZSF?p z<%KAw7f;XVyuA2^#>TmY=aq6~&+fBnNThMIS={n93@NVH zY*XA?P~`w_@_=9<5o+d9Q5x?1EnHfBCi?#1w83@aQ&VVJrkN?Nw($GgCqemQA;(v) zT&V*P;SK8O&qgXoM}D+_{dG4WAOMI2O(OUXHNSNoeL! z;pyvLlu7G%qyeqo{MbQ`(C;4(;?ZOTiBhu7Tie>W+1Q?~udf4nj|mA0k(87)7t{-V zF|zLI<5LIK7>tRGWN~zKB;n6Zt#jvT199>Sxil$mu=B?v?2uSk!p!OGrtjY(OMlVA z#yVoVLnjLQNzlrYn~!BLVbaN{w3NRFKu;>FdeF7iOYre%bBTYhNAUcWxFvv1J^^Uh7!!ycfd2QAB1KLYf!P z?y<1wNng0E_bD-=I{wCusIYD)XHrjWnkM_fU~?M*^BhS>$H#LxT-GPL*{?GuP`&1J zd5<$V8Pl>JegE#>{y?@G*PY{L)`g$<3Gl-rFjN$3U#qjzwO1wthK4C<&T&bUI)olh zVxX`^F(ZGdQ_kC`k#JbhKRM<3)bDNurhMV9nn$Za8b`>69=A+%7)vQf?kzATp| zycqO+%i~t6i(h4K7(r>f>KP}yNUMaH+I;hvZADAYA{9DP}N`Sof;aCmP&Q*}gqFcQOmd}XqTgUGG` z9Gjx0Ua*rBE@ep$cUX2@o3P-ni4;||o7~LNa!@p$o@Tf3rXuvUXc#?4kM^@1O@7HP zl14kf7uD?C9AeWv&;++(JZq?7RcVb83p?;i*licz6KfPr3++=4Snzv$)Do&rU%pkC z?c#G(PeG6VDR!33kU@wvXy5Hb=*B>Z>V*s9L>TO2SXgX*efnMnpIGgqdw#u)i>_w znRS&qo-Sm`JO6Ysv2^d*!Y3$SJwD6Cd_BT>3pXkmzm-?{fhCJ^@* zi4an=&dSQl2`065!JWgIB#pzv@+H~YZsJNd6e<}L6_xq^eWva#%d<}*G6?TH*4p?% zqm2hc!724_t4{C3*G4iaWWu#KBq)V8?&s!jd^L(AI%0HOwe9*%F5P!q{mr*_V3x4Z z(5FH>jx?jzv0WnamJC@^F6XMt6k$@2uSwz+MUh5paKin> zFtMkVrf2PF76TvL zeMNET6Mqe@maGyy@AbCpWAod8Mp6U23S^+=>&}wbZ{?+wUxa%%I%!eaX1_u`TD`{x zl?hu$JW3QT3wO-EXmn`vv-5?xAu1SW{3vW}7n!@`m0 z*R$r8n18_JGWL%zN`N3izvKBQ&h-yHe>dAqwj2hP8DDj0ItuexP-EfbJIO5Nq7$fl zt>on5rtW-D^WvXnfgA(b1OxlM#)D@1D((>e@1?=*-WOQH=7;0Hh&d1#DQe1tjurQj zs^M7GylV_|Rr&UmFaeZme;^;`SpQu~q_|&g#27y8;>3m%b81pn%81m|vh(Nx{xA2+ z3z}7>BgdbSy#-P~;aCW)tx#L(`U96b?=EerogdVsCA_M7B7^j=Lqp~vCC}Gc*N2vo zV3E4A^3onY8UPOtk$?U3VaU|Gvj)WdCWj8Xp&492vo6>^Y-eYQK z>|bn~V(##{rkFM;Jr$uXg3{t_!!)6xMkYxamG$>%7j;M0hWL2>ajzUjns|{d z7gyZ-Z_Ukech=c2#P6yll%;ZOU^H^xO3kgO64Cd^$Cb&s-MtCZf~i}-|Ly<lCcIoG9%}?$O3FdyWIf_~`!mkQGwO#9Yrs&=wrs9a!^Q={bHY_w96xIXw941*yDl9z?r_W6fchnPNehIWyaE1Y;U}EMhR`A!YP%O@sg#sHvxn8#Vs?F) zevIzEDI<`Vmnb7H_o&ki^ZTQQ@NCK%8z!0z!uK=YM5Bhko-!%`XZ>yD6cUPvhik&;Nuf-XpC|CK3U$^X4z^#n|1IM(f1TIX zj;p)eQI>bj7i}U;)k1%k*fsCFD;0$u8dg$Hc6&iBCtFB(fGk?P;ieNueR;q4>1Qmm zN^d*7`X5S;A!zm%^3W#Pte`3_4_=LTXQ+N%wqVpc)%(3vY0!!dSF{(er`W4UXP|6Y z{3;^6FZUK?e$0AbhhYahbD3$ZTxoWlj{_2#Agb$F)G^;k`Gxh_(x=`+D|v)eX1js- zUTz^{@hc4V(G$-I4F7J_M+Q#Y%irc>@=F2+c1BhP9lwY;RQXXWD=7?o=#SnR+Lm*r zc=OY;Jp9Pj(5lx;l!C{xZT2i#ndqxddHpg|v~X?r!PcYM8K)El#d^lwOYys!5tn#Y zGTM2T!M_3=Y@YU(Igfr?bs(ANguALZVYl%PJilySa_tprO;_9i*~(yGJ>HAq52GH_ zv%H2fzrw#lVVsNdaOkU=(zfkgx1cvRf&LVv_*yYi*H~Q_kx;Nc&$e7B66UK*p}$iR zWBh|}hl)8{y!ksXF~I!I#qmjKcN$|FY-s}vnUz`3y$cD|D;A)t)J!1+zjjE?Ao}o1 zyP$45eCjiKe!4lCR++f*iz*J@9z~%q))28?S051^P-&Uty#2u~q`;VlrsJ@nJ;5gb4yr!7ZjTum zgyJ3i6xvs*&+ff7L{$ma-JoFY{uXC5cVKe(6W8dJ8AY`-GPHJ@-!d2b1qXE3k!!r) z6^FHi56z&mOC*FD8P;?RhTnDCDZbHd!!vPE1eB(fw!e|<`0_U{ma~oJU_eE~?#(Ri zXh8Otg>Pxm>*W`dpt(aOZ&R<8o@~3pVY#rS3E>pnMu;Y6x-N>6)#ja?>zg57WUJ@c zifOz?bzM*U(@oFqX^PQZv>M*y0b08}x~*}vTjHK<(yrl%N$+>fN?1V6%c3t3Sc#ka^*)b0*3e@c%9uwRs+fb} zt8ETsk6ElI%4!|pTHA@^>&pWpUSfuMf`Sin+?Cj)B_);NYW<3|JbDiE++H0M_lZIT zDM=-6gOjaYTG@uVRYv;r?~oTV8V? zq_U+1HiVGfUucGuHFELlQZlw7@?R3KojlD-EcnKv9IX?w%s1wYY+#@mnC=0*$$`;T zmB2Y2)8v`+q1A5{tWr7`k3oVK&%_R<>~*O+Na)bV=&GvAu+0w3f_6opjH*}6!W%k7 zZD{90x5TPg)hL;=^JM9~us~t&JoW_(;nhq;RQAW&wv`j(JxG+S9AXLlVg0M7RK<+E zP~U`NgN4_B!DZOr6!SRj<5KQSc;zPcnmT^09WlvKmAHoxHk@_0jr#`7F5_GL6iF*; zg6-4$j1$*)3jy2PzPMQ?uU!!DPJYD8!C0}R7eakj$IIeH6~{wXCYj9R;9LY0qvJXJ z9R?BA>Lg~yhz1)@U>l3V>^W|$JqYp`%m-?v*~>Sx2=?OOiwpFZ-kM3ZQhD3wzI2ZI zf&+VA&Er~&T>%aiBZNliftE(&MtN#})u*9RcMMsT2R}aFacTE;4yH=@wf{t+anp~HcJ?*(iU zg0Q2b^tId4ezZ*PHm0sNz;2=-W~jk(bl#*O{qDix0o-szaBH(x+oYO|Y@*%+^CkXd zBXNAR%Em#GQSH3M^7?L18WZKlsOiD?+v0LYVa%QOGm3`EuFG-h&sT^Y7mx8crN+Jy z`j}LGu<*H~(}nfU5w}vNhWP8Nb@`;IqOxh2PJGfGV6Vd|8JZd{3a=oRaJ}eG#Cyd^*P-o6mc-b0x}*BhTSdq5tT?5i<96gfnm^C1 zNjhAMv9C4|wkvOTwP3pR~6aJ9Q0UwY`&T`o&Y-&o7kZG;(O2qj8;hfqh-EXu@L5{h0P0j{WJN3{t@AN>(g9IU%_n@b&*e-i>?G5R)xqpN&V%AkHCw(EU1*Z zkIMV3elJBoonKp@NK7T5rMj$cK#&)$pF83iUSs1C3ZIAbAz8YYlQ-BUTOHftOv7< z)m;wEBjquJw>1{G9uUk>81$|7*2surOv8uYg%;j$w5C+MpqOp&62^Jp_cF{?e6!T} z(@n^PiAZ=sMpAQ5a{!aOjk~!x7YpynH!tBQlMlx9Rc`8@{qbgCr(ngN(W^TJUBXhT zZ;UaK8L`<_&Cf}bSip;tW6NXQ?+>}|``C(Co=M!CwXq+oRcxo+7)W(a`P}>l2mM*B zxTd4%u@R+lyXLO@t@0j z&(sxtQVqBsz=Ub7@e;Njf80$ks%B~$wY%E2{^32~SE zy)No$up4GtAWN8U%zz&)EREgo4L?-?hO>q9lqyGc;_;6M z4YW4W;Jx-jSvo~^-v=(wYyA^fvmiWM=3#s_XMuMiTbQPY=yL7iB;02&Nx#W8Uc^sA za{}?qX48NQv6kQEj=$Psv=v7)OPA>0hCIIMaB!e!)NpI#cky@kfMUW9!4YL%+d;o% zMK}KF;$hobI8%5@{BcLe=s&$SrLW=|;dpfNs~HJNhtQnD9$=Y2Xip#a@YVjb#(>18 zTg7obsNRyQGnBB}6l#OH4}A6Wwi#Wr1S4eAUIbH6QV^s>-Md7^)UVM?g$8zX z@@@iv1dA8>2g>;yGo+6%F85m*W2Ud0RhnU&?5wC0*^qj~kkry}B1-4^>+VCDi(ia$5b5kmha|LxN^>Fl!+U@VsjKn z8MQ9w#o`zlie$yLDpNjmEx>p!m*4Ub9>EiB2FB~8pS|BcyY#rJwQx{%3`q>|^{wpb zMSGV$_&HWbR0>12A8yphRL&}3JkA6X1HnMIt2|x)Q5v9?;iosDi-bEAYHQJU#%r1H za4|{6Z8uaR+__lPH(slb zwg|6YDg0ZtxJl38uX)7hdbukz3k&QrGA22>xwq@dmBCS(z-uwTp#3`nI$1rHRX@&V z4fgn(MHmUpTV-*Ca(OEHmhZ)KW3xL<#kENhfCESGmY2u5zJaC}@d_4ZbjZ%dRNhkk z$&~q|T-!FlJh^e*Pr)!-q?yu3pV9AgFD=2h?G zm(*24lQS~PKO?FYoDmDJOOfvzMhggXZw7WFghy*mWXFBNQvHK;=;oTi)`yl}|C!8# zeRX@sdbxKYjU?o$0y{@VfiyMAuYM^@t1UlZ5|4E%5ihkVphV<;hmUmPf$xEv5FPmp zeR8$@;$8@^g{NIPEMS@0h96t*)#@|Lx5WaL;r;lkfs)K!1h5Ui-=+{L=cBkunXOa?RdK-_v@I7=|51^>VYbLkXxmnS5C;^*awdk!goA zxQ^);$^rRF!N-4PPzyLKM8@3k)eaF2$P!Sc95R&Eotx|J`Xq|Ao#br4u)&*_hQT=% zuANg4{dHoT{;VqAQO!)adu>G!*ahS#6qR2`%K2qKeuR)0Gv%g#BfD_nB4>lgSEzrB<)$Of60*%!qVC#I!~L=cDv$gs z?ogFds)%Q{&R&G$?0K~o*}JYSNhnJc^w!|x1j$(%AI@sw&X(Vf92H+Q!Y{iZ=!eRC zzB=?lJsWBsa|p6}iw^u2fF&z*)4X`W-(4czQ{%n?w|(cNfhy9eSLR*pDssg4FoPT<2@$9Sr1y2`}K# zhs(Il6>kH6WZ_`96Wc$0jUx?_0Ckfs2f6%6kGJIcTK91mOcL?x)On=`*tr~m6{dS@ z%vj}a=E`*fj%&r&ND zUhW?frr>D;%OLnp z%e8gy3oi-E%Cx?Kio2(YErrTZkv&#-T`rLk;DP`!0ywhs5=H7HH-2h&S~<3ugnmNJ zRVcrDp`g+~6A<1p(XG5U2@5%U#9!QiZE!vpq+OJ~y=dmXGmKIhtF)bv&3VVW-3*Y5 z(a8bBH)l>l8=cfYLOQs$xL+6>8;=J3c7$ymR7=1X3dhICHMxKI9NZ&|`Fp-I4xe$-b^OUfBa^5{T-5#Z)MXVB@ zU*pS34%Pe#Dezm<;{HO3~!6NR}J9<9H!R1R6q@Yt!80 zh$e0o6@QqWy#~xvI)3j<+=ccgVFq=R%T0^jilV6f+MCkX^Oc#Y`UB~v(1lWyHWQxk zD%h0Ht6;@##O|@-)ev_mx}`f2k9iCbM`PO5eZ#4y*NxY{7Zv&J*cUmu4t~I)Y_$&E%Pg%*x!$i5?~<)X_Z52(M(_Ml@*! z7)Tv`|7!>$#5g&~3dvz8*sDP64^QojR=@o2(>qjUlD87n6IRwh6;TN|@@bTHQGPiyYMUE%YzaSZcwiynbB%U?J;{FLkFwhDHw-R3<-H4UGJ={Bp` zRg!XshBVFMSxLhE?xeUlQP|-wB=I4v%42mDu}F~06+tF)f!Sfk0n1*B&J*6rv2xcy zuA=&wB;B6Qa`bA>E70QG5WNs+(b(+>v!m+nk?m3++to`^*`AYLdKQY8Y}bOj4;^Np zMs+cFqdT%!L^b=b9;d10d?BZl2Rx_p#f@3G7P73gR#)6j5-?u2!%F`KfDB+z@cc?6 zu8S)xC}0XS^4y#P;Qm!{JeM!KVX1pH)q_Igezh+4SUkt6|GSn9vw{d$$9fY?TFR#MP5`G z5*zUsb4SECKq^XqQM>c=B&B|rOITP-T6&V4k9N*&dvjC!xn*wE>Tt@MX>AY-FRyYu zADdVu8$0{*_<=6iYH;8E=G|su8nvBwP`=p11LmHC1AA?Pl3;?;%JBNl?)|CPVYiOn zuDnP0$+X|c&#dxawJ&`|My5ax+I8X5C0wqLvCYKEmX?m1ZXsPw+poKq85D1uWJI(O>+v^|i~jdCX|}=t=iFk}3yGlS9I98L;y7*BoeV zZsWDq5=FW13u!27pJXatsiIxXwhvfWH{XGP&}#)Pgjny(iQnzogyD)Ex8oz64_jV# zzD;Z=H!V#*b!0!_NyH{4C9Oba8Xr zI>N&h?w$FD-tvg%J~WhhgM!4h&#skC2?DO4VUnW%HKC;L(K54Y zK|vv{N2|{-#CO)|DyY2-TnWKOj@V&xc}XVRD@GTs&UhY#db5dky9W}aZz^D_-(8vd z!HF*N&YGkbd9gND@z5c2-ADofdFM0gJDqOI-?H3hlR)b>r&n3t3F%^FK^4Gz>7q_^$ zIvsx-&?*p1*Sb!f9nIHT%t6|C_13>s6Jm?9vst^o&OP-ecyY6`zQ27;R&+(iv!JXP z7r(PvDNWhA2S)bD)6nP5WM714Ve*k5j6_%We)(oHDo5-=UsCk@ z_vej3=;p_dwZ$Q`i;IZBK(YhEqvC(gO_veY16~BIkJ{S>qZQAY^eLW86BSwH6p*Wn z;bXIUaoe&$EI?fd;vx!>UWW!=Vvz~7MI7)}bF(iLme&68^7X|PAJ+r2qT1?TyNmzW ziQqmt-h7Q7rKrQlEgYiqn1w;4!Q8o50UglfX8$A*FPf8`&CScJb^CTg6sxDFD46Mh zNTlfCz~_C26|maeNeOATLP}&VEt>H!&8niHP?yl~V+Jl}W=9I9{m+ealw|2ILBQ`# zoqrjGHK~7F@XE8NNHHSnr_Cx;>FQ&>fXn|H}wp3}Qd>e=*w9yWuUEtreZ zG;=MDOpf9QqwGL*xLO$mBi`FDZA|Y+y)0& zwQCeVwiOW#$8(-0D6wBSAl$A$eFvH0S-_M?f8pg-gYa`o2XIh+OSZY$UI4oQmmY~W zcrg9g+pC75{?Et#Tl%XK`vKt~A6g3y4gbh{Q|M@xkBwV`T|2fjHVTy%0SqV-Q5sx< zf7*CkRh0_76K)eE2-uDJ)Es6ceqVw0vLM4HlXI33@Rv$^k$%SKw@0w~<>gn5e-g1w z3o2Qb*K%%w!=_dT1_ok4Zk+dXG(hIHp)QF7LPGAysVI_LX?%PR^bwg1^8vxD3vf}v z8rqgoqwqgxVeYG%o11e>Nhv2J5WB~|Bqc%a+(~uuT)bCp`{rNPYvwb+)7e)AWD#zm zLBDP*{22J?+S&xbk^B+B`!BClt%4*Hk2C(IoTk4PKwkgTtz=|$@+6|q=@t0t{|8R$ z|7!K$gv|sK%tb^_Q}hJNo<3G|nqt5s*2gTT?ZbX9j>x+a1^s{KShD?YF39z* zSALPNh2f9P{HOT)4)dtA>Uh@WqgF-W`6FFwA4nsnTbShe0D#q3$O27^ePYSm*k1qw zEjSiJ6J$iXaU+`6efKR~hp!k&?yTCM=PrjTpYo#k!Jq*kP(e{q!%()Yr=<;{5G2U0 z!Tn8)=Ct4`8J5gRdDwE#>dz1YKCJ{@JZm(Bn}Lxtz{Jtp+q=_z{IAo}G`CJ^K$eVM z2j=G4JooQwT^8e*ejQ)hhpI{K=U~wg0*Jdb)@I z^Ea8{)&IKj-*n^u)uH`U)BiS``TwN)=n*>+1_s5%p&zeXPimfCF{t7Z7Su0L@85z$ z^`hoz_4RUmCwYiByXR7DH=tW} zrhnx;HEM{-Z)u^)u`tg+?@x0o(&>G%H6=s^s~xMnl^S*KiEU%js`=x&DKs>**Z9l- zn|*!S(DZNPpDD2Q-$CB`<(;A13Spl`L`*zy+@MC+_s*_NEIPBXveVapYDo|hu$d^z zGG^LJEJY0Odo9=nVI2z_3AiX zw+M9`%?cIOE?;L8U_F+#WYZk`ZWVIJ^CQ#AWJq2naB-doahVZDH7&!e5K`+WDm;Q3 z;F=;H9S8*r^uA3MH|5VJ>45KXYjqVC^`+t_fWiOJ6_e-ldq&=ULFsd8y&CO&DH&Ob zKvFlLn`;FL=FBbP%vS%XhM?@0_s8NFj?03NjWgoZrUZWPf#DN9u97{&n`Gg8?=fcN z_=-XCgH=_Ca(`kaj^?)en&O$$3cm<1p}-dkCMEQriuX5RZBvj7*m6pqlA!=dMc%im zn}8{5WA0YOarK7F2>2YfkygczAZr=vqIm=Ij4j^$k@x%=ZYk?H`D{RYy3AH(WNqq$ zny60IvIOG@&6Aa3$U#$ULmU$Om3keEV*tIISuZ}-MH-FcXdSFN;eUwkh zB>k&`zkH-n*cMyRCABxwUTGaruZ=v>0)dKKJZ$26LRK*NMP>bbAKe=Iht?T;97<5& z1R4|r&maw|aVL`z`OnvUc1z2pQ?dY^JFhe?Tj!guPNg!f8J<3tq-G!X%6wHYePqr2F&`tUjBr1H4$> zY_e;shIM(aK*MJmlW$9iAd*cnx*)yKpHW*65;bQ(A)Z~Wa^t@RH1&)u~kQ&SAR zs6)P7NCfBo`*MyEj2XsK^$7bU4EdD;PVm91mI1jlj!jt?@s60Tb0%uXhxiKTK}#4O zUu`o1&ykhoR*13;*sTq|<|`*`JJk1y|0r#=+7|KQ!#lWcX=b9RZ4~I$sJOV?R>e3j zz}bD|aZ+G{EkqNg#!QUXn>0u<dD*42ur`rM~^0o z7B5O>fk+8x`AH2#WGUCx_5mp{;pCau@`n6|Y8{qG!H7H!VwCG*fFkCfJ=APt(U(FE6nv9Bwu!w90 zic9%uiUua>8keh_nhmOrWMw+SIWkGRJoTI!(E}T)sO;gZbUSkzy_^C9>f24nPz!~4 zZ4g&+u~G6VPk?a_Ri1x({l?0wn_ZHSmFdvz$z)xQ#Z~3R-%XjBnfM>nswA06^WTbG z2@V-+2MJg_=^r^{Htnxc3)_yiOg7o>-H|$4qFy=vcI@Lj=hPul9x(nM0yl0~#4ghcNp*p6`kurkeT@xTWBnossPoX6R&=TBI-Ox^sU(+V~+hdMC z6}@tGxE__=(%O#^5!gO#2ne*_P85KJYVTLQ(|4t{(9vYYeNvFOam3L z9Z3VR`|!3f(UqZsK?S8c!&zy-w?-A}A*$uW)FX@=(IwW3y!+0jreNOX!2pk6n8|KR>tGFm%f9eaM+JXB1Raw11A2M`gdeM1%rqO%%4bVdMro9);Kk z7Vl4$4uFL6W51T5+Hm=H#nTZV*Dpx`j_UDoeDQFZt!Q@xreV0 z=j-=2*zXiGk9ExKOv@i~vSsXGvwZa6qN zY&q?H0RXv!Emp;7y-uhLImlGaBUTe*&YR=9A!Ss#7J(B7C=~pU{AhsaQ=i1ozYh+nuLnr_{OnrF{N}Jj zb*1B?W@!H10q7vm!gl}eV*y~M3G#|I%JM9V)f0hXwyQSv7P)$-@9%pl zAHEEglpHUAP~y8a2g$qZ57IO0SD$$12~aSM7Y0+T;L3X!N0~K@0pVh&%~ozG*PW+P z#y?79+C)N3*M6+3pQQfQ8V*$2MU%SqtNq`RtgVvjqxxE7DRiNpoNLoQR9(Ga1!fyy zP&_5-;9~Qyy&stQ>tuJ#5oK@JU|f6YLMKl}*)M-*W3OEWlHuxy)3?ku0eG;g?Llao z+v>ivMYh%J<_!jPp*8h{Zet?lQ^uh(S|0phFM=%^a*23ouo01#e%gRUS5{)+y9WOL{yV0K74jez-x_(AlI%=Ew~jnWas2qZ$?>c?e1!m zwEIbe{_TW>(JEL-aFd9k?;ca%w9dtXE+fxQu*1E3_wgg*cur22_EO77YT&lPfJu%l zZaP+(?~K*(^K1B5+1~}>g=i#05u0K>uB#Y@&X5a|NE$^Wa63Be=jCr7vu|vKN+A;kE2yKT@X* zns?}mb!e0Zr(7L4H2Jup{zp&a*m1-DNIh0Q^%ag2^Hsye&N#8osvfJ6)s|v^y z*y^cnY{Lc}Cm)}RRd4Fx&@wX)=ZMm1r(AR2Ned{Opd*WUnvjqn;mcxd@s7VZ`cJ~% zqOcpZyNXecUQ8XVY~~ted3WLA3^~vgiCalm!I_)-fO#|Ui>+&C8*VaG@&s0CJ)r>n zQFVkK74mD>hBg?8eOt6L%kd`IAMNe(8x2yjDGnQ)AZoX^z8?3z_0ysK#6@1cIzt(x zKCh>!XyZ2KGTwjMKQGA2RYKd??iC7^mX_=Hw|c$j2IjM>C9c{Xr&VRA7Y5s7lG>R* z-i;2&n=>HtMi7(kQ)T^}KK;TJ8Bc37g=0rDtfo$5xR3wR% znD|3LrWRr}7HR)y(rgt!MX!2l)-5*HS+9|6F@7Z`5`dyodnZ><0v0*hmC6hYa-zgN zXI6C6gb1#u@S2k~n};PT3+%es>?VqagA`-vZzG5DUwdnn{*>JzM?N6Nbr;#N7=vAA zqOElK)PqQMI>A&8l1_B8CWSz!_ZfASOtD7){59KE`OWn-8E_GzC2kYw7QP=3zAxGS zu=9RvDyE}IpB$+8l4T^b*_DFyQ_*R1@0#20wEVNW-gd8G*dOES?6Xw`vY$@bkKFo~3xwRPyF7B9>&YGiamfLD@qxHC2?4uo zQf+y8-FJ5`{reovBQ}v$k|iNE*Bb%Krli^=90&O5pHu;?C`29}6FD?>(;%QcG+Nw%kjD1Y%%B>jdHV4SS zKu#B_%*y1r8j5&Q4~Vvi(2m1T&8C=(7329J zQNSt#ozsLoq)6ff_bO3q9^m--vmi(0Evi%O=yAt2f*BoO{~uVX_2wbi5kcS z5S1+?AV7bBd6Y<)*HIyyF29f21XinK=WF%z@_N)(zq7T0!BYEdSmX7Czi|sr$t-;j zVl$E%)Rau9#SnK9+C{p#i)job1vG2vO?7g;IDq9FQY)Snle>EqwH8^uK|xt7L%>;`mJp8ht@r0?>`|mc5A? zmdZ)_eg|7{I4f+%g5QFOmA1xCZE6Qck*b3^?gWa zXt=i95TtqXR8HB90J3(~>^WEqIlIoHz{0i<0gka^R8b_WR-xLH-kl8&()20e@c?DR(Yu<0w*)u?hBs9b%(~dIQ&{a357U%~~AJpOj=sHuGZKH0+1W7Cx0e%7Eq##njU#zd*MDfN(+$CkzqCx$T^D`fr~i>mMTWY zlvvdB*^fBb^~3`q>Q2TN-0|C2PZ6g!TjkSy<_-ABq3_FEdaK_FD04QJYH)tlnFa;jj`|33qMoLm4@$_}OF<^(Qt22qD7R{M!6|%>=Kg?QV)-6oG=ZN#zZS7woKuek>WP-ejFCa|CG~rhe~kRq=oJT|W|M z<6yfTVkq1mz%tTs+ksTRo=^eUV9L!@QVx7zL841t=}1@`KoF(& ze`iU!?SB|-0@Qs>p-~>+-nbPrHurcF;L>(yVhQNtvSE%o8R2%Sv2biw@2+HpH{r(!ia&aSO?BdX^bND0rt}8K9}vu z5Y2mTG@(QM1`)e0#}HKnVTyDDR8jW!hlGSsHV5)L3tYXBD-7(TtbO_r5nKC(dIrIg z5l8gim9X+Mb!WnCtG;E62G`y_M%uU45|}&lgwT?nYwSCvR`F@8{7KhA+yXRVDx)Ep! z?6*Z0D%(6aV&4E8-SH-wK0d2gmZ_B)3_w5*kuH-`D&F|%aj=Vws1A$RPU85u`TQ{M zgLQNu3tcT$@$BIv__O-^Hxlz0x{vI~yn)oYwo=SsY=|Ytz!ZgA#%XrqJ~+QD5ww|} zo^HdfjVk4lzZ1D(g-%=x_}x@Bz^Kioyn^<($eQ15-uC5r9Mia5m70euNVU_=@i2_m*acC@n8DFAW^Y@^Y4|l=94m^Tkr_ zk5JMe&sd1SAabohW>Kvi142yg?&v!T0PG-3gd!hhpS$x@uIJ85nWAj7oYSSWs*EH+ zR5`uQSb}6AS?bjXgI&|8bS~A7P`YyKRD82m(89*_Cf!SCmAI+#G1V94(dP$pjA zdj{opPXXpgQkC7jS;;<~TF2(0#~&fkE?2qO(w*-#wm6k;Xh3L9toEZUzBszRe*VTQ z@`Jep+F8ev7+A!3r3e4@nVW;d3SdoC2ClFnOn@70@Xqng2|_Hb!4l`{)B)@))3P`-hMAPzB^F&fOD1}`$Jw{-nJDlHvy(7 zL22Fze2ljIUm^bqzhIcSIqZ{(K04GbJye%X)?(G! zk0mdCtn4fD3FOmC*xt9NwBX&lC{OHM#R`RRA-Dn}26Ef%UP8sZ+u&eobk*CfR1FP{ zfM|){VzczF97BWxNNtRm&7hc<2f~^uIc&;1VJ7wF!BlMQ_~O)*$S$A!&^8lU1qI&O znq{|Pvq$2i-&2nO3oN&a(@UrgWG1ioONoc=`IR9j3D7D2bE87BL4kx4ZZ0l9lt2>= z>+bFz#>iMq-?AyP_Vx#mqR4$w#;bpw6~_m#AEi9cZ+&hs9kfG=h(WfWYAmJ5@p}sV_mTnP0rA6Jkf{y>lzsDtgpi}Mkq@SWAj|{0gF~~$SfR< z=le@KTKFSo>$%xQdG&~(fc_-{6;7&mJ-c?q$&o3 zg?AzgHal0Kzqrv(lwU$ZA7?j|gaj1c6~(X*cE33KCOE}=i;;&DB~O_hzJLZ9<}OgE zz`(-u_us8ErNPI5QII6q&J5#Jc_!@wG=~Lp3>xa{E*A%m4(j1^JI1m!^WJpPicQqp+5mTT=>yyPVsN{9IIFg~GJ&$2zHLA7PUp|9 z4W2u6HssUu!)J1xCNAhEA%6e1KKiN8cf7zOu4PVmb^pHosIlZ3$#>Y2p)<=0aokS~ zOR8#S6opxEva(G(qr&oY!^tROwuVRbXeEVAA~nw&9?!=G4S8V$G~+p-H$v!6m3wK9 zcicQO@(+VkVbTJrYHL@3hhV}y1DU$)k`AHwgex9iW8CWKXb*e+HseH7G&y-Dq_7gf zDzlzF156{6-rMg}PECmeH8`b{l2a zbL9}@b!4FA7361@-kdMb*~!V$FMI|JN5Z@mEtF#?-@~8WnVUlNl0kq z{tK*y<_bYU#q(U+Yn{9nDU9H)P8+c?;=4TMu`(bFw@SW9yjBf-*_A5LUwEO`_QQvc_QTeu z*%XD+0zk}l_L=Q$vAv`-m%^U_G=p<@kL9vgX+>jGlQD1>qGu=t9qFq403(4c?sSEd z3ueRXg6*CQKcUXg&*n>IhKBUnBIex;x7;L5Bp?O!frN-$;jzkzreLd(twRK~OYr&@ z1)DZe*J|R7$>!FgU3e-q#4kS!5pRw%Ch51llch**IDCFL1>*5D0 zbq!3ADH5!PjG(iDCU9f$=vpjRB-&_eSBxAKFs#yGAP;9dSqL0q?YrEUUeZ@mp$$N5 z3R|V8EgVv0aq9rWF;XTClh;}wZ{Rl`Z%EmPU>-es6m{9!7Xi~ZYLz=xW%I)Agy~x{ zi9pq^(Y~WSzqfIt;BTobvse;kD9&@CCL%1xXeopZ#wgJ!h67<2=+Poqz2hJF8tjS! z9@1|?`eq?eVP^Px!$yl$EKBXgq<4a@D#d%{UXCHX!i1GtK010K)nVWM{ixOCOi%Bg z+p$vYc(GyTRMWhmR>(`EWGFatYgH@~1$!cZ!h{}=Pa1g$71+svrB(h%@h8`)94llXE*bPEekvYnr%N1>&S=up+kj35-?zoV^B0!W;Vw~mCT@eAM&Lgz(nuWr zu-C@X>f}|~-Je4~tjC)#yv3TTpulfB>-G~I0^Fw&|I*?_lCG7-W{I7f_L1d%d(_(h zE(CZAHlAGt+@8a%KSfINKXJj`BYyMT#kh7q|4-CyrKJb_b*BfHHA6!~&F6N(j?h04 zAn?cQzvsF5f%G5tox3{oikq=JcU##RKssIbcoo%Be4c16-@sE6d&U>0Td4kM{w-HFWBd8fe}7 z`^B(>nLnMIo`fvs?NMRi>`1;f{4U?}=c)i0RW8=NJ-caQK(!XpM)D`i)HHrv%g%HuM&Gx3V6M{003!gb;9ZlPhV{LHK*o7M$cMwO% zJ>99!;2{Wi356YK?MclF(3k%FSd&WUxsC!&U#Ii`AyS-2oCMcV@c!V z$6}>$Lp@>mhO@^Bwk8X(?Y6+^C8%@eXg4P0LMd(4*qsP z@X#)fQR=hXS#mZwKB&a^v62NZ={%Y{NfokM;ok5*-V42~?)~u<&`wR!hmrei0sm~s zV6kX1>d@D_jig=te9taWZj=YH4XL7A8t#m#anDvMdV~}&NcEzsag!JBDt5~1YP49Og2xS}Mbr?XoZ9C+fx?XTOx@4gf;hsLv$a$3UWmJ$=&DbhoN2^DOX=EdFV`%S)Jkl^Da-h_%DKAOK`sdC@$fA)L{Tc^4n%DFd}RV*t{qz#XsoYAct&FqAuCQp z?HJoXw2cAa+{17@w(r{#X3lYTiFE!FiZDX5^Zz6XUh2Ha?v=%LukatHT2wOMrsYmh zF*3Qkkt%YT2|S^t?{FRYv7R1n6(CW}KR}CqH81iHPrpZPT+wJ3P7PEs63^5J*55YhI&&X_bFEwcDoANEKN4 zJg#YaLR~Z!`JmMY1sKCgQbdn}9h+lQq`Y-x(x;zHP&#BSI3v@)=vRZpD7TYygHslr z#Z5mTxBum@r`HH|&bxNLf-m05o_uwczHQuy;`O6$ztPRViG^S#{DN^VDDV*Mj+9}n zDu-cD1OUA@(T!U*w%r!{KC_$>-BaSRG*VY&xhONHhTySXT{-=(xWyY<$!^jJsy0Yf zURw^(uT50(8UF5v$p5?+y{^Ck3QD-Sxo20)Fqsy!>+560zn3i1FBS;8v6v9^krdvd zQI|Za&_v3Wvy7GYYPL2q(FhJfL3C!*n(`EJaJ?FG!V~w218RpP0=-zey{<5R!vDLr^A^le%At#EGW?gI;uFJPItbADH79~F!#Fergd`o6SJCIh+% zY=v5hZDanvay#ts;r7xEh1u8=1*`7dK~Gvu#4#2Y+kxwVadyNSFOZTr8#^mD_Jc^p zT)HDK54dtI5ZNG7LY1)&IL`XcZ=Ua3%wE2D(H32e=_slX>D>Cbb=+&jw?pp+@T_gl zLW~+fiLNcL@n#+S*E#)-jsF>9rruU-Y`q$uWYdl6{>b} zt2W)@OxV_v5cJNqx*BCRX(zoka76LuEfEKe>D=9caQk{mcx&6>?;obqdyMp99yzZx z*zc^tyy)9*4_YtwJ-8zgd-F>pXe7w}i<7e>LrhlnLBn`}q1JlNGuhU(vy-UdIzY?2 zG2<2nBq}$%c*1x!6^OL=M%cjn#vo_W%wu59CdmqD$4U|q6wr0_dWv^+YNM_df@wM~ z9$K5tI!@mDY*wCbc(Rf*$>KRiIIFT%^5W&ot^{4b2B_C$SKhh;e!ImRP5*DPE1pFW zE-}cI-joCd`IzKi_m01R3qk1erhL-qUd2Sw?JBfw*Y@3kl-A>GFiCj!b@fiI>(lOD zBkwDev0R^e4RtrjY-xwtf`K&+I^V9z+FHlKQ(Cl{%6{a`8h?cM6xUDC>hMJ4Y}wwH zFV)r6LsKIoiQI6yt5+YX^xIL*{6Vgfq>EvmKK4OLBlYzk(i?WTSV?b#A0m>Qw?I(o zqXxma1Bb_ zIdm@c_3PVMRS;f98yd_c9s<;HIS^nT$}M90_}G{k*4f>?yP8QlVP&FmCIV$^QT1$Z zOW1Y{_-EJ2938x_VSKx5Dxen%(SYvt<^h1(it*8Vvjlj<8jl|PpvzM|kD6)5jgF4F zEPcZqX37hhzqQf+@gsDRbhPQuUsZ+2MC1N_)^xY%cTp(Bi5arjn_c{S5lK%J$~qhR z6f*l+{t2`G;AL4guZ{Wc8y#sGrqu^kcG6p7+Cc9^0rNIjvz&5RMjeP?3Um_@v1CkJ zadL=9bXj-j=G=PrN3D*~@bca4Od+J{wdT#5mn!zbTA)uLl`boQ@3X-RbTeV=NXPCQ zL*B{{mD%u#QOmkhb1d}O2!7~>`~#i2l&aL&-{0R8n*+nVxw*y5^Y@n?PW}B$;3R#F zom~iBe*dBhxV~xtAQUK9NcgX1VPf7Q-cH2`gfcJEG1%RW2t*wFf;e2uljY+26@zz0 zXh(eHub7qv$Ny-74XSG--JUxB1(toI9IoMX`i^MDm8-;+{KWwdE>2!)>FS;s0U*dY zxj6U)Wt!p2EEBom^UvjPbAL#*T&Zi;W36_B-8*cRqHEd$1_fGUT-&O^Y^v-O?`+=p z!UKwZ*Q+AOTPi(RO5!)X{_4w;FxQbG@T!KAoE@i}5!;NvWVv_83AQ8~POdrk3vD4G zum{=%6Q1FGqQCnms z-4|l=_3K`-cIS`L0f2u7xN8{4frAIhqcx=$#*Y5$=<(CX=R3nOx+~5<zqp@n{Kvn)oyq@8s1>&ITc-didV0&aG0<3de2ZJQz3FVY{+e#m-9Q#Z(e1r8 zxPdTRP~b>#*f|Jm#S@1N18pdxoqm>;_(PTrc+}G;Po^t2WvB6Qt!1nEP@mX|KpWdl z?k>xt2N0^p;r+70)@5XSfvYA0b#WJSFQs-!)r( zgB-m$iNCSoHHV^>EcRpqG(GcZ%j>RTiL4lC>C42DTgh`q>w<$#``#d zY9SycyqauH-Wnh4t1?S}Rw;AMnYgXcvW_#rRxL*j3>4DtFO(OC=m;97fR3p%0;KCx zCil^WvRl_;7pF7gbuYjaW&pF^R~NNG`=1Lk$JwS5g_)WN6H*q&M;qAdm|96bOjV4` zTX7Sy0X6LwrU&{^t-y&!v;-%7=s8rG&C>O`UOa-S08SbnA0I#YH7YTBmV{a$Lq7st z6=B)9Tqx+Bri`3N_SlJqk;I^M)waT&_~Ju5!CJf=*9$ElAXv1`ND`;#3@Pztz{~dR z(;eD{wG&7GI^fFrA1i<&m-BBqR|{r(RHTnIbM7vqpU^w^?9wL}4RXI6;dX^DwHb0b z(1#gvQ@TjeM$6aU?*TR3&zvH`YB%5eQ5Of$WgB0<1;orhUZo~Tdimq^?SG|##Qz@} zrQOT?Pr#Vn@Bg>2zS&$fx~aC7{wY60xRwio_DZrg->K-o043v>mNx#AejTqvX!xh> z@5|5fJ@%g<&oP09??1)-{cnf}C8y-fGW8 zo*p&(V^4xOw2oPEbdJc&i`WM~P>ZwnXJ7|-&5dM&YSS+bd*XwG)7~Dr7o1X%x^H}O zRzOHdH8NoT-aX%$-f}`+CGS~Y`6)q@V2&^*#^92Y^m{xovtIFx!CcC<{SD14d5@ai z5Pn!Khvk}9n%2Yjzk$TB<~cgJBqF^*Zx|0hYJJgR8TLB#4pay2d3_!^uj3%Fza8~& zSF=pY-Zz9E{@ZQ;9<>W$yvGyBVU4rqUp=7C`E&*3s|85q>YiM~izi35Qm>spK;2@7 zRF0=>-;TF7eC>4_Aoz#xf8Zv;Ics}`;pDju>ud@V0ARh|y@TJ%U3f2|Es)C+%(cth z10}bYMB(DicTvAwB{Vv7WrHFL-}K@4UULQc9#8N>-)e`{sqV!Y~=P?eU|IBGoZBt z#&GxUzbG>6HmTehGOt{vna2iI-k$p>uRkUSe^s))vZ4i$-hqh22>#2+CYf|GM5gl* zk&(r(JjGtheKu!9rq!2|KhW3%tQR;ivY0S_Lj^FO`1ypu{lBPnu9`-5#kPaj1LF5U z>b!^L&sIPo4irHHHTHu)pQ(p; zGN2mr)xPZ=mstS;paYsQY8p-jKZ~y6mud`NFl}-2N^r`9@O6qGDD zYM7Y6)6C+B4yFYLbYI#Ch`Nnw!?xdO%z-5wl96qkP10YzRT z*=3&VsbZb!!+%Lrzcw<{7Jk`bIc-0T^Er8tHue3tt(|Ew$fhzpP`2%&o1Xb+#Ci5{ z%FG3U_0FuAeHd^}{%H&o3kwcsf`v|lK6(zn3BCwIq&%;X2k$Fgz`7^u;uH%^erCV^ zni%Qy{1BP;1@AurSyUf8NP#+nB%!LEtFY;-m@#d;>Lu5zl8A5AZSFf8Bd(Bl(au#g zlSZ6Lvc{uFK!-nS2xSZhAW}A zI7o)H+2ap9OH-Q}om|Nz(=~j9rmh!AMt;lpvF|Zw!NsF2|J<=px^VX^4>6L=5T|IA>bdowl(T$IYkIz%Nt}r`3BV0S; z#;=>F`L)-%Jkw2C*#nzm;++^@8|0~6GU(|KQQ7<$+|{+F4gZPRu^e|lVwNsuIz1xZ zOEK?#t7=u1i~+q)baQKKh92js1wb+%+NLj~>L9~3UNBbbW^k04b;8Wip|*Ds2d!Ek zRxw}ven1;?=7w)tnBSfBq&!m3)VKfwTb`SrE_XGI15Pf1`=1?fom;8$vBs8;$VnTW{F zY<2I!uHvwc9PQQGW^R_>8P8l!iLKbcJKdD8+~`uP+#b*@UtM=Q{QIweGd6|5LssWj zVpU65u>Jh)q!xGfGnxcjCX*#DayF^zpRut`h6-&_W#%r;RW1hCh3y00C61Zx?H!!x zuxorbgH_^Rw1L$sy1l-`vdDIEZ~A=Rv%H|7hVb8XpjNLdd)QnycTqTN&mPSP^!2M+ zZU&y^K3m>}&^+(#@dmt>T0(Q2R32E|MfBPgZ^*-w3VxsY^#0mq^N*=YzrlJK5)qNU zTT)s_3vAC6zQ|}e-tyv$6+HP3(45v4o0V!A_dqYzcORf#qbP~fKXbM{UyNZb92^{U z#gsH3KKy%Yv+-7uX$Qz;bD~JcjreZ9X-kK-@VfF_>Wd*(S!Fi1g<4~yi%^`A8!Pn% zc7V6bK4mw@5)+7w>?C9NB3-yu zfzg<-K2sFpQKFT9O#(Kz3|NP19n*9@xisqEcsXeEET%7=5E=CAgECL74(*XfgWF0 zEwa(Z+sz67%kR|<{MC6IL=bJ%97hbITP~&pv*r4ennZ@;{}g+TAGhUyThT%!j74t` zRChR{{_9bR2!T3}9`*65T3iB zSk8UST0YK?2ze3hzoZ;ez1-2UQUYNcpp?{WNT{h6@ENKNK%gruI^{30CS?7Hj+Zk* z3il}stEC|34;+*q9g8ePs`de)?*zW1cHzzl0E5VPKm%sGShe#bPWsVxFX3$|FtRGY zvsl{+zJm+paU1y;*f$tOh&l}A!rI@99Tw1orde?6bGr%Jv7@?@$+A+2j^4(+C|_b2 zYJ7{R5g1BO$j(}COj+&1wFoFCMoLN%3IMP^?A*bJcHSkoGi7$1suUPmGO%}5+d7xA zw$<$Yzixx4%Zux~Z|(PEwE;9bcCooSE2~fJ)$k#;NAXF2J-^Mx$0wd3!GG7>$_0?mpqLPzY4V&iiO*%{I@wU|%mN4)2?0eKGB_*Y9slq8f zyB3p)$qDB4z2El1g5USfqaw~{`_D~Oh7h#ybJnK&d0AIa&O^zTC>t^|X}caZ1A7E@ z-0CQaCM$*|ipOm|Skkrf!%N5lhr_2@rvfygEWyxydaaAK)^rcgQ3z|Zzka=-ows0v z8p<&BS;8%~n&R(4x=`@y9r1aRE87uFwSsad?eUx1RJi}$Uu%4Qjz8Hsj%{F~_#dRf z@f#O|w6g|sUGv5EX}znUe=Tlg+LAT;Bb#e)PLXTB8@j#dbm2>TndsNAGt{vG+GBSG zCdOukFvPpelv=%-xXb$Eb{cc_A0Ieb2z2Sr)h2Uoo;A&_+29hQ_*M?J$bvflEN(7 zMn)0!CKbKrUy8EJoIaWUA|zc;My`ZST7b@SJS;3M^#D8WPTA02fqt8hb@4p>!i}ZJ zcsgF)n4*ixADHlYNt4EY9oKL8^0mkS9+lg(ziu5dy3ne6^VTIq>t&?LIbS8a+$SC@ z{ioUS?Vctv3A?lkJFY+t z*xleF+3kl1nY_`nV%wZ2Po5-Yj3h!^&m0ifQDxR;4-=c~lJwDfe_)+2H#i@sZ6lhxSVtYX<5(-vwijJiAU`JCl1c9@Y@ zG|lwvMhZuqqQ>1f(S}Old9BZy`canDUj!KAa=w*mY7-Zlbn0Nzh8}pbbAVZFg*2Br zhPwOtkH(&aM>{Al@_m%UxGmuXtZD{)ysu?hSd-81_s!l%Pr6Efp+2VgUf+>Z*^_;i zp5a4x4eKj%;6yX8j2`KGZyFmepq~N)$k|&8&$y~2Sc28K zUAO-7rDPgRm2;p}2KNj;KJr`Utu5=VNlIVAGU(8X)opcX2?i!6!72I4H>@X^8Ykvs z={{WnnaCL?n|yA-yVi-%;TRb?q?M^5Z%?z0Wt`hF^pXP;6QnhW4E4LF{PoF*HOF@) z-5vYmJBM25q2@HX*xn#-7)L{+Z0_^O$b7UpM8n#4TQ?L%2B!>xevjyGr*r-OTjWqe z45#hNHcgMY&anr^i|B)o61lr1$T!YYgDYgFAlF#k@7y` zv+0z{czv9{75gSK6N@tvxKXDV?%I}rFKf!VaA0r+%P1}-Vg1d_dwfodN=L%a9^X;A zn}&)Fd4Y=5*5H_igQl1UmGlsZ+7LuIyfG49?~KGA zl(?Ep%0dU9VP&P6}*&ke4Utb5T+oq#D>>2U$S8~i1 z{lB+s{z5HdGteEA8MxNJE5DQP4|?gIEGwI&SMZ?;?=KUCU4p_dU`$=1yy%L)reHN~ z;;e0U!zu>{m$kh;Ttf%^rxQ^h-%hu^BA(i zr?8$1ED-{dPwR8qt2*-+T)%ri*r5!3ON0&N^yvnPh-9g9w>Pn|vFr0p-K>KPr0pPI zp3V^oQ6oWcx%o?S?&$TucDHc%{BNZ@%2cjIqgVku)+PHwi0PggZ=`D7-wc5AK z`z-r{Q%We*RzLPT$AOk!ti18+)hnIV8VTTSxKtz40;7w+)TO^lQ}s{+ z(l-AqrkTK>r4k!Gp|i8i6{;A3oDHAv=y?D=6=wZvXZIZ9u$-=W2<;!#EegFFgy4$~bW3B&Mht{`A8{ zsovwkYd?%gILkV>!^EA&GdSv-NZL#rK48YPUiOWIpQ?0n$xcyu#40j17zq_t1;9Co zxKg3RJxfMrhb15XY&(M)zg9+qq}cEUSoU><>J)X^4DvQNb;0@wZ^A~4Iw7Q=1>I6J z?W09c4)8qp57KpV@)1~S&~BDJpcee($@QJ(se|ZtIi>+Dud>#(Q|{n|;;qZ6okd#c zV7aH;+`qkqM_BV}87|?L)O{XeifZz+O))A5?>lc>WQZg>xOpTvwa?e8sNV^8&B4J` zG1Oi7{fQ`G`Pd@6)X?Q#`%%*agW$uLD1K2b4&sx?k`O}YSN0V!f)vAdpSLpOU zf+(XgA?kpI6S+Gt{l%DqZG&Nm;Qc`6i$;Qif=Hp^;t<>6!F>IX?A{5Jdz(TbXWV4> zPTFKQ-gZy8<`c+l)1)eEv--?cC-2k0L?eQo1#d*kyDf2X#kB{x4{55Xyi)ibhkkQt z-Ksy0LcLGBOt3Zc&WVXRqn&xjXWC)F8g~&^7UqlFoalBh=SgeW%nX`f=2aNU%VO_A z2VzA#p5H?c08j-2t9Tt0)gNLr((9|LAUNk=?tB_u3FBp_zj*{QQjtm0s`7o#O!qvt zC~4RCo*QI`-%UM+c8ubQ4_ z9TMQDuT^!>6lY?ROWOKWAPzZm`wNZm-<%vBTVstYrYkHkcpR}RIHk$3cn0>Td)Aqc zU6Vg+riVtF8b^(NOZ@dIyEqTzx=?7rvp$Z7g558$XUAga%`;PRT<6Dp7i+2q<-~@K z4EcIe-h^nDx47b3wmS2$>=P3cGX$|(tBr-f8wbLSD%xSi41xCHNM$84J8C-$S~3k5 z@A%ddALeY$;juYx)41>Tx{4}j($O6+jEk~Wj}N#km7U~809v&Zp%qYQ--YeFyE%37 z{Id-AyakZ%arZ}*K4eLH|or)RcSXGYISsIT3gRBFZZ!X-aFTKDFU4InWk{rL{W!u zj-92k!w_{^M}qzvYE`m1>U(?9j0YHO=I7?dZ^yI0&!gKWJ2~fI{|>DkslKr`*{_K( z;pp}kN86&d*R^7$+*M%5$wD8+HTFU1%zF9$O$e1B^rUY4%lDPrd%Y<{Yvao^u<_d; zmii}#ZPy2wLe(9G&w>}BQn(Ku9#nnSWZ!lJmVosx7-BivPj+dyn z(Iwt%LZYALzzF}rO(g7WY_RCT=#{5C->y&!ALX?hihlhzr8e*ZN#bw1klM(h^BKJe zXYk^smJJ|H z+H_Z;$LgxiN=ZpQo$tk~lniHv+wUh8n^~e5tun2Jht+l5e57d%ID0KW730nV`vl2> zKKZ>RMWm8OVgzg%)QwrZV%SP!vld=Q8R~39IFKe_D7!NWb@9LRxlPe)Iw8`8+ojWS z!hXDa?SyOjjtZQL|IndB3?9oKWjc7Scu6tXP@vxC`$tb13KHc^%Gf%^??n%^^pMn_v-zP=kOz`mSfWR%4Nv6%wErJ!wy zaGe*7s5fsPZg#kAMXq;2v&tZ}yA{jb(? zp3J^DgoxXC_+hiaxZI#Q@82?PI(=Mp%$TjfV2erNX0YeRoI~aayALb$H6J$*j9yA( z7PIAr6lIf&>hP~NQHSlyqG_fh9py^BMX>2c%T&>jb@KeqL8yo1!8@Zh92|15>1?OC zv0_6YOG2(ktTv!K@%b13_1~XMduSvNo#KbQ3Q3EuG!`2yEpw;Z6axT|?ZH?t)a@)_ zJTDQ?;AyZwemj0{ZVnbo?mERVb8I|))+}gY5G+6ba4oAWM1B++n)3Ox=8A2nTH)PW z+Uc)0Q55X_v5aR74}kbd>FEiP^je51cPmqt%{$y??CwH%AaLlAS0Kwy`NI4g`ezFV zhq##7SaXdTsfI4fa+_uR1vT(!xj+mmvhPsD>(UaWj`%L{X=hmt0eO3)yPp$0hR`-0 zX@nC#mob!C5o(w~r1E&&rJL3R5kf z*Bdn-c4ve@2zGJunVy9tQylDM>+AuozP>E`*%lmNDUa~WZd-XxvKjc&omJE_LA9Tk zgf!IGgyo`93sbq{p_hl5*JPF)F|JnKIxtdUhp(;gRlS^3T6&*hdRP~n?Yh#M42#UB z1idLW*C2a3i$=COAEV_EB**t zW?074c~o49!D!EwO*0_YAsJgrzG$O1)!-J6$$4&e@vxO%o%jPeC7R&%It+{DnW}S? z69+IMp3s|qR%os@e-_XQ2*O`El@!XJy@(DTAO4#t5!E(++8Jfn`PmP zyF4&RSdY+VzVzKg+7YK(DZ61D_<&*|pij*ywj<}#a3q}v=jDG#Gd!t08~U5i86d?As_JxGuCA3{J2%YzKXYx{T} z40>#ME25Q2V9J(*AhW4cR5hW^979+Aifw5>ne>Ox)!fzqqup~wLOb`957Wl#NAG)0 zuF?a$kzM1~Ran_rHDi>TB0d)?1Ril~icl~eBOnzm@fWs@Sh4d-b@31SvX&jdnC&2w zhraOwIZ?t{R&5PGsuw6HT0J42H7w8V$qx3B^ygb^8N$#qhWL z8?<|b(1AzD^L`j}cOP)1L~?v2fQ9htbUG(`#E(%aSQ2ASbE>JSIqi1=yy~Hof(S_@ zbZj|GUvsg=TNhR-B$aNR6zK2VdP9>u_6B!!tb+Yo5p@cK#OHk{i#6F>;?uh^UfK{c zr5rxauNSKn3|t&MWVUAnb)Ft(Y^ZMvBVy#>L0!0m5r{f;iV22OHv!&llo z%N_gJBW=CejUtx9c=v}YuQ++SV)Ka&fD)vEL{q2-4>;PX_>v&0# z4QZuInP4-s*g6P7)kPJhU?lm96t?V4l3yP22xMksmhuc8ibfgN^YR)HM}*KCdOd6& z9wedDjUd z7~t;f14Vt|6Afymzf=z@BMHyDCH}EBPVbWieJd>|`!_KLko{&tY+EE{7bHW!^Tx@^ zDSPrf6MI*T2YZ(3ehk5`ZQxQIq~Zfcv&P@!;!x&TOK!{b)ztd{Q`x&7Jqy|rcERru zMD<>poSRDl>LIh*FKD`dv8p6WNmaG`#>aSrKy)w+DQYPvPl#xcJy?;$vV7OVVg|x1 zuz2pUIrH;kmlpHm|2F;f%h+xGbzHNGlbcg}bF1`$M@97-eN!3`P-e5@7T<6{evssE{OA0Sj4l2n$(wbbMtG18?xjL!mPQaWjgo++phKe23(c4 zfk8R5=n`pga3Pd~l&7m}>a{*S%h^~2PBa#l1s#jCv{qYeK$vQ*B$&N*HxaM}+3s#` z;UGLfHj8kdt=Kzes(fHsGfZDfHaWdqu2New11M1Dou@|{5A5C35Cpg!XIcsr?eNuR z(ywdSlwZc{3N!BCbK7}TCDo)PJ{|H=x3^zw?fWM_ue?SXn7mUOhCBNBpp08vE3(Lk zST<|J2B@XBf&2RWY^{av1qfI%J_J3?1%qtZZO|H|EJ5-;cQFPQNj;Nio;!&Z)gqho z)_oNB3?Ny@=f+b^q!$SWwxZFLjx3btYEI@$|DXterQ-~zx8EBO-pdE=U=tQ*d`j*% zy|s~;LPDL{$}*}`+Z|Y5zZ5DkfPqY5d7ytC)9kb-Dd5V0U#}s=>Y|9wJ^4SLh$0 zv5^MH7fc2<{AHK53O+F@=#kbJ&-AFYFw9{+FkSL>DCY9=DhVhBc4Y28ya6G8=>z z$z?_URb!qIofBFEl!WR~!`zs=@;JtKmf5PE+$vJVop|6-yJ;<3tU%xevDQGW!ljktsqf>IA zSXc#UwsQcJ!K!!6M?`^ve4izqe)P|}JI7kzy}Ac=AkjzNrh8nsJOJLXyHPgWOT26z z2n)JrJ=n)Wu!%@z3Ggih{@8szoJ|{8oLgiUxfP7S0h?kgC|KtKVBtSLH#dy?TZ2z; zxI)*xS`oGjH;^hiD(53*h@lE_Y|Izpn>=RBxb`&oKqG&RZinb~ZfQ5vfTIum@#~h5 zCTxtq0pIoGC3fr+jsN!V+w_4_Qt9Wk*!nMO!!)`kd~`&D?aJB#cyCbXYA`Q3gzzbq z7u|d(&ag_kYeOEm{CYOGwB?M~N=o_g#>2P=p06jis@jNV5lqT$k3bX;^ZD?xj zcomCdNvE_dkG*^zptU-=*C|J*Nqi^1zP?FYK_P7buNx6k7;=yL%-lcz^v}^%)NrV# z!AdfwmT$(#GbRkYMpK-m2?D#Bm?`{zQBVLSBqTKGq~wes6#4o2I?k4tE+M%H%I+IK z7ApkMxiMr%I<{atmIOeCE4k+?G-J2<(TD?Q%!9x`P)ai^7OjF!&Y5dz#RandI!N-sJ0zUu;7@ z-t4`q2>F$z>gU}65FSxsi1mR6Y=5VIG}U*IS`#**&sIQ{J+d8*vgPCEzOh5FF60~! zPl3^#1-~4d?&3fPhPjNlZ}sFA;_~|AA%+^PsP4>Amjk8-9b8aQAmY?%RVlu991>sa zzR>z8QHuiR?_J$r-S5suPMN4d2o6-lt1}W=XN4HL^Kq~Eg@kk^%F1dvgOU9400VP& zXy>t}crnAkogEPP(LCL|L?C_8MNCR63e#pDdn{&JhpdYI74S-dwL@B(z5T|=Bd%Uk zDp6ZQ7XnYwf;BWWDV@SC);+=BT{+{+#M{~~lEuEEcUJlh7+6+(kv%k4(ybHW`IehXAfz_C{0o#f zYMfeOpLPlwo&4H8lOyFKDk!8HV%-osPZpxlG~ zoqCAj!B?9qfECGuc)vCFgETRy@;O*l)mJI?wZNI^*zIFFHh8xws-Z1ESo{3&7*x-G ze_=&%AhoyOblY^7orb_)#Ae)a=iN37Wxm7Eduy$$+h3+5`e>c?SegLUd}J!z`51Mi z?l`%B%5&s8I9Odq;^lQSil(ZP(ouev%^|$ z7~Gj_ZyPxWUSlVYiE^#4+NMC5$uB4~bg4w@!YvZMA`^_I!Y?K_?tHDOZ)j*QeSt;J zXp7TNJ^MJmd;i8p=a%y@>5DF=D>!x7rm<_j7D6W;LWiNd-ZfggIE-tl#AXG3Y%+WS zwlBy7do>(B(dvb#6y<#(4|ou$B={?A7x!gu)5WxM$VuTPMXfKUt>jP6b@C4oFg^E6 zmY!W{Q>fZnpVxJBE0!#3!Cr^~`%{ZXqVDR$yPnw?44#<=&MQo7<*G0yR`cbu;HP^x zG6Z@xxik3C^d&GU>fohdNm=ha-S^%idMNUuvT?=0T_X*ft!gH#oo9ibMCV zZf@=VLYKMGRPTBA;1nu_TtA%mM!Urq_lg}Uqh(v9XI#2;$#qE$>dDtF>za*i`cm>Q z+jjCeP1<5{-}l-N6v?;9tcC(TZgW};tZ3Z2S+mHaNrR@Q2z9JxP(S>1`pd(=#vC(` zJ)`|X>qeHG@v&J9x&0wBIF16L(Eu$#-2AV9sh;)|_{22nR~HPnN;U4!G5qdBZQAR+k!^JCWnYLf%m;DEB}&M7&VaM%y$=BNH3#>F)%o% z{Puo;N9bgBprP9-KThyQmAmsA6z!z$pzoWx8z>j005Y6v3za|!1T&VXcRDU8=Kdy@O$^6)gk_MWaUI2qS6%p!8S}xsf4a> zwJbNcE|Iog!G^nZGhT4}lel-2#gBv)-~HITXd#GFYrSVe>yAdjL87FJl-$Ot^c3F& z9M$W{+S*u<6_Arnkuq0rB+f&c}m=_f_05Tm16SCGpQ%RrgC&+T#_2HG1DoOWZd6b7eGKzJh=)^)M@q^NAX*@Nv{PSh zR;&V8pFk!J7I`%4fV^ZDSS6*+r1kkegSh)WRb~;8>uT?KZmLRcNAqbps;M~SZtpOY z;}+acZrPafX#N6K0!IF*;6yK;enRpM$rZ)UBvf4q-LIv0)Mc#jOOBd8)8Pn8`|+WN#abLF!s zg7H4Qlws{g#o${l$!pJ_O3Ik$@I%Jw5U-j_}hw$ka>d=TC^h2cilMvvh9+DQ5sU;okpj6hm`ydLI%EuL_i{0cJt&8ux>XT% zuyQiQoXifzC0qhh6AWPyP!il1c6*yAlg+t=?|-igkXQGaB!5Dwu7hUoS-%lV*$L@< zS3fle(ef!)mYy#X68WLPVpl2z+cYe0aTaY6&d`AM6?BoFu$*<(AP{41fB;SQ?cENN zkmPB!hXMb_`hfB0jtiMpKt*PMuFPk)f&u_O_wbkjwx7B04d5Jg4NK=?W6J z{yCr5vCer;5d7c9#V39=bhYaBA2-FMSzZ#~&4cL}KdHA_~QT$m= zgPMZ6Y?`;%>KI71tkx0>v(L;Chr>r8S0KpIr?yV_+4WYO2Do8C?oa5VDm)o;s8@6l z4%!0T0tvcGEm0$IX?ET1;cTU#m$q(8jfZ2zCunN2Z=2E>dd@uLLwsUAa1{q|#ftB2 zLhdgLkT#Q`YUM9BXv*=;C4N_>#(Otc5KToLsPwnWfE z@4%;e^0nZSS%iglopx^9OpV!0FY9?si`SHR-v(6Bb}`f zQt!4xCKDn@&X$*bd6BD7@{sJB3^wYUg#+6gqNEb!f;nCQvE#ks^w@k2HB6NDN;U#0 ziTeCOVQ+k6xj|y4$fU$mUa?=_T?+=}j(fhvk-9>gB#^5OvV>6v33o2aommTPZI)y% zT4kF-l_u>rBLu(mI>R)hmoIY?Y!9R!t7p=8KB-t5m>Ef@Sg7Sqb%-}qLRb4&uaYK6 z##vR-(Fcc(veMs}HOf;~cF_)`w(Q?FB;HnNl(~i<3u(ug}J9UR`X3=vx4QOBwUq z&r3zK-bmK~#{ORQ4yC@dP)ao zLQeEjPL#>HMI4P6fpCqo;Lbb2VcRa6?K zY<(IOqzOvBiMpKf_VHE=#8AU@4r!3Q6|LOGYC!`%orEV!mHH9sdafZ5mtX*6U19)b zo6wr^xxYbP5f^Cd1=HB{U^{j5i_Tf%fy(;`D73Pybyb2Bb7eh9#VVM3=Gd-iX;)<~ zA)OcOa;s2cTY-=+z{`EUr`QERIYFbh5=@_f0K2EqV~L%yc+!hrF9CI+Raf^*Qfb@} z&ML=Dv*i4p$ zB@pp6`*Mz0ekf{IKI^KSQzmx_eVqU~okN2RG#x7i(bRL8wveCy@|fzr1Ypa79TgE> zS$QeUzP2e+lB6zN-g=Z%K9OYO-TWfriA{Tn3%b(uQlX2o@9&&E^yak_z|I@*5H3oFr%wim@6G6rHeTwJY0awr<0lqJ zL4MYC-2v2hx&ydVWAZ1guYpuEI}tl;M&~8X60@N%U=|f0N*{3>Cq9;NW7BR`wK`CEHzj`+&ha4X0V+jSH zQU3g9lF*puDYr#|thF1(rDY5KjgcpG(TfAj_XW6;iTwR28H5aa$BvNj=sCD}UGHR> zX}@5*iYFZ)ck=tLln^AyFG*@Siu_>E6$l2L=E03hdf(qJaOCV2Kh7Bv2=>eYqn0N- zGy(2y(4a4H_^>9j#;0@jk6V87u8%xHD!PbATtL119T4#=FQ(jwa5^=@6y4cn+kv%VFwzMVVVzERG-F?wJ`J6|Kye1$OR! z7JxK}X9Wl>oxb^~_^NKl03|+Vw65V=+K!JnEuEW1a#5IWt(iQjKSFv-DVO83WnD-liJU6EJ)gQG=nQQS1EDsV~LXiQNVx2d*w z(=xl8GSd!CQc{O0&w&&l0|HV7kJ=Uwh3>Ai_jp;uS8{|Hyh4@4!}yG0df5C@)^PxE zk`j|AEZa_CwLr9sx|~8Gkc5`|&7m7fNhw(T`3nnmFf!*ds=nR)rbB=Q?sIqXouIXa z@O5@~PlovMw%lg~Bex3GFfENbDq#I-E&|qL|NKyVGss=IsWi)Ikh_3TO|wZ`-KgE9 z!BqqXCb7sKI5mgIoWDQcKrqskl95Uak4SNQGSiG79#y#m$YQACu-p^{KypYe0EP?} zc1Mb^LRKSk2PCsAnB8pj$IAIOOfAgL>`#4OtLCR)qf9Td(Apx+X%=GSC>v)OyIa<1 zR2`CAd;uZs>ayQtkUhnkp;Wo|5t+X;|4!`M>t53(NeIO$JuLto(X?gR%TC}*2A{MU)X_9OjeCdHL27NeGCFo=ncWg z70Se_st_V6bB_88BlVe8{>my)$7?2VK^6yc&B;K`qnR-UrBRaxI@hZ?B6|I{2xI^S z8+upBXO~|5^RHLhp4ubPK89(Z6R$}c$@v7FY?AMBPTm=M9BpaZr7}am(F0{-u;?rsN=~AB2=&36 zSTwXIoz~D!X)KNVVdo_DAGLu&cs|f#^m2D-;&;FIfa%l{1gF7Ux~@(ku`t&jsystO zL+AiZ+^Nn#p>Z*BqJ2q|PNT}=*@=5W&@+CdWI?y7f?SkOJpY(Iyiqf1(`F9qI~|8W zxFt)w9J}>rT3vCFB6Q~OoRHNp;W|Ac>nhY~efH={70AldK`yg@t8Kp#QpP|M3M?h* z>09m4KW};gMRz}Iofs%;crLRXAi+jIekrgd?uiff0fR}fu{-$QT5_v$J22SlyQ%}* zLko`?&v8qd7G1k`4LHf${bjPd-<#$8%G1u(Z;BKI_3eT@?c#zw`{@|k&;LQ?r>5w> zPtvAc2Xb8$U_UAaSwh(x9=VovwfD$o507c~-Ym1~AmI}~LL)JpFCdfG3Yq1H7Zi%; z)zpnhcfONje^5;Gb-U=&5R(m(TARh9Er1y@YaX7DaN+ss+SthJ(&6dhG*OxJSyh}H z4hq7rxib`g?2LUjx5U_%SM?)XW6;2sT-SA@Gx^ozg|g=t_QYI>eTfE zhBTT&+hJ?qSf(ybk(mU|;^KD9K4mTNHyHJ`oCi@}K!k{{wNWHMP_t<|2CedI6$)O= zLG}$OI;MZR`|Sl8K*KWtO9(t9Q`s^E22_0&B3&(Dk9Y{5Y!~GQJvKjoxTwY1$*Fl! z(4hvz$8X*QSq)7lfQwbkc*OM=jnazcEOfJ%@vbEy#G@%>*KHfW(?~{K7pYw%$Sv*c z3%}Q9#@#>$o@3=d@<8!k$AY#=E*KX1XfzDI&AyNFI<=q=!BwdW(E$;EQZb4L12oTl zl&<=Ap#2BADr{dDZVTDZJ9Av=)UVRd1%+6Ctdvx- zJCzgyDI)P^NLd+Rv14&m-mikXUl^0KHcJ2q;S+($C3udTk`}+_ka^a|EkG1`3aeG} z&Ti3a&NIVhrjIANdNZ4#sHps-9F2HiG;i&dPbM=V@{D~!Qt=FwT9S5EA^?1i`#BIb zA#{cl@FM*#%{fbO2+1+(;o7=7ZDP3>=<}UG)GDy#`aD>@X%i-jF0Lbo^bZC zK!1V+_t~?QA#!RwkkaXDJPS4x{Q&)d?n(&$1ilW}5Y3JA8CS0alXu3_7cY4Oi zt`5O~K=t&Tm6DOENesZ$i>3qWo37hb@_U@2cCr4Q!mpB?mbdQt#^si(Yu3NsJO+n! zUkvdZ2J#iUwA8?=&ALixOW|!KC;l)KQDBCl`yEM{pwDB!h&C8%K(!V@lSYo#ilp52 zMx!oMQ$z`bN3PfmKL4nn2r?oYtsGt!NBRZ>$R>m6Rr}unF33AIRK`t6Q9ZIgpZdP@ z6V#<)fbF}~P;o|jJ`V7MYrGTY8}|Fq4JsD14^~%=LvMOr*YGSTj#)20%1c;RrPK;q z1J8KhCMc3lZs^S9?vD>MGv$2)wfCkP|3;%& zIf=*1vxF*aC>Yket~fsI+)YrK?)S*mQ6RG0Z~IC+YTza3p)ead{}-*X?qqe`WXMf> zN%LIxbt=*cO8I1MHKxvVANb3q5aE-5b-mloRRrz9C#AiU>^Fy6klAE5?=yKNsql5bDU%7=v3zDyE|7hOqssmGrZZ*KQ?je;Eg zgc_DrfyjqcaRB%IouyVF1%b+Xs)D(n(cA2B`z-%5PJHyCPcUeqPpWgaH9w`h+qB%3 zI&)@U1dF-RrCZ5WS7MUlk0NIX>5N@-x$D;LJ}17+%YkPE+U#EO_{b@E^kl2GD9Q=e zwIPn14B$*VrM4Zia>{`#Ex}>q(k50*Wy!_ve`Sa=#eukLWZx?`85$3Vs2X?y(#f=; zP#x&zus;RPV(lrkm)xJ6vi4=%;oX;kzRcCVuSd1Ohqo*C&y^PzR@o}YxCqwF+G;ZH zZ--{aBNkBz?85q4df?(j?o+_SB<2`<2$|MB zq51#r35Aus2uP&h+&dYOQ4g5APO$6dP)WGDpPPKh|7jZ_2z78+fH11^l21Y4OKBvo zDT{Wq8D+P6xb*4kwNoc`w9I-xNSS>c1Z!&zJlJcMsSe;^W{_Y55=1%8?*=_Ml6QBx zmZ}~W_SOQQhm)Y=M;Gvvte!m1bzlVdjK5CbfV9MW^4=a9CMb+vt*dk#qwUH+oMZHE zu9^thLs7@t!&;Rm)MXb+O%Brh zITSC}LSR~6b_4fR8<2w&eKDMZz`10YArlzIV^$v-J=@Z>!_DBa&^EBo+D_BPo1xok zQ7(+-rcTsNcvFnEDlPWWS~9rho$^4lmJUu%z_gnC<4cyt?jJ808O3e4sO6mO_q6c` z0FIxlM?@eCLZa2zm1pQF;G5&ef_cN;q2a8m=fZTIG?@h8S@Q)in$F+TI&~Uii zdmHI^XV@dU;zLGKyu4Mr;>1F1(T8JYaI#xsCo!nlY)!s`ERsh!r$_+kgjzJ56oVcW z?ZAC6f!z^SK^ve}LK{FzYh;-G*hm*4EHo;!F!@U1lvXfE2E>W9NId?fF40>SG|kZ* zygeCUja(YGi2Xt^k{pZ(;RExm(%^AbJrk1{sPz)!Qer|Ojph?IS_{<6q8jpa6}D#E zy)G~x$WR3)PxbSv5% zEdPCs*k13|c=M(};`IoR*gnp5%0tdC;GRNrHjD~e<|6#|b7}%yQNH?33ER@Nck|?o z{hf8==FlklvV+<|VK62E(7*%R!JmGwT`)V&e(u+bHcg z_u^Y-%hPY-hUJW5X#53gc>^lID|}MY(i3QI&dVwWWTCC$SxoN^-o3mzu)nL~7uVt} zNYr*Upl9+53-udUXPN;%0RdfY)L;AS@?+i>Fn$^MdU3VQ_3wYL1g7L%X%Gg*Wv(|z zFH$IT_IQEzzjvjJW#&`P4;cZymj$q3{Ro2PfNvXK?j9O=!P~Xhy7}z6b+*^Z>4&td z5Ej0NaplpZC~&4yYw9wRot<5{czBMkLw=BbyV>dF*c*S`u@|+t{I9H%O4XkPq@^!` z_+w&Wj76o)8@52#u{OoygWsX;8%TnCT`Is44rZME(qK59K$T|&QIJn>tC*+z2RPyy zeJ!&J%t& z(twc?zPaSkHVIjwIX4pcRk-SvL`FDW#xJTVSjBXaN(+XQX2oU3^tX(PVNJgaCM72+ z;|~fA%|?o&Evahz9CTg;(G9*PR33-#ccIqWRCW!T|4PqXa!Rwo z^)R2DGkgmXS2gmqlIq$4>-j&w?G>%x)lp8^v$?Sywi86J?J!FbI3d_s1Xy=PvhhkG zq}(iPDfaI#|BgG=lw({!nFk!>#6WAyncG+>=)k6mcj`C-%1aOe=$YvnUmLpaAf9hn zTUU~s?4#-GHSwjg&!nM&8h;I7eIU=AI$41QKV`b2f={H3d@YIVwEt$23RBkDM@s7 zj0l#=;CkJk5&%17`r(H$FQDN3p2jzL3L>iNU$_kWg|+Yd9(oO~subgM`=P}SbjHCa zE=@A?*uU4`$_JU1x5615a2GQ(GjKIpz}%8G!Y8;^@zdw37-abeU8-IZOks~-?f02| z7rI;=y6VxF0>mG3OXrlGxKwh-&v4|dtj!lvJt!j#*+nH74$@w<0@!XctJE$kT~*%A zwak-hL{bbB9+ltk*wyq01-5|NuLWYFx23FMVpO`A7_=U1$tGUN8iAd-z^Qdl#)-Jh zmC=jO@p$dqv%SX8we{pyC$44~uf^Y31=ahINpHP1&p+TNF|IG-+v!-y4K-%hc6b^p z5S5)~z8C3bBy&tJ*bv2yN-qlQWoy}2&a6TgRVc=`2KvEZK`FSFbHm0TJ9dkHGN$MRW@??BHgY2rP5?j6N7C@A=_Qw>xFU>H5(c#y{`(2P3`dQ zS`!pZL(Jg!!Ck-^`GM=>cdl!#MtyzwM4$+78u|=WD3mSq^&GJ%^~8|UlkVSNi`kUl z7o9aN<5mmXKV(8k(M^(Pnx6ed;3N?Il2%;@!A|H_nUQ;VHf?A(Q0$cwNlygj0*h2j_I}C4Me*r#yID^-b#; zgl{wTvq`C`W?Bjfx5z{I57#<}+`cj;Zq5H0PUtF>zeZ;}8(&axo7K%WhdSG+2~4us zN>78DS~{?rJ9q9xhA7ku0c2LnT5m^1vp$$bM;%1&o@$1a7_bcH=F$D}^7f09?$!fL zky#?Fh=gj@f>QBoKIG^-me8riT%u;eorCv;avhPW3C$duQz{phd>R_M0GK`m`t?_@ z48tdnVqv|H|9GH)GB5UQFNomaHcWNR2!}Q$jlwj!pL+Iv;NU5-mq*=trmtI|t#SK6 zShtG41I_tby_5|YK9J(fi*g%fZgA?6ybp|G&GfPvNJ^k>ot9#(=VJV^=P*W*P#Om2 zXMiP0>BCu?NBt(j3w)K8j&Dowz#v8pG*rjHK?yC;YTjz`%l51)NG>nr8(r0ba2L6} zd=o)IplfsYnAip^QYyIUvev#`m8DFzIyL+zh_m<^4D>`JnGMMr>&uX$LsWaX$k6e8P=b+vK0N$T-Rf>p(7WK{8PiPQ3U~T zLx%|HvSNK=Gyg43H@6I#7vfK|mv3KptCb)3BQG%;+Osb=Ea;nn>dL^;g)^_HP z4qdl!K(JX63%a}lFQcM_Ca&Ciw=VQ|K6dh|ni|*o!rHsudCOeO+~Rn&vaB6Er6M^> zSvIQ{k{Nid`&)lQkeb9eGfD`H$D{UBr_<*w48Ap@aE#yhV_iaIz?;FBq29+@&#=P2 zAWFZI3_lNP)_;bd|FWoP+yZV>!Q_y=zd!c6pFB&&Exx1}J)JAQrDuDfYYZ!j@8{lL zK|@;({ynq>)WYoY+zD*1rGc%?;;AVY<;&QYe7ZSChRjhNEX?93?f)P2M5p2Z_rCuj>weYe X)y|l6Z&EXv=(1oH)h=eAzwY~Q$Cv~8 literal 0 HcmV?d00001 From 550ea4abe505d0e32af8f56bd6557bc0851a72b9 Mon Sep 17 00:00:00 2001 From: reSSSno <46084217+reSSSno@users.noreply.github.com> Date: Sat, 23 May 2026 20:27:54 +0300 Subject: [PATCH 56/56] Update and rename ci.yml to ci-serovaa.yml --- .github/workflows/{ci.yml => ci-serovaa.yml} | 37 ++++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) rename .github/workflows/{ci.yml => ci-serovaa.yml} (56%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-serovaa.yml similarity index 56% rename from .github/workflows/ci.yml rename to .github/workflows/ci-serovaa.yml index 80a5b67..55a2c08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci-serovaa.yml @@ -1,8 +1,6 @@ -name: CI Pipeline +name: CI - SerovAA on: - push: - branches: [ main, master ] pull_request: branches: [ main, master ] @@ -12,59 +10,44 @@ jobs: services: redis: image: redis:alpine - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + ports: [6379:6379] + options: --health-cmd "redis-cli ping" --health-interval 10s steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' - - name: Install dependencies + - name: Install backend dependencies working-directory: SerovAA/backend run: pip install -r requirements.txt - name: Install pytest run: pip install pytest - name: Run backend tests working-directory: SerovAA - run: | - # Ждём Redis (хотя healthcheck уже есть, на всякий случай) - sleep 2 - PYTHONPATH=. python -m pytest tests/test_backend.py -v --tb=short + run: PYTHONPATH=. python -m pytest tests/test_backend.py -v env: - REDIS_HOST: localhost # чтобы backend точно знал, где Redis + REDIS_HOST: localhost test-worker: runs-on: ubuntu-latest services: redis: image: redis:alpine - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + ports: [6379:6379] + options: --health-cmd "redis-cli ping" --health-interval 10s steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' - - name: Install dependencies + - name: Install worker dependencies working-directory: SerovAA/worker run: pip install -r requirements.txt - name: Install pytest run: pip install pytest - name: Run worker tests working-directory: SerovAA - run: | - sleep 2 - PYTHONPATH=. python -m pytest tests/test_worker.py -v --tb=short + run: PYTHONPATH=. python -m pytest tests/test_worker.py -v env: REDIS_HOST: localhost