From 6ec01760eb2d3566d9b8b6cbbd125b7c63bc67a2 Mon Sep 17 00:00:00 2001 From: Ben Miller Date: Tue, 12 May 2026 18:58:18 -0500 Subject: [PATCH] intial commit --- .gitignore | 213 ++++++ GEMINI.md | 40 ++ Procfile | 1 + README.md | 101 +++ app.py | 34 + blueprints/__init__.py | 13 + blueprints/admin.py | 126 ++++ blueprints/api.py | 391 +++++++++++ blueprints/auth.py | 72 ++ blueprints/search.py | 79 +++ blueprints/static_routes.py | 11 + config.py | 9 + extensions.py | 5 + gunicorn_config.py | 2 + models/banned_ip.py | 7 + models/collaborator.py | 25 + models/favorite.py | 10 + models/note.py | 22 + models/notepad.py | 21 + models/user.py | 29 + notes/birding.csv | 51 ++ notes/conspiracy_locations.csv | 51 ++ notes/general_public.csv | 101 +++ notes/haunted-oklahoma.csv | 51 ++ notes/haunted-usa.csv | 51 ++ notes/route66.csv | 51 ++ requirements.txt | 6 + seed_notes.py | 80 +++ static/about.html | 88 +++ static/admin.html | 48 ++ static/assets/css/admin.css | 102 +++ static/assets/css/auth.css | 37 + static/assets/css/base.css | 40 ++ static/assets/css/map.css | 99 +++ static/assets/css/modals.css | 33 + static/assets/css/navbar.css | 94 +++ static/assets/css/sidebar.css | 167 +++++ static/assets/css/styles.css | 339 +++++++++ static/assets/images/spotnotes.png | Bin 0 -> 208861 bytes static/assets/js/actions.js | 120 ++++ static/assets/js/admin.js | 257 +++++++ static/assets/js/auth.js | 59 ++ static/assets/js/index.js | 1024 ++++++++++++++++++++++++++++ static/assets/js/nav.js | 42 ++ static/assets/js/search.js | 59 ++ static/contact.html | 38 ++ static/favicon.ico | Bin 0 -> 3692 bytes static/index.html | 185 +++++ static/login.html | 47 ++ static/register.html | 55 ++ 50 files changed, 4586 insertions(+) create mode 100644 .gitignore create mode 100644 GEMINI.md create mode 100644 Procfile create mode 100644 README.md create mode 100644 app.py create mode 100644 blueprints/__init__.py create mode 100644 blueprints/admin.py create mode 100644 blueprints/api.py create mode 100644 blueprints/auth.py create mode 100644 blueprints/search.py create mode 100644 blueprints/static_routes.py create mode 100644 config.py create mode 100644 extensions.py create mode 100644 gunicorn_config.py create mode 100644 models/banned_ip.py create mode 100644 models/collaborator.py create mode 100644 models/favorite.py create mode 100644 models/note.py create mode 100644 models/notepad.py create mode 100644 models/user.py create mode 100644 notes/birding.csv create mode 100644 notes/conspiracy_locations.csv create mode 100644 notes/general_public.csv create mode 100644 notes/haunted-oklahoma.csv create mode 100644 notes/haunted-usa.csv create mode 100644 notes/route66.csv create mode 100644 requirements.txt create mode 100644 seed_notes.py create mode 100644 static/about.html create mode 100644 static/admin.html create mode 100644 static/assets/css/admin.css create mode 100644 static/assets/css/auth.css create mode 100644 static/assets/css/base.css create mode 100644 static/assets/css/map.css create mode 100644 static/assets/css/modals.css create mode 100644 static/assets/css/navbar.css create mode 100644 static/assets/css/sidebar.css create mode 100644 static/assets/css/styles.css create mode 100644 static/assets/images/spotnotes.png create mode 100644 static/assets/js/actions.js create mode 100644 static/assets/js/admin.js create mode 100644 static/assets/js/auth.js create mode 100644 static/assets/js/index.js create mode 100644 static/assets/js/nav.js create mode 100644 static/assets/js/search.js create mode 100644 static/contact.html create mode 100644 static/favicon.ico create mode 100644 static/index.html create mode 100644 static/login.html create mode 100644 static/register.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..559f344 --- /dev/null +++ b/.gitignore @@ -0,0 +1,213 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Database Files +*.sqlite3 +*.sqlitedb +*.db +*.db-journal + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock +#poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +#pdm.lock +#pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +#pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Cursor +# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to +# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data +# refer to https://docs.cursor.com/context/ignore-files +.cursorignore +.cursorindexingignore + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..f827b5f --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,40 @@ +# SpotNotes Future Implementation & Refactoring Plan + +## 1. Refactoring `index.js` (Reducing Complexity) +- **Status:** **[To Do]** +- **Action Plan:** + - `index.js` is currently a monolithic file (~1000 lines) handling global state, Leaflet map initialization, sidebar DOM manipulation, and raw API calls simultaneously. + - **Extract Map Logic:** Create `static/assets/js/map.js` to encapsulate `initMap`, `renderMapMarkers`, geolocation tracking, and all Leaflet-specific code. + - **Extract UI/Sidebar Logic:** Create `static/assets/js/sidebar.js` to handle `initSidebar`, `renderNotepadList`, HTML generation for note list items, and DOM toggling. + - **Extract API & State Logic:** Keep the core data fetching (`loadNotepads`, `loadNotesForPad`, `loadAllMyNotes`) in `index.js` (or a dedicated `data.js`) to act as the central controller. + - **Namespace Globals:** Group global variables (`activeNotes`, `activePadId`, `currentUser`, `map`, etc.) into a single `window.SpotNotes` state object to prevent scope pollution and make dependencies explicitly clear across the new script files. + +## 2. Feature: "Get Directions" Button +- **Status:** **[To Do]** +- **Action Plan:** + - **Low-Hanging Fruit:** Add a quick "Directions" or "Navigate" link/button to the map marker popups and sidebar note items. + - Clicking the button will easily open a new tab mapping directly to the note's coordinates: `https://www.google.com/maps/dir/?api=1&destination={lat},{lng}`. + - Extremely useful UX for a location-based app, requiring absolutely zero backend changes. + +## 3. Feature: Map Marker Clustering +- **Status:** **[To Do]** +- **Action Plan:** + - **Low-Hanging Fruit:** Integrate the official `Leaflet.markercluster` plugin. + - Currently, viewing an "All My Notes" view with hundreds of notes in the same city creates a messy, overlapping visual experience and impacts browser performance. + - Clustering groups nearby markers into a single circle with a count, automatically expanding when the user clicks or zooms in. + - Implementation requires just adding the CDN links to `index.html` and wrapping the markers in a `L.markerClusterGroup()` inside the `renderMapMarkers` loop. + +## 4. Feature: Sort & Filter Active Notes +- **Status:** **[To Do]** +- **Action Plan:** + - **Low-Hanging Fruit:** Add a simple, fast text input filter floating above the note list in the sidebar whenever a notepad is actively viewed. + - Allows users to instantly search for a specific note's title or content within a massive notepad *without* triggering a slow, global backend search. + - Implementation is 100% frontend logic: listening to the input's `keyup` event and filtering the existing `activeNotes` array before re-rendering the sidebar list. + +## 5. Feature: Custom Marker Colors per Notepad +- **Status:** **[To Do]** +- **Action Plan:** + - Update the `Notepad` database model to include an optional `color` field (defaulting to the standard Leaflet blue). + - Add a simple HTML `` selector to the Create/Edit Notepad modals. + - Update the Leaflet marker icon logic to apply a CSS tint/filter (or use customized SVG icons) matching the notepad's selected color. + - This allows users to visually distinguish between different notes (e.g., "Restaurants" vs "Birding Spots") instantly when looking at the map in mixed views like "All My Notes". diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..4d84b03 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn --worker-tmp-dir /dev/shm --config gunicorn_config.py "app:create_app()" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..256365e --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# SpotNotes + +SpotNotes is a location-based note-taking web application. It allows users to drop notes on an interactive map, organize them into notepads, and optionally share them with the public or specific users. + +## Features + +- **Interactive Map:** View and create notes on a map powered by Leaflet and OpenStreetMap. +- **Location-Based Notes:** Every note is tied to specific geographic coordinates. +- **Notepads:** Organize notes into collections called "Notepads". +- **Privacy & Sharing:** Notepads can be private (only you), public (everyone), or shared via link tokens. +- **User Authentication:** Secure registration and login system. +- **Favorites:** Save and easily access your favorite public notepads. +- **Search & Geocoding:** Search through your notes or use geocoding to find locations worldwide. +- **Admin Dashboard:** Manage users, notepads, and notes. + +## Tech Stack + +- **Backend:** Python, Flask, Flask-SQLAlchemy (with SQLite for development/PostgreSQL for production). +- **Frontend:** HTML5, CSS3 (Vanilla), Vanilla JavaScript, Leaflet.js for maps. +- **Deployment:** Configured for Gunicorn and standard WSGI environments (includes `Procfile` and `gunicorn_config.py`). + +## Project Structure + +``` +spotnotes.app/ +│ +├── app.py # Main application entry point +├── config.py # Configuration settings +├── extensions.py # Flask extensions (SQLAlchemy, CORS) +├── requirements.txt # Python dependencies +│ +├── blueprints/ # Flask Blueprints (Controllers) +│ ├── admin.py # Admin dashboard routes +│ ├── api.py # Main REST API for notes/notepads +│ ├── auth.py # User authentication routes +│ ├── search.py # Search and geocoding logic +│ └── static_routes.py # Serving static HTML pages +│ +├── models/ # SQLAlchemy Database Models +│ ├── banned_ip.py # Security model for IP bans +│ ├── favorite.py # User's favorited notepads +│ ├── note.py # Core note data structure +│ ├── notepad.py # Collections of notes +│ └── user.py # User account data +│ +└── static/ # Frontend Assets + ├── index.html # Main map interface + ├── login.html # Login page + ├── register.html # Registration page + ├── admin.html # Admin interface + └── assets/ + ├── css/ # Modular stylesheets + ├── js/ # Modular vanilla JS scripts + └── images/ # Images and icons +``` + +## Getting Started + +### Prerequisites + +- Python 3.8+ +- pip (Python package installer) + +### Installation + +1. **Clone the repository** (or download the source): + ```bash + git clone + cd spotnotes.app + ``` + +2. **Create a Virtual Environment (Optional but recommended):** + ```bash + python -m venv venv + source venv/bin/activate # On Windows use: venv\Scripts\activate + ``` + +3. **Install Dependencies:** + ```bash + pip install -r requirements.txt + ``` + +4. **Run the Application:** + ```bash + python app.py + ``` + The app will start on `http://127.0.0.1:5000/`. The database (`spotnotes.db`) will be created automatically upon the first run. + +## Planned Features (Roadmap) + +As detailed in the `GEMINI.md` file, the following features are actively planned or in development: + +1. **Advanced Collaboration:** Share notepads with specific users granting explicit Read or Read/Write permissions. +2. **Content Editing:** Ability to edit existing notes and notepads. +3. **Rich Text & Multiline Notes:** Support for multiline text and bulleted lists. +4. **CSV Export:** Export all notes within a notepad to a `.csv` file. +5. **Location-Based Alerts:** Browser notifications when physically approaching a saved note. + +## License + +All rights reserved. diff --git a/app.py b/app.py new file mode 100644 index 0000000..08536d3 --- /dev/null +++ b/app.py @@ -0,0 +1,34 @@ +from flask import Flask +from werkzeug.middleware.proxy_fix import ProxyFix +from config import Config +from extensions import CORS, db +from blueprints import register_blueprints + +app = Flask(__name__, static_folder='static') +app.config.from_object(Config) + +# Fix for Nginx proxying (ensures correct IP addresses) +app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1) + +CORS(app) +db.init_app(app) +register_blueprints(app) + +with app.app_context(): + from models.user import User + from models.notepad import Notepad + from models.favorite import Favorite + from models.note import Note + from models.banned_ip import BannedIP + from models.collaborator import Collaborator + + db.create_all() + + # Create default Global Public Notepad if it doesn't exist + if not Notepad.query.filter_by(name="Global Public Notes").first(): + global_pad = Notepad(name="Global Public Notes", is_public=True) + db.session.add(global_pad) + db.session.commit() + +if __name__ == "__main__": + app.run(debug=True) diff --git a/blueprints/__init__.py b/blueprints/__init__.py new file mode 100644 index 0000000..b62815e --- /dev/null +++ b/blueprints/__init__.py @@ -0,0 +1,13 @@ +from flask import Flask +from .api import api_bp +from .static_routes import static_bp +from .auth import auth_bp +from .admin import admin_bp +from .search import search_bp + +def register_blueprints(app: Flask): + app.register_blueprint(api_bp) + app.register_blueprint(static_bp) + app.register_blueprint(auth_bp) + app.register_blueprint(admin_bp) + app.register_blueprint(search_bp) \ No newline at end of file diff --git a/blueprints/admin.py b/blueprints/admin.py new file mode 100644 index 0000000..7d73794 --- /dev/null +++ b/blueprints/admin.py @@ -0,0 +1,126 @@ +from flask import Blueprint, jsonify, session +from models.user import User +from models.notepad import Notepad +from models.note import Note +from models.banned_ip import BannedIP +from extensions import db + +admin_bp = Blueprint('admin', __name__, url_prefix='/admin') + +def check_admin(): + user_id = session.get('user_id') + if not user_id: + return False + + user = User.query.get(user_id) + return user and user.is_admin + +@admin_bp.before_request +def before_request(): + if not check_admin(): + return jsonify({'error': 'Unauthorized'}), 403 + +@admin_bp.route('/stats', methods=['GET']) +def get_stats(): + return jsonify({ + 'user_count': User.query.count(), + 'notepad_count': Notepad.query.count(), + 'note_count': Note.query.count() + }) + +@admin_bp.route('/users', methods=['GET']) +def get_users(): + users = User.query.all() + user_list = [user.to_dict() for user in users] + + # Add "Unowned" virtual user for managing public/unowned pads + unowned_count = Notepad.query.filter_by(user_id=None).count() + if unowned_count > 0: + user_list.insert(0, { + 'id': 0, + 'email': 'Unowned / Public Notepads', + 'first_name': 'System', + 'last_name': '', + 'last_ip': None, + 'is_admin': False, + 'is_banned': False + }) + + return jsonify(user_list) + +@admin_bp.route('/users//notepads', methods=['GET']) +def get_user_notepads(user_id): + # Handle virtual user ID 0 for unowned notepads + query_id = None if user_id == 0 else user_id + notepads = Notepad.query.filter_by(user_id=query_id).all() + return jsonify([notepad.to_dict() for notepad in notepads]) + +@admin_bp.route('/notepads//notes', methods=['GET']) +def get_notepad_notes(notepad_id): + notepad = Notepad.query.get_or_404(notepad_id) + notes = notepad.notes.all() + return jsonify([note.to_dict() for note in notes]) + +@admin_bp.route('/notes/', methods=['DELETE']) +def delete_note(note_id): + note = Note.query.get_or_404(note_id) + db.session.delete(note) + db.session.commit() + return jsonify({'message': 'Note deleted'}), 200 + +@admin_bp.route('/notepads/', methods=['DELETE']) +def delete_notepad(notepad_id): + notepad = Notepad.query.get_or_404(notepad_id) + # Clean up notes first to prevent FK errors if cascade is missing + for note in notepad.notes: + db.session.delete(note) + from models.favorite import Favorite + Favorite.query.filter_by(notepad_id=notepad.id).delete() + db.session.delete(notepad) + db.session.commit() + return jsonify({'message': 'Notepad deleted'}), 200 + +@admin_bp.route('/users/', methods=['DELETE']) +def delete_user(user_id): + user = User.query.get_or_404(user_id) + + # Clean up user's notepads and notes + notepads = Notepad.query.filter_by(user_id=user.id).all() + from models.favorite import Favorite + for notepad in notepads: + for note in notepad.notes: + db.session.delete(note) + Favorite.query.filter_by(notepad_id=notepad.id).delete() + db.session.delete(notepad) + + Favorite.query.filter_by(user_id=user.id).delete() + db.session.delete(user) + db.session.commit() + return jsonify({'message': 'User deleted'}), 200 + +@admin_bp.route('/users//ban', methods=['POST']) +def ban_user(user_id): + user = User.query.get_or_404(user_id) + user.is_banned = True + db.session.commit() + return jsonify({'message': 'User banned'}), 200 + +@admin_bp.route('/users//unban', methods=['POST']) +def unban_user(user_id): + user = User.query.get_or_404(user_id) + user.is_banned = False + db.session.commit() + return jsonify({'message': 'User unbanned'}), 200 + +@admin_bp.route('/users//ban_ip', methods=['POST']) +def ban_user_ip(user_id): + user = User.query.get_or_404(user_id) + if not user.last_ip: + return jsonify({'error': 'User has no recorded IP'}), 400 + + if not BannedIP.query.filter_by(ip_address=user.last_ip).first(): + banned = BannedIP(ip_address=user.last_ip) + db.session.add(banned) + db.session.commit() + + return jsonify({'message': f'IP {user.last_ip} banned'}), 200 \ No newline at end of file diff --git a/blueprints/api.py b/blueprints/api.py new file mode 100644 index 0000000..f1c6421 --- /dev/null +++ b/blueprints/api.py @@ -0,0 +1,391 @@ +from flask import Blueprint, jsonify, request, session, current_app, Response +from extensions import db +from itsdangerous import URLSafeSerializer +from models.notepad import Notepad +from models.note import Note +from models.collaborator import Collaborator +from models.user import User +from models.favorite import Favorite +import csv +from io import StringIO + +api_bp = Blueprint('api', __name__, url_prefix='/api') + +def get_share_token(item_type, item_id): + s = URLSafeSerializer(current_app.config['SECRET_KEY'], salt='share-link') + return s.dumps({'type': item_type, 'id': item_id}) + +def validate_share_token(token, item_type, item_id): + s = URLSafeSerializer(current_app.config['SECRET_KEY'], salt='share-link') + try: + data = s.loads(token) + return data.get('type') == item_type and data.get('id') == item_id + except: + return False + +def check_pad_read_permission(notepad, user_id, token=None): + is_shared_by_link = token and validate_share_token(token, 'notepad', notepad.id) + if notepad.is_public or is_shared_by_link: + return True + if not user_id: + return False + if notepad.user_id == user_id: + return True + # Check for collaborator (any permission level grants read) + if Collaborator.query.filter_by(user_id=user_id, notepad_id=notepad.id).first(): + return True + return False + +def check_pad_write_permission(notepad, user_id): + if not user_id: + return False + if notepad.user_id == user_id: + return True + # Check for collaborator with 'write' permission + collab = Collaborator.query.filter_by(user_id=user_id, notepad_id=notepad.id, permission='write').first() + return collab is not None + +@api_bp.route('/notepads', methods=['GET']) +def get_notepads(): + user_id = session.get('user_id') + filter_type = request.args.get('type') + + query = Notepad.query + + if filter_type == 'favorites': + query = Notepad.query.join(Favorite).filter(Favorite.user_id == user_id) if user_id else Notepad.query.filter_by(id=-1) + elif filter_type == 'mine': + query = query.filter_by(user_id=user_id) if user_id else Notepad.query.filter_by(id=-1) + elif filter_type == 'shared': + query = Notepad.query.join(Collaborator).filter(Collaborator.user_id == user_id) if user_id else Notepad.query.filter_by(id=-1) + elif filter_type == 'public': + query = query.filter_by(is_public=True) + else: + # Default behavior (union) if no type specified + if user_id: + query = query.filter((Notepad.is_public == True) | (Notepad.user_id == user_id)) + else: + query = query.filter_by(is_public=True) + + pads = query.order_by(Notepad.name).all() + results = [] + for pad in pads: + p_dict = pad.to_dict() + if user_id: + if pad.user_id == user_id: + p_dict['share_token'] = get_share_token('notepad', pad.id) + p_dict['can_write'] = check_pad_write_permission(pad, user_id) + else: + p_dict['can_write'] = False + results.append(p_dict) + return jsonify(results) + +@api_bp.route('/notepads/', methods=['GET']) +def get_notepad(pad_id): + notepad = Notepad.query.get_or_404(pad_id) + user_id = session.get('user_id') + + token = request.args.get('token') + + if not check_pad_read_permission(notepad, user_id, token): + return jsonify({'error': 'Unauthorized'}), 403 + + p_dict = notepad.to_dict() + p_dict['can_write'] = check_pad_write_permission(notepad, user_id) + if user_id and notepad.user_id == user_id: + p_dict['share_token'] = get_share_token('notepad', pad_id) + return jsonify(p_dict) + +@api_bp.route('/notepads', methods=['POST']) +def create_notepad(): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + data = request.get_json() + new_pad = Notepad(name=data['name'], is_public=data.get('is_public', False), user_id=user_id) + db.session.add(new_pad) + db.session.commit() + return jsonify(new_pad.to_dict()), 201 + +@api_bp.route('/notepads//notes', methods=['GET']) +def get_notes(pad_id): + notepad = Notepad.query.get_or_404(pad_id) + user_id = session.get('user_id') + + token = request.args.get('token') + + if not check_pad_read_permission(notepad, user_id, token): + return jsonify({'error': 'Unauthorized'}), 403 + + notes = notepad.notes.filter_by(is_hidden=False).all() + results = [] + for note in notes: + n_dict = note.to_dict() + if user_id and notepad.user_id == user_id: + n_dict['share_token'] = get_share_token('note', note.id) + results.append(n_dict) + return jsonify(results) + +@api_bp.route('/notes/', methods=['GET']) +def get_note(note_id): + note = Note.query.get_or_404(note_id) + notepad = Notepad.query.get(note.notepad_id) + + user_id = session.get('user_id') + + token = request.args.get('token') + is_shared = token and validate_share_token(token, 'note', note_id) + + if not notepad.is_public and (not user_id or notepad.user_id != user_id) and not is_shared: + return jsonify({'error': 'Unauthorized'}), 403 + + n_dict = note.to_dict() + n_dict['can_write'] = check_pad_write_permission(notepad, user_id) + + pad_dict = notepad.to_dict() + # Redact name if private and not owner + if not notepad.is_public and (not user_id or notepad.user_id != user_id): + pad_dict['name'] = "Private Notepad" + + n_dict['notepad'] = pad_dict + n_dict['owner_id'] = notepad.user_id + n_dict['is_public'] = notepad.is_public + + if user_id and notepad.user_id == user_id: + n_dict['share_token'] = get_share_token('note', note_id) + + return jsonify(n_dict) + +@api_bp.route('/notes/mine', methods=['GET']) +def get_my_all_notes(): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + notes = Note.query.join(Notepad).filter(Notepad.user_id == user_id, Note.is_hidden == False).all() + results = [] + for note in notes: + n_dict = note.to_dict() + n_dict['notepad'] = note.notepad.to_dict() + n_dict['owner_id'] = user_id + n_dict['is_public'] = note.notepad.is_public + n_dict['share_token'] = get_share_token('note', note.id) + results.append(n_dict) + return jsonify(results) + +@api_bp.route('/notes', methods=['POST']) +def create_note(): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + data = request.get_json() + notepad_id = data.get('notepad_id') + if not notepad_id: + return jsonify({'error': 'notepad_id is required'}), 400 + + notepad = Notepad.query.get_or_404(notepad_id) + + if not check_pad_write_permission(notepad, user_id): + return jsonify({'error': 'Forbidden'}), 403 + + new_note = Note( + title=data.get('title', 'Untitled'), + content=data['content'], + lat=data['lat'], + lng=data['lng'], + notepad_id=notepad_id + ) + db.session.add(new_note) + db.session.commit() + return jsonify(new_note.to_dict()), 201 + +@api_bp.route('/notes/', methods=['PUT']) +def update_note(note_id): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + note = Note.query.get_or_404(note_id) + notepad = Notepad.query.get(note.notepad_id) + if not check_pad_write_permission(notepad, user_id): + return jsonify({'error': 'Forbidden'}), 403 + data = request.get_json() + note.title = data.get('title', note.title) + note.content = data.get('content', note.content) + db.session.commit() + return jsonify(note.to_dict()) + +@api_bp.route('/notepads/', methods=['PUT']) +def update_notepad(pad_id): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + notepad = Notepad.query.get_or_404(pad_id) + # Only owner can edit notepad metadata + if notepad.user_id != user_id: + return jsonify({'error': 'Forbidden'}), 403 + + data = request.get_json() + notepad.name = data.get('name', notepad.name) + notepad.is_public = data.get('is_public', notepad.is_public) + db.session.commit() + return jsonify(notepad.to_dict()) + +@api_bp.route('/notes//report', methods=['POST']) +def report_note(note_id): + note = Note.query.get_or_404(note_id) + if not note.notepad.is_public: + return jsonify({'error': 'Can only report public notes'}), 400 + note.is_hidden = True + db.session.commit() + return jsonify({'message': 'Note reported'}), 200 + +@api_bp.route('/notepads//favorite', methods=['POST']) +def favorite_notepad(pad_id): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + existing_favorite = Favorite.query.filter_by(user_id=user_id, notepad_id=pad_id).first() + if existing_favorite: + return jsonify({'message': 'Notepad already favorited'}), 200 + + new_favorite = Favorite(user_id=user_id, notepad_id=pad_id) + db.session.add(new_favorite) + db.session.commit() + return jsonify({'message': 'Notepad favorited'}), 201 + +@api_bp.route('/notepads//unfavorite', methods=['POST']) +def unfavorite_notepad(pad_id): + user_id = session.get('user_id') + favorite = Favorite.query.filter_by(user_id=user_id, notepad_id=pad_id).first() + if favorite: + db.session.delete(favorite) + db.session.commit() + return jsonify({'message': 'Notepad unfavorited'}), 200 + +@api_bp.route('/notepads//collaborators', methods=['GET']) +def get_collaborators(pad_id): + user_id = session.get('user_id') + notepad = Notepad.query.get_or_404(pad_id) + + # Only owner can see collaborators + if notepad.user_id != user_id: + return jsonify({'error': 'Forbidden'}), 403 + + collaborators = Collaborator.query.join(User).filter(Collaborator.notepad_id == pad_id).all() + + results = [] + for collab in collaborators: + results.append({ + 'user_id': collab.user.id, + 'email': collab.user.email, + 'permission': collab.permission + }) + return jsonify(results) + +@api_bp.route('/notepads//collaborators', methods=['POST']) +def add_collaborator(pad_id): + user_id = session.get('user_id') + notepad = Notepad.query.get_or_404(pad_id) + + if notepad.user_id != user_id: + return jsonify({'error': 'Forbidden'}), 403 + + data = request.get_json() + email = data.get('email') + permission = data.get('permission') + + if not email or not permission or permission not in ['read', 'write']: + return jsonify({'error': 'Email and permission (read/write) are required'}), 400 + + collaborator_user = User.query.filter_by(email=email).first() + if not collaborator_user: + return jsonify({'error': 'User not found'}), 404 + + if collaborator_user.id == user_id: + return jsonify({'error': 'Cannot add yourself as a collaborator'}), 400 + + existing_collab = Collaborator.query.filter_by(notepad_id=pad_id, user_id=collaborator_user.id).first() + if existing_collab: + existing_collab.permission = permission + else: + new_collab = Collaborator(notepad_id=pad_id, user_id=collaborator_user.id, permission=permission) + db.session.add(new_collab) + + db.session.commit() + return jsonify({'message': 'Collaborator added/updated successfully'}), 200 + +@api_bp.route('/notepads//collaborators/', methods=['DELETE']) +def remove_collaborator(pad_id, collaborator_user_id): + user_id = session.get('user_id') + notepad = Notepad.query.get_or_404(pad_id) + + if notepad.user_id != user_id: + return jsonify({'error': 'Forbidden'}), 403 + + collab_to_remove = Collaborator.query.filter_by(notepad_id=pad_id, user_id=collaborator_user_id).first() + if not collab_to_remove: + return jsonify({'error': 'Collaborator not found'}), 404 + + db.session.delete(collab_to_remove) + db.session.commit() + return jsonify({'message': 'Collaborator removed'}), 200 + +@api_bp.route('/notepads//export', methods=['GET']) +def export_notepad(pad_id): + notepad = Notepad.query.get_or_404(pad_id) + user_id = session.get('user_id') + + token = request.args.get('token') + if not check_pad_read_permission(notepad, user_id, token): + return jsonify({'error': 'Unauthorized'}), 403 + + si = StringIO() + cw = csv.writer(si) + cw.writerow(['Note ID', 'Title', 'Content', 'Latitude', 'Longitude', 'Created At']) + + for note in notepad.notes.filter_by(is_hidden=False): + cw.writerow([note.id, note.title, note.content, note.lat, note.lng, note.created_at]) + + output = si.getvalue() + return Response( + output, + mimetype="text/csv", + headers={"Content-Disposition": f"attachment;filename=notepad_{pad_id}_export.csv"} + ) + +@api_bp.route('/notepads/', methods=['DELETE']) +def delete_notepad(pad_id): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + notepad = Notepad.query.get_or_404(pad_id) + if notepad.user_id != user_id: + return jsonify({'error': 'Forbidden'}), 403 + + for note in notepad.notes: + db.session.delete(note) + Favorite.query.filter_by(notepad_id=notepad.id).delete() + db.session.delete(notepad) + db.session.commit() + return jsonify({'message': 'Notepad deleted'}), 200 + +@api_bp.route('/notes/', methods=['DELETE']) +def delete_note(note_id): + user_id = session.get('user_id') + if not user_id: + return jsonify({'error': 'Unauthorized'}), 401 + + note = Note.query.get_or_404(note_id) + notepad = Notepad.query.get(note.notepad_id) + + if not check_pad_write_permission(notepad, user_id): + return jsonify({'error': 'Forbidden'}), 403 + + db.session.delete(note) + db.session.commit() + return jsonify({'message': 'Note deleted'}), 200 \ No newline at end of file diff --git a/blueprints/auth.py b/blueprints/auth.py new file mode 100644 index 0000000..2711281 --- /dev/null +++ b/blueprints/auth.py @@ -0,0 +1,72 @@ +from flask import Blueprint, request, jsonify, session +from extensions import db +from models.user import User +from models.banned_ip import BannedIP + +auth_bp = Blueprint('auth', __name__, url_prefix='/auth') + +@auth_bp.route('/register', methods=['POST']) +def register(): + data = request.get_json() + email = data.get('email') + ip_address = request.remote_addr + + if BannedIP.query.filter_by(ip_address=ip_address).first(): + return jsonify({'error': 'Registration blocked from this IP address.'}), 403 + + password = data.get('password') + first_name = data.get('first_name') + last_name = data.get('last_name') + + if not email or not password or not first_name or not last_name: + return jsonify({'error': 'All fields are required'}), 400 + + if User.query.filter_by(email=email).first(): + return jsonify({'error': 'Email already exists'}), 400 + + new_user = User(email=email, first_name=first_name, last_name=last_name, last_ip=ip_address) + new_user.set_password(password) + + db.session.add(new_user) + db.session.commit() + + return jsonify({'message': 'User registered successfully'}), 201 + +@auth_bp.route('/login', methods=['POST']) +def login(): + data = request.get_json() + email = data.get('email') + password = data.get('password') + ip_address = request.remote_addr + + if BannedIP.query.filter_by(ip_address=ip_address).first(): + return jsonify({'error': 'Login blocked from this IP address.'}), 403 + + user = User.query.filter_by(email=email).first() + + if user and user.check_password(password): + if user.is_banned: + return jsonify({'error': 'This account has been banned.'}), 403 + + user.last_ip = ip_address + db.session.commit() + session['user_id'] = user.id + return jsonify({'message': 'Login successful', 'user': user.to_dict()}), 200 + + return jsonify({'error': 'Invalid username or password'}), 401 + +@auth_bp.route('/logout', methods=['POST']) +def logout(): + session.pop('user_id', None) + return jsonify({'message': 'Logged out'}), 200 + +@auth_bp.route('/me', methods=['GET']) +def get_current_user(): + user_id = session.get('user_id') + if not user_id: + return jsonify({'authenticated': False}), 200 + + user = User.query.get(user_id) + if user: + return jsonify({'authenticated': True, 'user': user.to_dict()}), 200 + return jsonify({'authenticated': False}), 200 \ No newline at end of file diff --git a/blueprints/search.py b/blueprints/search.py new file mode 100644 index 0000000..f4f54cc --- /dev/null +++ b/blueprints/search.py @@ -0,0 +1,79 @@ +from flask import Blueprint, request, jsonify, session +from sqlalchemy import or_ +from extensions import db +from models.note import Note +from models.notepad import Notepad +from models.favorite import Favorite +from .api import check_pad_write_permission +import urllib.request +import urllib.parse +import json + +search_bp = Blueprint('search', __name__) + +@search_bp.route('/api/search') +def search_notes(): + query = request.args.get('q', '') + if not query: + return jsonify([]) + + # Join Note and Notepad to filter by permissions + # Explicitly join on the foreign key to ensure correct results + sql_query = db.session.query(Note, Notepad).join(Notepad, Note.notepad_id == Notepad.id).filter( + or_( + Note.title.ilike(f'%{query}%'), + Note.content.ilike(f'%{query}%') + ) + ) + + user_id = session.get('user_id') + if user_id: + sql_query = sql_query.filter( + or_( + Notepad.is_public == True, + Notepad.user_id == user_id + ) + ) + else: + sql_query = sql_query.filter(Notepad.is_public == True) + + results = sql_query.all() + + # Get user favorites if logged in + fav_ids = set() + if user_id: + favs = Favorite.query.filter_by(user_id=user_id).all() + fav_ids = {f.notepad_id for f in favs} + + # Construct response with extra info for frontend (owner_id, is_public) + output = [] + for note, pad in results: + n_dict = note.to_dict() + p_dict = pad.to_dict() + p_dict['is_favorite'] = pad.id in fav_ids + p_dict['can_write'] = check_pad_write_permission(pad, user_id) + + n_dict['notepad'] = p_dict + n_dict['owner_id'] = pad.user_id # Keep for map marker compatibility + n_dict['is_public'] = pad.is_public # Keep for map marker compatibility + output.append(n_dict) + + return jsonify(output) + +@search_bp.route('/api/geocode') +def geocode(): + q = request.args.get('q', '') + if not q: + return jsonify([]) + + try: + # Proxy request to Nominatim with required User-Agent + url = f"https://nominatim.openstreetmap.org/search?format=json&q={urllib.parse.quote(q)}" + req = urllib.request.Request(url, headers={'User-Agent': 'SpotNotesApp/1.0'}) + + with urllib.request.urlopen(req) as response: + data = json.loads(response.read().decode()) + return jsonify(data) + except Exception as e: + print(f"Geocode error: {e}") + return jsonify({'error': str(e)}), 500 \ No newline at end of file diff --git a/blueprints/static_routes.py b/blueprints/static_routes.py new file mode 100644 index 0000000..739a4d4 --- /dev/null +++ b/blueprints/static_routes.py @@ -0,0 +1,11 @@ +from flask import Blueprint, current_app + +static_bp = Blueprint('static_routes', __name__) + +@static_bp.route('/') +def index(): + return current_app.send_static_file('index.html') + +@static_bp.route('/') +def serve_static(path): + return current_app.send_static_file(path) \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..72a205d --- /dev/null +++ b/config.py @@ -0,0 +1,9 @@ +import os + +basedir = os.path.abspath(os.path.dirname(__file__)) + +class Config: + SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key-very-secret' + SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ + 'sqlite:///' + os.path.join(basedir, 'spotnotes.db') + SQLALCHEMY_TRACK_MODIFICATIONS = False \ No newline at end of file diff --git a/extensions.py b/extensions.py new file mode 100644 index 0000000..d227d1d --- /dev/null +++ b/extensions.py @@ -0,0 +1,5 @@ +from flask_sqlalchemy import SQLAlchemy +from flask_cors import CORS + +db = SQLAlchemy() +cors = CORS() \ No newline at end of file diff --git a/gunicorn_config.py b/gunicorn_config.py new file mode 100644 index 0000000..30e6708 --- /dev/null +++ b/gunicorn_config.py @@ -0,0 +1,2 @@ +bind = "0.0.0.0:8081" +workers = 2 diff --git a/models/banned_ip.py b/models/banned_ip.py new file mode 100644 index 0000000..d72829a --- /dev/null +++ b/models/banned_ip.py @@ -0,0 +1,7 @@ +from extensions import db +from datetime import datetime + +class BannedIP(db.Model): + id = db.Column(db.Integer, primary_key=True) + ip_address = db.Column(db.String(45), unique=True, nullable=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow) \ No newline at end of file diff --git a/models/collaborator.py b/models/collaborator.py new file mode 100644 index 0000000..d13ff0b --- /dev/null +++ b/models/collaborator.py @@ -0,0 +1,25 @@ +from extensions import db +from datetime import datetime + +class Collaborator(db.Model): + id = db.Column(db.Integer, primary_key=True) + notepad_id = db.Column(db.Integer, db.ForeignKey('notepad.id', ondelete='CASCADE'), nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'), nullable=False) + permission = db.Column(db.String(20), default='read', nullable=False) # 'read' or 'write' + created_at = db.Column(db.DateTime, default=datetime.utcnow) + + user = db.relationship('User', backref=db.backref('collaborations', cascade='all, delete-orphan', lazy='dynamic')) + notepad = db.relationship('Notepad', backref=db.backref('collaborators', cascade='all, delete-orphan', lazy='dynamic')) + + __table_args__ = ( + db.UniqueConstraint('notepad_id', 'user_id', name='unique_collaborator'), + ) + + def to_dict(self): + return { + 'id': self.id, + 'notepad_id': self.notepad_id, + 'user_id': self.user_id, + 'user_email': self.user.email if self.user else None, + 'permission': self.permission + } \ No newline at end of file diff --git a/models/favorite.py b/models/favorite.py new file mode 100644 index 0000000..d0afb29 --- /dev/null +++ b/models/favorite.py @@ -0,0 +1,10 @@ +from extensions import db + +class Favorite(db.Model): + id = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + notepad_id = db.Column(db.Integer, db.ForeignKey('notepad.id'), nullable=False) + + __table_args__ = ( + db.UniqueConstraint('user_id', 'notepad_id', name='unique_favorite'), + ) \ No newline at end of file diff --git a/models/note.py b/models/note.py new file mode 100644 index 0000000..aa9dd44 --- /dev/null +++ b/models/note.py @@ -0,0 +1,22 @@ +from extensions import db +from datetime import datetime + +class Note(db.Model): + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(200), nullable=False, default="Untitled") + content = db.Column(db.Text, nullable=False) + lat = db.Column(db.Float, nullable=False) + lng = db.Column(db.Float, nullable=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow) + is_hidden = db.Column(db.Boolean, default=False) + notepad_id = db.Column(db.Integer, db.ForeignKey('notepad.id'), nullable=False) + + def to_dict(self): + return { + 'id': self.id, + 'title': self.title, + 'content': self.content, + 'lat': self.lat, + 'lng': self.lng, + 'created_at': self.created_at.isoformat() + } \ No newline at end of file diff --git a/models/notepad.py b/models/notepad.py new file mode 100644 index 0000000..44f3562 --- /dev/null +++ b/models/notepad.py @@ -0,0 +1,21 @@ +from extensions import db +from datetime import datetime + + +class Notepad(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100), nullable=False) + is_public = db.Column(db.Boolean, default=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + + notes = db.relationship('Note', backref='notepad', lazy='dynamic', cascade="all, delete-orphan") + + def to_dict(self): + return { + 'id': self.id, + 'name': self.name, + 'is_public': self.is_public, + 'owner_id': self.user_id, + 'note_count': self.notes.filter_by(is_hidden=False).count() + } \ No newline at end of file diff --git a/models/user.py b/models/user.py new file mode 100644 index 0000000..db24207 --- /dev/null +++ b/models/user.py @@ -0,0 +1,29 @@ +from extensions import db +from werkzeug.security import generate_password_hash, check_password_hash + +class User(db.Model): + id = db.Column(db.Integer, primary_key=True) + email = db.Column(db.String(120), unique=True, nullable=False) + first_name = db.Column(db.String(50), nullable=False) + last_name = db.Column(db.String(50), nullable=False) + password_hash = db.Column(db.String(256)) + is_admin = db.Column(db.Boolean, default=False) + is_banned = db.Column(db.Boolean, default=False) + last_ip = db.Column(db.String(45)) + + def set_password(self, password): + self.password_hash = generate_password_hash(password) + + def check_password(self, password): + return check_password_hash(self.password_hash, password) + + def to_dict(self): + return { + 'id': self.id, + 'email': self.email, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'is_admin': self.is_admin, + 'is_banned': self.is_banned, + 'last_ip': self.last_ip + } \ No newline at end of file diff --git a/notes/birding.csv b/notes/birding.csv new file mode 100644 index 0000000..27bf7b6 --- /dev/null +++ b/notes/birding.csv @@ -0,0 +1,51 @@ +title,content,lat,lng +Magee Marsh,The "Warbler Capital of the World" offers legendary close-up views of colorful migrants.,41.6117,-83.1864 +Bosque del Apache NWR,Tens of thousands of Sandhill Cranes and Snow Geese create a stunning winter spectacle.,33.7997,-106.8906 +Cape May,A critical stopover point where thousands of hawks and songbirds congregate during fall.,38.9319,-74.9077 +Everglades National Park,This massive wetland is a paradise for spotting Roseate Spoonbills and Wood Storks.,25.2866,-80.8987 +High Island,Famous for "fallouts" where exhausted migratory songbirds land by the hundreds.,29.5608,-94.3894 +Point Reyes National Seashore,Over 490 bird species have been recorded at this diverse coastal headland.,38.0801,-122.9575 +Big Bend National Park,The only place in the United States where you can find the Colima Warbler.,29.2498,-103.2502 +Monterey Bay,A premier pelagic birding destination for Albatrosses, Shearwaters, and Jaegers.,36.6002,-121.8947 +Madera Canyon,A "sky island" famous for Elegant Trogons and over a dozen hummingbird species.,31.7230,-110.8800 +Sapsucker Woods,The home of the Cornell Lab of Ornithology features serene trails and rare species.,42.4795,-76.4513 +Aransas NWR,The primary wintering ground for the endangered and majestic Whooping Crane.,28.3139,-96.8040 +Sax-Zim Bog,A world-famous winter destination for boreal owls and northern finches.,47.1691,-92.7441 +J.N. "Ding" Darling NWR,Mangrove forests filled with Yellow-crowned Night-Herons and Roseate Spoonbills.,26.4468,-82.1122 +Bear River Migratory Bird Refuge,One of the best places in the West for American Avocets and Black-necked Stilts.,41.5126,-112.2681 +Chincoteague NWR,A diverse Atlantic coast refuge famous for shorebirds and Snowy Egrets.,37.9150,-75.3621 +Central Park,An urban oasis that acts as a "migrant trap" for dozens of warbler species.,40.7851,-73.9683 +Platte River Valley,The spring staging ground for nearly one million Sandhill Cranes.,40.7300,-98.4000 +Cave Creek Canyon,Spectacular cliffs in the Chiricahuas home to many Mexican specialties.,31.8967,-109.1719 +Laguna Atascosa NWR,A South Texas hotspot for Altamira Orioles and Aplomado Falcons.,26.2289,-97.3542 +Bombay Hook NWR,Expansive tidal salt marshes that attract massive numbers of shorebirds.,39.2559,-75.4678 +Mount Desert Island,Diverse habitats in Acadia National Park for Atlantic Puffins and Spruce Grouse.,44.3386,-68.2733 +Grand Isle,A vital first stop for Neotropical migrants crossing the Gulf of Mexico.,29.2366,-89.9873 +Klamath Basin NWR,The largest wintering population of Bald Eagles in the lower 48 states.,41.9200,-121.5700 +Santa Ana NWR,The "crown jewel" of the national wildlife refuge system for South Texas birds.,26.0700,-98.1400 +Hawk Mountain Sanctuary,The first refuge in the world dedicated specifically to birds of prey.,40.6416,-75.9866 +Dry Tortugas National Park,Isolated islands that serve as the only U.S. nesting site for Sooty Terns.,24.6285,-82.8733 +Lower Rio Grande Valley,A subtropical birding paradise with Green Jays and Great Kiskadees.,26.1000,-97.8000 +Malheur NWR,A high-desert oasis that is a massive draw for Trumpeter Swans and cranes.,43.2644,-118.8456 +Fort De Soto Park,Consistently ranked as one of the best spots in Florida for shorebird diversity.,27.6143,-82.7169 +Dauphin Island,A primary landfall site for migratory birds arriving in the spring.,30.2505,-88.1026 +Yellowstone National Park,High-altitude birding for Harlequin Ducks and American Dippers.,44.4280,-110.5885 +Olympic National Park,Rugged coastline and alpine forests home to Sooty Grouse and Marbled Murrelets.,47.8021,-123.6044 +Edwin B. Forsythe NWR,Managed impoundments that are ideal for viewing tens of thousands of waterfowl.,39.4633,-74.4447 +Patagonia-Sonoita Creek,One of the few places in the U.S. to see the Thick-billed Kingbird.,31.5422,-110.7600 +Great Smoky Mountains,Diverse elevations support everything from Wild Turkeys to Blackburnian Warblers.,35.6118,-83.4895 +Tule Lake NWR,A major stop on the Pacific Flyway for White-fronted Geese and Eared Grebes.,41.8800,-121.4600 +Merritt Island NWR,Surrounds the Kennedy Space Center and hosts thousands of wintering ducks.,28.6415,-80.6860 +Anahuac NWR,Coastal prairies and marshes famous for sightings of the elusive Yellow Rail.,29.6105,-94.4304 +Kodiak NWR,A rugged Alaskan refuge where you can find Tufted Puffins and Emperor Geese.,57.4800,-153.5000 +San Juan Islands NWR,Pristine marine habitats for Pigeon Guillemots and Rhinoceros Auklets.,48.5300,-123.0000 +Seney NWR,Large pools in Michigan's Upper Peninsula provide habitat for Common Loons.,46.2872,-85.9392 +Okefenokee NWR,Mysterious swamp habitat home to Sandhill Cranes and Prothonotary Warblers.,30.8400,-82.3400 +Gunnison Basin,The best (and only) place to find the rare Gunnison Sage-Grouse.,38.5458,-106.9253 +Glacier National Park,Alpine vistas hosting White-tailed Ptarmigan and Clark's Nutcrackers.,48.7596,-113.7870 +Snake River Canyon,The highest density of nesting raptors in all of North America.,43.3000,-115.8000 +Montrose Point,A world-class urban birding site on the Lake Michigan shoreline.,41.9642,-87.6375 +Waikamoi Preserve,A high-altitude rainforest that is the last stronghold for several Hawaiian honeycreepers.,20.7800,-156.2300 +Brazos Bend State Park,An inland Texas site known for its diversity of herons and songbirds.,29.3712,-95.5966 +Jekyll Island,A Georgia barrier island that is an excellent site for wintering shorebirds.,31.0700,-81.4200 +Pawnee National Grasslands,Wide-open prairies home to McCown's Longspurs and Mountain Plovers.,40.7833,-104.1167 \ No newline at end of file diff --git a/notes/conspiracy_locations.csv b/notes/conspiracy_locations.csv new file mode 100644 index 0000000..8ecc0ab --- /dev/null +++ b/notes/conspiracy_locations.csv @@ -0,0 +1,51 @@ +title,content,lat,lng +Area 51,Highly classified Air Force facility long associated with UFO and alien cover-ups.,37.2343,-115.8108 +Denver International Airport,"Subject of theories involving underground bunkers, New World Order murals, and gargoyles.",39.8561,-104.6737 +Dulce Base,Alleged secret underground laboratory where humans and aliens collaborate on experiments.,36.9395,-106.9986 +The Greenbrier Bunker,Once-secret massive underground facility designed to house Congress in the event of nuclear war.,37.7854,-80.3083 +The Georgia Guidestones Site,The site where granite monuments with 'commandments' for the New World Order stood until 2022.,34.2324,-82.8946 +Plum Island Animal Disease Center,Often linked to theories about the origin of Lyme disease and secret bio-warfare testing.,41.1736,-72.1864 +The HAARP Facility,A research site often accused of being a secret weather-control or mind-control weapon.,62.3933,-145.15 +Mount Weather Emergency Operations Center,The real-world 'safe house' for high-ranking officials during national disasters.,39.0631,-77.8892 +Montauk Project Site (Camp Hero),Alleged site of secret government projects involving time travel and psychological warfare.,41.0628,-71.8744 +The Bohemian Grove,A private campground where world leaders gather for secretive rituals in the redwoods.,38.48,-123.0019 +S-4 Facility,Alleged secret site near Papoose Lake rumored to house recovered extraterrestrial craft.,37.0863,-115.8208 +Winchester Mystery House,Built continuously to confuse the spirits of those killed by Winchester rifles.,37.3184,-121.9511 +Dealey Plaza,Site of the JFK assassination and the source of endless 'grassy knoll' theories.,32.779,-96.8082 +The Octagon House,Rumored to have secret tunnels and connections to early government occultism.,38.8995,-77.0403 +The Pentagon,"Central hub of US defense, often center-stage in massive structural and strategic theories.",38.8719,-77.0563 +Point Pleasant (Mothman Site),Location of numerous sightings of the Mothman before the Silver Bridge collapse.,38.8445,-82.1371 +Roswell UFO Crash Site,The epicenter of modern UFO conspiracy theories involving a 1947 crash.,33.3944,-104.523 +Coral Castle,Built by one man who supposedly used magnetism and anti-gravity to move massive stones.,25.5003,-80.4442 +Skinwalker Ranch,"A property famous for alleged paranormal activity, UFOs, and shape-shifters.",40.2526,-109.8872 +Brown Mountain Lights Overlook,Site of mysterious ghost lights that have defied scientific explanation for a century.,35.845,-81.745 +Marfa Lights Viewing Area,Atmospheric lights that have spawned theories ranging from ghosts to alien scouts.,30.2764,-103.8831 +The Integration,A structure built in the desert intended to act as a rejuvenation machine and time travel portal.,34.2986,-116.4036 +Teotihuacan,Ancient city often cited by ancient astronaut theorists for its planetary alignment.,19.6925,-98.8437 +San Luis Valley,A 'paranormal hotspot' known for cattle mutilations and high UFO traffic.,37.7492,-105.85 +Mount Shasta,"A volcanic peak rumored to hide the underground city of Telos, home to Lemurians.",41.4092,-122.1949 +The Stanley Hotel,Famous haunted hotel that inspired 'The Shining' and is center to psychic theories.,40.3833,-105.5189 +Bridgewater Triangle,"A region in Massachusetts known for cryptids, cult activity, and UFOs.",41.936,-71.026 +Bennington Triangle,Area of mysterious disappearances that some link to supernatural vortexes.,42.8781,-73.1968 +The Superstition Mountains,Home of the Lost Dutchman's Gold Mine and legends of underground gateways.,33.45,-111.35 +Bigfoot Discovery Museum,The headquarters for researchers tracking the legendary forest cryptid.,37.0505,-122.0725 +Sedona Vortexes,Sites believed to emit swirling centers of energy that affect the human spirit.,34.8697,-111.761 +International Cryptozoology Museum,Preserves evidence and artifacts from sightings of unproven animals.,43.6565,-70.2558 +Project Sign/Grudge Site (Wright-Patterson),Base rumored to be the true location where Roswell debris was stored.,39.8136,-84.0494 +Cheyenne Mountain Complex,Underground bunker that serves as the command center for NORAD.,38.7442,-104.8461 +Raven Rock Mountain Complex,The 'underground Pentagon' designed to sustain government after an attack.,39.7333,-77.4167 +Site R,Alternative name for the secret Raven Rock facility in Pennsylvania.,39.734,-77.417 +The Archuleta Mesa,High-altitude site above Dulce rumored to be an alien landing strip.,36.994,-106.942 +Blackwood Chasm,Alleged site of unexplained seismic activity and 'hollow earth' rumors.,35.1234,-112.5678 +The Great Dismal Swamp,Site of many 'maroon' colony legends and strange atmospheric phenomena.,36.6384,-76.4789 +Oak Island Money Pit,Site of a 200-year-old treasure hunt involving elaborate traps and theories.,44.5133,-64.2953 +Bermuda Triangle Tip (Miami),Eastern edge of the zone where ships and planes famously vanish.,25.7617,-80.1918 +Point Dume,Rumored underwater base entrance for UFOs coming from the Pacific.,34.0012,-118.8068 +Yakima UFO Hotspot,A location on the Yakima Indian Reservation with high frequency of 'orb' sightings.,46.2307,-120.6552 +Groom Lake,The dry lake bed adjacent to Area 51 used for secret test flights.,37.2758,-115.7989 +Tonopah Test Range,Site used for testing stealth technology and captured foreign aircraft.,37.795,-116.7722 +Dugway Proving Ground,"Often called 'Area 52', known for testing chemical and biological weapons.",40.2,-113.15 +The Winchester Vault,A specific locked room where Sarah Winchester allegedly held séances.,37.3185,-121.951 +The Dakota Building,Historical NYC residence associated with cult theories and the occult.,40.776,-73.9763 +Granite Mountain Records Vault,Massive Mormon genealogy vault built into a mountain for protection.,40.5728,-111.7711 +The Sphinx (Giza),Ancient monument often the subject of 'Hall of Records' underground theories.,29.9753,31.1376 diff --git a/notes/general_public.csv b/notes/general_public.csv new file mode 100644 index 0000000..585faad --- /dev/null +++ b/notes/general_public.csv @@ -0,0 +1,101 @@ +title,content,lat,lng +The Center of the Universe,An acoustic anomaly in Tulsa where you can shout and only you hear the echo.,36.1553,-95.9931 +The World's Tallest Thermometer,"A 134-foot tall reminder that Baker, California, is basically the surface of the sun.",35.2661,-116.0725 +Carhenge,A faithful replica of Stonehenge made entirely of vintage American automobiles.,42.1422,-102.8581 +The Fremont Troll,A massive stone troll living under a bridge that is currently eating a real VW Beetle.,47.651,-122.3473 +The Leaning Tower of Niles,A half-size replica of the Tower of Pisa that was built to hide a water tank.,42.0233,-87.7964 +Unclaimed Baggage Center,The only place on Earth where you can buy someone else's lost vacation dreams.,34.8697,-86.0028 +The Maine Ridge Runner,A tribute to the man who lived in the woods and stole only library books.,44.5497,-69.7797 +Cadillac Ranch Graffiti,A public note to the world where everyone is encouraged to bring spray paint.,35.1872,-101.987 +The Muffler Man,A giant fiberglass Paul Bunyan who lost his axe and now just looks confused.,35.5122,-98.9819 +World's Largest Ball of Twine,Built by one man who just didn't know when to stop winding.,39.4842,-97.6475 +The Mushroom Houses,Architectural notes in stone that look like they were designed by a Smurf.,45.3167,-85.2583 +Berkeley's Fish House,A house shaped like a giant fish because why live in a square box?,40.015,-105.2705 +The Prada Marfa,"A permanent ""store"" in the middle of the desert that will never actually open.",30.6035,-104.5185 +The Beer Can House,"A retirement project involving 50,000 flattened cans and a lot of patience.",29.7711,-95.4294 +The Republic of Molossia,"A sovereign ""micronation"" in Nevada that is currently at war with East Germany.",39.3233,-119.5397 +The Oregon Vortex,"A ""forbidden"" patch of land where brooms stand up and people look shorter.",42.4936,-123.0844 +Dinosaur Park,A collection of green concrete monsters that haven't aged a day since 1936.,44.0761,-103.2436 +The Paper House,"A home built out of 100,000 newspapers that has survived since 1922.",42.6681,-70.6289 +The Jolly Green Giant,A 55-foot tall statue that makes every visitor feel like a side dish of peas.,43.6483,-94.1039 +World's Largest Chest of Drawers,"A 38-foot tall dresser that serves as a literal ""note"" on the local furniture industry.",35.975,-80.0069 +Lucy the Elephant,A six-story high wooden elephant that used to be a real estate office.,39.3225,-74.4533 +Desert Christ Park,A hillside covered in giant statues waiting for a movie that never started.,34.1197,-116.4447 +The Gum Wall,"A colorful, sticky, and slightly gross public mosaic of chewed-up history.",47.6083,-122.34 +Ave Maria Grotto,A tiny world of 125 miniature stone shrines built by a hunchbacked monk.,34.1758,-86.8294 +"Hole N"" The Rock","A 5,000-square-foot home blasted into a solid cliff face by one very determined man.",38.39,-109.455 +The Spite House,A very narrow home built specifically to block a neighbor's view of the street.,42.3781,-71.1167 +Coral Castle,"A monument built by a 100-pound man using ""the secrets of the pyramids.""",25.5006,-80.4442 +The Haines Shoe House,A literal giant shoe that you can actually sleep in.,39.9928,-76.6347 +The Toilet Seat Art Museum,"A collection of over 1,000 lids proving that anything can be a canvas.",35.2014,-101.8317 +Enchanted Highway,A stretch of road featuring a 110-foot tall family made of scrap metal.,46.4719,-102.5589 +The Peachoid,A water tower that looks suspiciously like a giant bottom from the highway.,35.0808,-81.6739 +The Big Duck,A poultry-shaped building designed specifically to sell duck eggs.,40.8233,-72.7153 +The Hat Museum,A tribute to the days when nobody left the house without a topper.,45.5122,-122.6758 +Jimmy Carter's Peanut,A giant smiling peanut statue that bears an uncanny resemblance to the president.,32.0436,-84.3917 +The UFO Watchtower,A platform in the desert where people wait for a ride to the stars.,37.935,-105.8753 +The Longaberger Basket,A seven-story office building that looks exactly like a picnic basket.,40.0636,-82.3458 +Vollis Simpson Whirligig Park,"A field of massive, colorful kinetic sculptures made from farm parts.",35.7311,-77.9125 +The Bone Museum,An Oklahoma City gem where the skeletons literally tell the story.,35.3942,-97.4933 +The Wigwam Village No. 2,"A 1930s hotel where you can tell people you ""slept in a teepee.""",37.1472,-85.9189 +The Blue Hole,A natural artesian spring in the desert that stays 62 degrees all year.,34.9439,-104.6736 +Salem Witch Trials Memorial,"A somber note in stone to those who were ""not actually witches.""",42.5211,-70.8911 +The Evolution of the O,A statue at OU that students touch for luck before finals.,35.2089,-97.4456 +Old North Tower,A historic building on UCO's campus that is a landmark for every Edmond local.,35.6558,-97.4725 +World's Smallest Police Station,A repurposed phone booth that was used by the local force until 1990.,29.8136,-84.6589 +The Egg City,A tribute to the once-thriving poultry industry that now looks like an alien base.,34.2814,-118.8833 +Sleepy Hollow Headless Horseman,A bridge where people still look over their shoulders for a pumpkin-headed rider.,41.0903,-73.8617 +The International UFO Museum,"The only place where ""I saw a weather balloon"" is an insult.",33.3944,-104.5231 +Marvin's Marvelous Mechanical Museum,A chaotic collection of vintage coin-op machines and weird neon signs.,42.5286,-83.3528 +The Winchester House Mystery,A home with stairs that lead nowhere and doors that open to drops.,37.3184,-121.9367 +The Neon Museum,"The ""Boneyard"" where retired Las Vegas signs go to spend their golden years.",36.1769,-115.1356 +Lucy the Elephant,A six-story elephant built in 1881 to sell real estate and survived several hurricanes.,39.3233,-74.4533 +Prada Marfa,A permanently closed luxury boutique in the middle of the Texas desert that is actually an art installation.,30.6035,-104.5185 +The Corn Palace,A multipurpose arena decorated annually with murals made entirely of corn and other grains.,43.7142,-98.0253 +Wall Drug Store,A massive tourist stop that started by offering free ice water and now takes up an entire city block.,43.9928,-102.2414 +The Thing?,"A roadside mystery in Arizona that you have to pay a few dollars to see, hidden in a series of sheds.",32.0942,-110.3019 +Salvation Mountain,"A massive colorful art installation made of adobe and straw, covered in thousands of gallons of paint.",33.2538,-115.4731 +Seven Magic Mountains,"A desert art installation featuring seven towers of colorful, stacked boulders.",35.8383,-115.2708 +Musical Highway,A stretch of Route 66 that plays 'America the Beautiful' if you drive exactly 45 mph.,35.0744,-106.4322 +Carving of Crazy Horse,A mountain monument under construction since 1948 that will eventually be the world's largest sculpture.,43.8367,-103.6244 +Bottle Tree Ranch,A forest of 'trees' made from glass bottles and scrap metal along old Route 66.,34.6908,-117.3374 +Wigwam Motel,A classic motel where you sleep in individual concrete teepees.,34.9022,-110.1581 +London Bridge,"The actual bridge from London, dismantled and moved to the Arizona desert in 1968.",34.4717,-114.3472 +Meteor Crater,"The best-preserved meteorite impact site on Earth, nearly one mile across.",35.0272,-111.0225 +Bishop Castle,A massive stone castle built by one man over 60 years using local rocks.,38.0614,-105.0942 +The Stanley Hotel,The inspiration for Stephen King's 'The Shining' and a hotspot for ghost hunters.,40.3833,-105.5189 +Meow Wolf Santa Fe,An immersive art experience that starts in a Victorian house and leads to psychedelic dimensions.,35.6548,-105.9967 +Cadillac Ranch,"Ten Cadillacs buried nose-first in the ground, inviting visitors to leave their mark with spray paint.",35.1872,-101.987 +Hole N' The Rock,"A 5,000 square foot home carved directly into a massive sandstone rock.",38.3912,-109.4567 +Enchanted Highway,A collection of the world's largest scrap metal sculptures along a 32-mile stretch of road.,46.4674,-102.5583 +Cabazon Dinosaurs,Giant roadside dinosaurs featured in the movie 'Pee-wee's Big Adventure'.,33.92,-116.7725 +Winslow Corner,"A park dedicated to the Eagles' song 'Take It Easy', complete with a flatbed Ford.",35.0242,-110.6975 +Hoover Dam,A massive concrete arch-gravity dam in the Black Canyon of the Colorado River.,36.0162,-114.7372 +Four Corners Monument,The only place in the US where you can stand in four states at the same time.,36.9991,-109.0452 +Shiprock,"A towering volcanic rock formation that rises 1,500 feet above the desert floor.",36.6872,-108.8364 +Very Large Array,A massive radio astronomy observatory consisting of 27 giant dish antennas.,34.079,-107.6184 +Rio Grande Gorge Bridge,"The tenth highest bridge in the United States, offering dizzying views of the river below.",36.4764,-105.733 +Garden of the Gods,A park of towering red sandstone rock formations against a backdrop of Pikes Peak.,38.8785,-104.8806 +Royal Gorge Bridge,"One of the world's highest suspension bridges, hanging 955 feet above the Arkansas River.",38.4614,-105.3253 +Casa Bonita,"A legendary pink Mexican restaurant with indoor waterfalls, cliff divers, and puppet shows.",39.7419,-105.0708 +Coral Castle,An oolite limestone structure built by one man who claimed to know the secrets of the pyramids.,25.5003,-80.4442 +Ames Pyramid,A 60-foot tall granite pyramid built to honor the brothers who financed the Union Pacific Railroad.,41.1314,-105.3975 +Market Theater Gum Wall,"A brick wall covered entirely in used chewing gum, considered a local landmark.",47.6084,-122.3404 +The Big Basket,A seven-story office building shaped exactly like a Longaberger picnic basket.,40.0633,-82.3464 +Carhenge,A replica of England's Stonehenge formed from vintage American automobiles.,42.1422,-102.8581 +Winchester Mystery House,A massive Victorian mansion built continuously for 38 years to appease spirits.,37.3184,-121.9511 +Dinosaur Park,A hilltop park featuring seven giant concrete dinosaur sculptures built during the Great Depression.,44.0789,-103.2458 +International UFO Museum,A museum dedicated to the 1947 Roswell UFO incident and all things extraterrestrial.,33.3944,-104.523 +Gatorland,"The 'Alligator Capital of the World', featuring thousands of gators and crocodiles.",28.3556,-81.3364 +The Blue Hole,A sapphire-blue artesian spring in the middle of the New Mexico desert.,34.9439,-104.6736 +Dinosaur Kingdom II,A bizarre theme park where Union soldiers fight dinosaurs in the Civil War.,37.6631,-79.4883 +Desert of Maine,A 40-acre patch of glacial silt that looks exactly like a desert in the middle of a forest.,43.8586,-70.1283 +World's Largest Chest of Drawers,"An 80-foot tall building shaped like a dresser, complete with giant socks hanging out.",35.9681,-80.0101 +Ava Maria Grotto,A park containing 125 miniature replicas of famous religious structures from around the world.,34.1764,-86.8331 +The Unclaimed Baggage Center,The only store in the world that buys and sells lost luggage from airlines.,34.8697,-86.0028 +Voodoo Doughnut,A quirky doughnut shop known for its eccentric decor and unconventional toppings.,45.5227,-122.6731 +The Heidelberg Project,An open-air art environment in Detroit that transformed a neighborhood into a massive gallery.,42.3584,-83.0214 +Wall Drug,The legendary drug store that grew from free ice water into a world-famous attraction.,43.9928,-102.2414 +The Salt Palace,A salt-covered building in Utah where you can literally lick the walls.,40.7667,-111.895 +Paper House,A house built entirely out of newspapers by a mechanical engineer in 1922.,42.6622,-70.6289 +Dog Bark Park Inn,"A bed and breakfast shaped like a giant beagle, where guests sleep inside the dog.",46.0583,-116.4447 diff --git a/notes/haunted-oklahoma.csv b/notes/haunted-oklahoma.csv new file mode 100644 index 0000000..eda9db4 --- /dev/null +++ b/notes/haunted-oklahoma.csv @@ -0,0 +1,51 @@ +title,content,lat,lng +Skirvin Hotel,A maid named Effie and her baby are said to haunt the 10th floor.,35.4697,-97.5144 +Cain's Ballroom,The ghost of Bob Wills is rumored to play his fiddle late at night.,36.1610,-95.9918 +Stone Lion Inn,A young girl named Augusta is often heard running through the halls.,35.8797,-97.4257 +Dead Woman's Crossing,A headless woman searches for her child near the old bridge site.,35.5667,-98.6500 +Fort Washita,The spirit of Aunt Jane is seen wandering the grounds in a 19th-century dress.,34.1030,-96.5505 +Belvidere Mansion,The original owner died before completion and still roams the master suite.,36.3150,-95.6078 +Cherokee Strip Museum,Ghostly hospital patients from its former life are seen in the windows.,36.7570,-98.6660 +Guthrie Masonic Boys Home,Orphan spirits are said to play in the halls of this former home.,35.8647,-97.4111 +Blue Belle Saloon,The ghost of a murdered woman named Claudia haunts the cellar.,35.8778,-97.4261 +Overholser Mansion,The Overholser family spirits are seen looking out from the windows.,35.4856,-97.5283 +Constantine Theater,A ghostly woman in a Victorian dress is seen sitting in the balcony.,36.6661,-96.3400 +Fort Reno,Soldiers from the frontier and POWs are heard marching on the grounds.,35.5451,-98.0267 +Tulsa Theater,A stagehand who died in an accident is said to haunt the backstage.,36.1583,-95.9936 +Labadie Mansion,A tragic fire left the spirits of a family trapped in the ruins.,36.7112,-95.9525 +Haskell University (Old Site),Crying children are heard near the sites of the former boarding schools.,35.8236,-95.3405 +Bird Creek School,A spectral teacher is still seen writing on the chalkboard after dark.,36.6961,-96.3389 +Kitchen Lake,The "Witch of Kitchen Lake" is said to chase off late-night visitors.,35.3444,-97.3911 +Parallel Forest,Trees planted in perfect rows create a disorienting haunt for hikers.,34.7297,-98.6744 +Spook Light,A mysterious orb of light has bounced down this road for over 100 years.,36.9414,-94.6361 +Gilcrease Museum,Thomas Gilcrease is seen wandering his favorite garden paths.,36.1751,-95.9996 +Picher Ghost Town,The toxic remains of this town are haunted by the echoes of those left behind.,36.9839,-94.8291 +St. Vincent's Asylum,Tormented spirits from the hospital's dark past roam the abandoned wings.,35.4725,-97.5501 +Langston's Western Wear,Two sisters who died in a fire haunt the upstairs dance floor area.,35.4489,-97.5456 +The Purple Church,Rumors of occult rituals have left a dark energy at these ruins.,35.9189,-97.4183 +Sacred Heart Mission,The charred ruins are haunted by those lost in a devastating 1901 fire.,35.1436,-97.0544 +Hex House,A real-life tale of psychological torture left a permanent stain here.,36.1556,-95.9889 +Griffin Memorial Hospital,Shadow figures are frequently reported in the older hospital tunnels.,35.2189,-97.4236 +Cry Baby Bridge (Moore),The sounds of a crying infant are heard coming from beneath the span.,35.3392,-97.4589 +Timber Ridge Cemetery,A ghostly boy on a bicycle is seen along the road at night.,36.1744,-95.7336 +Governor's Mansion,Former residents are seen in the halls of this historic residence.,35.4925,-97.5033 +Mohawk Park,A "Deer Lady" is said to lure people into the deep woods here.,36.2167,-95.9000 +Poncan Theatre,A ghost named "Pete" is known to play pranks on the projectionist.,36.7031,-97.0850 +Wheelock Academy,The "Ghost Maiden" is seen walking the grounds of the girls' school.,33.9939,-94.9961 +Ingalls Ghost Town,Outlaw spirits from the Doolin-Dalton gang shootout still linger.,36.1044,-96.8833 +Murrell Home,Musical instruments are heard playing in empty rooms of the mansion.,35.8572,-94.9603 +Oklahoma State University,A ghost named "Old Red" is seen in the halls of the library.,36.1214,-97.0678 +University of Oklahoma,The spirit of a roller-skating boy haunts the North Oval.,35.2089,-97.4456 +Santa Fe Depot (Guthrie),The sounds of a steam engine are heard when no train is near.,35.8778,-97.4303 +Hillside Mission Cemetery,Native American spirits are seen protecting the old mission grounds.,36.1558,-96.2239 +Broken Arrow Elks Lodge,A mysterious man in a tuxedo is seen in the ballroom mirrors.,36.0508,-95.7908 +Central State Hospital,Unexplained screams are heard coming from the old morgue area.,35.2194,-97.4253 +Pawnee Bill Ranch,The ghost of May Lillie is seen in her former bedroom.,36.3339,-96.8086 +Kendall's Restaurant,A young boy's ghost likes to play with toys in the dining area.,35.1400,-97.3919 +Saline Courthouse,The old lawmen never truly left this historic Cherokee site.,36.2081,-95.1158 +Jack Brown Home,Lights flicker and whispers are heard in this old Tahlequah house.,35.9133,-94.9700 +Hotel Vinita,A man in a 1920s suit is seen walking through the ballroom walls.,36.6439,-95.1556 +Frank and Lola's,A female spirit named Estelle is heard calling out from the kitchen.,36.7481,-95.9764 +Pink House Restaurant,A protective female ghost is known to move furniture and slam doors.,35.9583,-95.3772 +Elgin Cemetery,Strange lights and shadow figures follow visitors through the gates.,34.7814,-98.2911 +Boggy Depot,A Confederate soldier is seen standing guard near the old cemetery.,34.3514,-96.3119 \ No newline at end of file diff --git a/notes/haunted-usa.csv b/notes/haunted-usa.csv new file mode 100644 index 0000000..de3280b --- /dev/null +++ b/notes/haunted-usa.csv @@ -0,0 +1,51 @@ +title,content,lat,lng +Eastern State Penitentiary,The "Slick Willie" spirit is often seen in the shadows of the crumbling cellblocks.,39.9683,-75.1727 +The Stanley Hotel,The sounds of a phantom piano playing in the ballroom often wake guests.,40.3833,-105.5189 +Gettysburg Battlefield,Soldiers in tattered uniforms are frequently seen reenacting their final moments.,39.8142,-77.2375 +The Whaley House,The ghost of "Yankee Jim" Robinson is said to haunt the staircase where he died.,32.7523,-117.1947 +Waverly Hills Sanatorium,The "Creeper" is a shadow figure known to crawl along the ceiling of the tunnels.,38.1256,-85.8414 +LaLaurie Mansion,Victims of the infamous Madame LaLaurie are heard screaming from the attic.,29.9615,-90.0620 +The Myrtles Plantation,Chloe a former slave is often photographed peering out from behind columns.,30.7951,-91.2882 +Trans-Allegheny Lunatic Asylum,A ghostly girl named Lily is known to follow visitors and play with toys.,39.0392,-80.4682 +The Queen Mary,A "lady in white" wanders the salon and ghosts are heard splashing in the pool.,33.7526,-118.1903 +Villisca Axe Murder House,The spirits of the Moore children are still heard laughing and crying.,40.9299,-94.9740 +Alcatraz Island,Cell block D is said to have a "cold spot" where an unseen entity chokes inmates.,37.8267,-122.4230 +St. Augustine Lighthouse,Two young sisters who drowned during construction are seen playing on the steps.,29.8860,-81.2884 +The Mount,Edith Wharton's former home is haunted by figures in period clothing.,42.3486,-73.3150 +Winchester Mystery House,The heiress built endless hallways to confuse the spirits of those killed by her rifles.,37.3184,-121.9367 +Lizzie Borden House,The spirits of the elder Bordens are said to still linger in the guest rooms.,41.7011,-71.1558 +Crescent Hotel,A Victorian ghost named Michael is known to play pranks in Room 218.,36.4086,-93.7364 +Sossaman Ferry Road,A spectral hitchhiker is seen waiting for a ride that never comes.,33.4000,-111.6667 +The Lemp Mansion,Three members of the Lemp family committed suicide and are seen in the halls.,38.5908,-90.2245 +Bachelor's Grove Cemetery,A phantom farmhouse appears and disappears in the middle of the woods.,41.6306,-87.7697 +Rolling Hills Asylum,A massive shadow man named Roy stalks the hallway of the second floor.,42.8988,-78.1360 +The Driskill Hotel,The spirit of a young girl playing with a ball is heard on the grand staircase.,30.2681,-97.7405 +Old Charleston Jail,Infamous serial killer Lavinia Fisher is said to haunt her former cell.,32.7758,-79.9372 +Dock Street Theatre,A ghost named Nettie is seen gliding across the stage in a red dress.,32.7781,-79.9303 +Fort Mifflin,The "Screaming Lady" is heard wailing from the casemates of the fort.,39.8856,-75.2125 +Trans-Allegheny Asylum,Patients who were mistreated are seen wandering the massive stone corridors.,39.0392,-80.4682 +Moundsville Penitentiary,The "Shadow Man" is a dark entity seen lurking near the execution room.,39.9142,-80.7428 +Moon River Brewing Co.,A violent spirit named "Toby" is known to push people in the basement.,32.0809,-81.0924 +Sorrel-Weed House,The spirits of two women who died tragic deaths haunt the courtyard.,32.0734,-81.0950 +Bodie Ghost Town,The ghosts of miners protect the town and curse those who take artifacts.,38.2122,-119.0125 +Old Louisville,A Victorian gentleman is often seen walking his dog along the gas-lit streets.,38.2291,-85.7602 +The Omni Homestead,A jilted bride is said to roam the 14th floor looking for her groom.,37.9958,-79.8286 +The Red Onion Saloon,A ghost named Lydia is known to leave the scent of perfume in the air.,59.4539,-135.3136 +Bobby Mackey's Music World,A "portal to hell" in the basement is said to cause physical scratches.,39.0667,-84.5000 +Pennhurst Asylum,The mistreatment of patients has left behind a heavy dark energy and screams.,40.1834,-75.5562 +Sloss Furnaces,A cruel foreman named "Slag" is said to haunt the catwalks.,33.5206,-86.7908 +The Bell Witch Cave,An entity tormented the Bell family and is said to still inhabit the cave.,36.5894,-87.2158 +Merchant's House Museum,The Tredwell family never left their 19th-century Manhattan home.,40.7281,-73.9926 +The Congress Plaza Hotel,"Peg Leg Johnny" is a spirit that wanders the halls of the south tower.,41.8753,-87.6247 +The Marshall House,The hotel served as a hospital and guests report seeing phantom amputees.,32.0798,-81.0906 +The Grove,The "Lady in White" is seen walking the gardens of this Jefferson estate.,32.7606,-94.3411 +Ohio State Reformatory,The spirit of the warden's wife is often smelled as rose perfume.,40.7836,-82.5022 +Fort Delaware,Confederate prisoners are seen marching through the dungeon-like cells.,39.5889,-75.5686 +Emily's Bridge,A vengeful spirit named Emily is said to scratch cars that cross at night.,44.4375,-72.4844 +Poinsett Bridge,Strange lights and figure-like mists are seen under the stone arch.,35.1292,-82.3386 +Salem Witch House,The energy of the 1692 witch trials still hangs heavy in this home.,42.5215,-70.8996 +The Octagon House,The spirits of two daughters who fell down the stairs still linger.,38.8947,-77.0406 +Pike Place Market,A ghost named "Arthur" is known to browse the stalls after hours.,47.6097,-122.3422 +Bushwick Inlet Park,A ghostly sea captain is seen looking out over the East River.,40.7222,-73.9619 +The Rengstorff House,A woman in a white dress is seen staring out at the bay.,37.4339,-122.0911 +The Menger Hotel,The ghost of Teddy Roosevelt has been seen having a drink at the bar.,29.4248,-98.4862 \ No newline at end of file diff --git a/notes/route66.csv b/notes/route66.csv new file mode 100644 index 0000000..5649e38 --- /dev/null +++ b/notes/route66.csv @@ -0,0 +1,51 @@ +title,content,lat,lng +Route 66 Begin Sign,The symbolic start of the Mother Road located on Adams Street in downtown Chicago.,41.8794,-87.6245 +Lou Mitchell's,Known as the "first stop" on the route serving breakfast since before the road opened.,41.8784,-87.6395 +Gemini Giant,A 30-foot-tall "Muffler Man" in an astronaut suit named for the Gemini space program.,41.3105,-88.1478 +Ambler's Texaco Gas Station,The longest operating gas station on Route 66 now serves as a visitor center.,41.0924,-88.4271 +Standard Oil Gas Station,An iconic eight-sided "cottage-style" station that served travelers in the 1930s.,41.0044,-88.5233 +Chain of Rocks Bridge,Famous for its 22-degree bend this bridge carried travelers over the Mississippi River.,38.7601,-90.1764 +Gateway Arch,The 630-foot monument to westward expansion is a primary landmark for Missouri travelers.,38.6247,-90.1848 +Meramec Caverns,Advertised for decades on barns across the country as a legendary outlaw hideout.,38.2431,-91.0903 +Wagon Wheel Motel,The oldest continuously operating motel on the route with original stone cottages.,38.0011,-91.3914 +Gay Parita Sinclair Station,A lovingly recreated 1930s gas station that is a favorite for photo ops.,37.2642,-93.7142 +66 Drive-In Theatre,A classic neon-lit outdoor cinema that has been showing movies since 1949.,37.1856,-94.3353 +Cars on the Route,A restored station featuring the tow truck that inspired the character Mater.,37.0753,-94.6361 +Rainbow Bridge,The last remaining Marsh Arch bridge on Route 66 built in 1923.,37.0672,-94.7075 +Blue Whale of Catoosa,A whimsical waterfront landmark built as an anniversary gift in the early 70s.,36.1932,-95.7333 +The Blue Dome,A 1924 Art Deco service station that once offered 24-hour service to travelers.,36.1539,-95.9861 +Rock Cafe,A historic eatery built from local stone whose owner inspired Sally in the movie Cars.,35.7533,-96.6542 +Arcadia Round Barn,A restored 1898 wooden barn that is a feat of local engineering and design.,35.6608,-97.3239 +Pops 66 Soda Ranch,A modern landmark featuring a 66-foot tall neon soda bottle and over 700 sodas.,35.6606,-97.3353 +Milk Bottle Grocery,A tiny triangular building topped with a giant metal milk bottle.,35.4925,-97.5303 +Lake Overholser Bridge,A critical 1924 link for early motorists crossing the North Canadian River.,35.4800,-97.6694 +Lucille's Service Station,A classic "porch-style" station that served travelers for over 60 years.,35.5317,-98.5306 +Route 66 Museum Clinton,An immersive museum that takes visitors through the history of the road by decade.,35.5122,-98.9819 +U-Drop Inn,A stunning Art Deco masterpiece that served as both a café and a gas station.,35.2153,-100.2483 +Leaning Tower of Texas,A tilted water tower intended as a clever marketing gimmick to draw travelers in.,35.2014,-101.1128 +Big Texan Steak Ranch,Home of the free 72-ounce steak challenge if you can finish it in an hour.,35.1914,-101.7606 +Cadillac Ranch,An art installation featuring 10 vintage Cadillacs buried nose-first in the dirt.,35.1872,-101.9870 +Midpoint Cafe,The geographical halfway point between Chicago and Santa Monica.,35.0394,-102.6664 +Blue Swallow Motel,Famous for its stunning neon sign and garages attached to every room.,35.1764,-103.7153 +Tee Pee Curios,A whimsical shop shaped like a tipi that has sold souvenirs since the 1940s.,35.1717,-103.7317 +Route 66 Auto Museum,A high-quality collection of vintage cars and memorabilia in Santa Rosa.,34.9383,-104.6881 +Central Avenue,The longest urban stretch of the original route running through Albuquerque.,35.0844,-106.6504 +KiMo Theatre,A beautiful "Pueblo Deco" theater that blends Native American and Art Deco styles.,35.0844,-106.6522 +El Rancho Hotel,The "Home of the Movie Stars" who filmed Westerns in the nearby desert.,35.5261,-108.7214 +Yellowhorse Trading Post,A gateway to the Navajo Nation set against massive red sandstone cliffs.,35.3533,-109.0556 +Jack Rabbit Trading Post,Famous for its "HERE IT IS" sign and the giant fiberglass rabbit out front.,34.9800,-110.3347 +Wigwam Motel,One of only two remaining motels on Route 66 where you can sleep in a tipi.,34.9039,-110.1586 +Painted Desert Inn,A National Historic Landmark built from petrified wood and native stone.,35.0833,-109.7833 +Standin' on the Corner Park,Commemorates the famous lyrics from the Eagles song "Take It Easy".,35.0211,-110.6975 +La Posada Hotel,A restored 1929 Harvey House hotel that was a favorite of celebrities.,35.0242,-110.6931 +Meteor Crater,The world's best-preserved meteorite impact site located just off the route.,35.0272,-111.0225 +Museum Club,A former roadhouse and taxidermy shop that became a famous country music venue.,35.2047,-111.5997 +Seligman Route 66 Shield,A large painted highway shield on the pavement in the "Birthplace of Historic Route 66".,35.3267,-112.8711 +Delgadillo's Snow Cap,A quirky drive-in famous for its practical jokes and vintage "shocker" cars.,35.3261,-112.8756 +Hackberry General Store,A "museum" of Route 66 kitsch and vintage gas pumps in the desert.,35.3661,-113.7225 +Oatman Ghost Town,A former gold mining camp famous for wild burros that roam the streets.,35.0264,-114.3831 +Elmer's Bottle Tree Ranch,A unique forest of art installations made entirely from vintage glass bottles.,34.6908,-117.3381 +Wigwam Motel San Bernardino,The second "village" of concrete tipis still welcoming guests in California.,34.1069,-117.3456 +Cucamonga Service Station,A restored 1915 station that represents the earliest days of the route.,34.1067,-117.5939 +Santa Monica Pier,The official symbolic "End of the Trail" where the route meets the Pacific.,34.0101,-118.4961 +End of the Trail Sign,The most photographed sign on the route marking the 2,448-mile journey's end.,34.0086,-118.4983 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dccaabe --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +Flask +requests +Flask-Cors +gunicorn +Flask-SQLAlchemy +python-dotenv \ No newline at end of file diff --git a/seed_notes.py b/seed_notes.py new file mode 100644 index 0000000..fef9001 --- /dev/null +++ b/seed_notes.py @@ -0,0 +1,80 @@ +import csv +import sys +import os +from app import app +from extensions import db +from models.notepad import Notepad +from models.note import Note +from models.user import User + +def seed_from_csv(csv_file, notepad_name, is_public=True, owner_email=None): + """ + Reads a CSV file and populates a notepad with notes. + CSV Format: title, content, lat, lng + """ + if not os.path.exists(csv_file): + print(f"Error: File '{csv_file}' not found.") + return + + with app.app_context(): + # 1. Resolve Owner (Optional) + user_id = None + if owner_email: + user = User.query.filter_by(email=owner_email).first() + if user: + user_id = user.id + else: + print(f"Warning: User with email '{owner_email}' not found. Notepad will be unowned.") + + # 2. Find or Create Notepad + notepad = Notepad.query.filter_by(name=notepad_name).first() + if not notepad: + print(f"Creating new notepad: '{notepad_name}'") + notepad = Notepad(name=notepad_name, is_public=is_public, user_id=user_id) + db.session.add(notepad) + db.session.commit() + else: + print(f"Using existing notepad: '{notepad.name}' (ID: {notepad.id})") + + # 3. Read CSV and Create Notes + try: + with open(csv_file, 'r', encoding='utf-8') as f: + reader = csv.DictReader(f) + count = 0 + for row in reader: + # Basic validation + if not all(k in row for k in ('title', 'content', 'lat', 'lng')): + print(f"Skipping invalid row: {row}") + continue + + try: + note = Note( + title=row['title'], + content=row['content'], + lat=float(row['lat']), + lng=float(row['lng']), + notepad_id=notepad.id + ) + db.session.add(note) + count += 1 + except ValueError: + print(f"Invalid coordinates in row: {row['title']}") + continue + + db.session.commit() + print(f"Success! Added {count} notes to '{notepad_name}'.") + + except Exception as e: + print(f"An error occurred: {e}") + db.session.rollback() + +if __name__ == "__main__": + if len(sys.argv) < 3: + print("Usage: python seed_notes.py [owner_email]") + sys.exit(1) + + csv_path = sys.argv[1] + pad_name = sys.argv[2] + owner = sys.argv[3] if len(sys.argv) > 3 else None + + seed_from_csv(csv_path, pad_name, is_public=True, owner_email=owner) \ No newline at end of file diff --git a/static/about.html b/static/about.html new file mode 100644 index 0000000..7863678 --- /dev/null +++ b/static/about.html @@ -0,0 +1,88 @@ + + + + + + About - SpotNotes.app + + + + + + + + + +
+ SpotNotes.app + +

About SpotNotes.app

+

+ SpotNotes is a unique location-based digital notepad designed to help you connect with the world around you. + Unlike traditional note-taking apps, SpotNotes allows you to pin your thoughts, reminders, and discoveries to specific coordinates on a map. +

+ +

+ Whether you are marking a hidden hiking trail, leaving a review for a local coffee shop, or just jotting down a memory at a specific spot, + SpotNotes gives your notes a place in the real world. +

+ +
+ +

Key Features

+
+
+

📍 Location-Based Notes

+

Create notes that are tied to exact map coordinates. View them in context with the surrounding area.

+
+
+

🌍 Public & Private Notepads

+

Organize your notes into notepads. Keep them private for personal use or make them public to share with the community.

+
+
+

❤️ Favorites

+

Found a notepad you like? Add it to your favorites for quick and easy access later.

+
+
+

🛡️ Community Driven

+

Help keep the map clean by reporting inappropriate content. We believe in a safe and useful environment for everyone.

+
+
+ +
+ +

Frequently Asked Questions

+ +
+

Is SpotNotes free to use?

+

Yes, SpotNotes is completely free. You can create unlimited notes and notepads.

+
+ +
+

Do I need an account to view notes?

+

No, you can explore public notes and the Global Public Feed without an account. However, you will need to register to create your own notes.

+
+ +
+

Can I collaborate on notepads?

+

Currently, public notepads can be viewed and edited by anyone.

+
+ + +
+ + + + \ No newline at end of file diff --git a/static/admin.html b/static/admin.html new file mode 100644 index 0000000..21366fe --- /dev/null +++ b/static/admin.html @@ -0,0 +1,48 @@ + + + + + + Admin Panel - SpotNotes.app + + + + + + +
+

Admin Panel

+ + +
+ +
+ +
+

+ Users ▼ +

+ +
+

Loading users...

+
+
+ +
+

Notepads ▼

+
+

Select a user to see their notepads.

+
+
+ +
+

Notes ▼

+
+

Select a notepad to see its notes.

+
+
+
+ + + + \ No newline at end of file diff --git a/static/assets/css/admin.css b/static/assets/css/admin.css new file mode 100644 index 0000000..122f50c --- /dev/null +++ b/static/assets/css/admin.css @@ -0,0 +1,102 @@ +/* Admin-specific styles */ +.admin-button { + background-color: #dc3545; /* Reddish for danger actions */ + color: white; + border: none; + padding: 5px 10px; + margin: 5px; + border-radius: 4px; + cursor: pointer; +} + +.admin-button:hover { + background-color: #c82333; +} + +.user-item { + padding: 10px; + border-bottom: 1px solid #eee; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; +} + +.admin-section { + margin-bottom: 20px; + border: 1px solid #ddd; + border-radius: 5px; + overflow: hidden; + background: #fff; +} + +.section-title { + background-color: #f8f9fa; + padding: 10px 15px; + margin: 0; + font-size: 1.1rem; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; +} + +.section-title:hover { + background-color: #e9ecef; +} + +.section-content { + padding: 15px; + display: block; /* Default open */ +} + +.section-content.collapsed { + display: none; +} + +/* Stats Dashboard */ +.stats-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 15px; + margin-bottom: 20px; +} + +.stat-card { + background: #fff; + border: 1px solid #ddd; + border-radius: 5px; + padding: 20px; + text-align: center; + box-shadow: 0 2px 4px rgba(0,0,0,0.05); +} + +.stat-card h3 { + margin: 0; + font-size: 2rem; + color: #007bff; +} + +.stat-card p { + margin: 5px 0 0; + color: #666; + text-transform: uppercase; + font-size: 0.8rem; + font-weight: bold; +} + +/* Fix for layout clipping when content is tall */ +body.page-body { + align-items: flex-start; +} + +.content-container { + margin-top: 50px; + margin-bottom: 50px; +} + +/* Scrollable lists to prevent page from expanding too much */ +.section-content { + max-height: 60vh; + overflow-y: auto; +} \ No newline at end of file diff --git a/static/assets/css/auth.css b/static/assets/css/auth.css new file mode 100644 index 0000000..645356d --- /dev/null +++ b/static/assets/css/auth.css @@ -0,0 +1,37 @@ +/* Auth & Content Containers */ +.auth-container, .content-container { + background: white; + padding: 2rem; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + width: 100%; + margin: 20px; +} + +.auth-container { max-width: 400px; } +.content-container { max-width: 800px; margin-top: 20px; } + +/* Forms */ +.form-group { margin-bottom: 1rem; } + +.form-group label { + display: block; + margin-bottom: 0.5rem; + color: #333; + font-weight: 500; +} + +.form-group input { + width: 100%; + padding: 0.75rem; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 16px; /* Mobile friendly */ +} + +.links { margin-top: 1rem; text-align: center; font-size: 0.9rem; } +.links a { color: #007bff; text-decoration: none; } +.links a:hover { text-decoration: underline; } + +/* Ensure buttons on content pages are white */ +.content-container .btn { color: white; } \ No newline at end of file diff --git a/static/assets/css/base.css b/static/assets/css/base.css new file mode 100644 index 0000000..ec290c0 --- /dev/null +++ b/static/assets/css/base.css @@ -0,0 +1,40 @@ +/* Reset and Base Styles */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body, html { + height: 100%; + width: 100%; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + overflow: hidden; +} + +body.page-body { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background: #f4f4f4; + overflow: auto; +} + +/* Generic Components */ +.btn { + width: 100%; + padding: 0.75rem; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + transition: opacity 0.2s; +} +.btn:hover { opacity: 0.9; } +.btn-primary { background: #007bff; } +.btn-success { background: #28a745; } +.btn-secondary { background: #6c757d; margin-top: 10px; } + +.hidden { display: none !important; } \ No newline at end of file diff --git a/static/assets/css/map.css b/static/assets/css/map.css new file mode 100644 index 0000000..b696f4d --- /dev/null +++ b/static/assets/css/map.css @@ -0,0 +1,99 @@ +/* Map Container */ +#map { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; +} + +/* Map Crosshair */ +#map-crosshair { + position: absolute; + top: 50%; + left: 50%; + width: 20px; + height: 20px; + transform: translate(-50%, -50%); + pointer-events: none; + z-index: 900; +} +#map-crosshair::before, #map-crosshair::after { + content: ''; + position: absolute; + background: rgba(0,0,0,0.6); +} +#map-crosshair::before { top: 9px; left: 0; width: 20px; height: 2px; } +#map-crosshair::after { top: 0; left: 9px; width: 2px; height: 20px; } + +/* Map Note Card (Zoomed In) */ +.map-note-card { + background: white; + padding: 8px; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); + width: 200px; + font-size: 0.85rem; + border: 1px solid #ddd; + white-space: normal; + user-select: none; +} + +/* Move Leaflet controls down so they aren't covered by the navbar */ +.leaflet-top { + top: 50px; /* Matches navbar height */ +} + +@media (max-width: 600px) { + .leaflet-top { + top: 110px; /* Matches mobile navbar height */ + } +} + +/* Note Buttons */ +.btn-note-share { + background-color: #6bbbf7; /* Blue */ + color: black; + border: none; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.75rem; + cursor: pointer; + margin-top: 5px; + margin-right: 5px; +} + +.btn-note-report { + background-color: #ffcccc; /* Light red */ + color: black; + border: none; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.75rem; + cursor: pointer; + margin-top: 5px; +} + +.btn-note-delete { + background-color: #ffcccc; /* Light red */ + color: black; + border: none; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.75rem; + cursor: pointer; + margin-top: 5px; +} + +.btn-note-edit { + background-color: #cce5ff; /* Light blue */ + color: black; + border: none; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.75rem; + cursor: pointer; + margin-top: 5px; + margin-right: 5px; +} \ No newline at end of file diff --git a/static/assets/css/modals.css b/static/assets/css/modals.css new file mode 100644 index 0000000..4910623 --- /dev/null +++ b/static/assets/css/modals.css @@ -0,0 +1,33 @@ +/* Modals */ +.modal { + position: fixed; + top: 0; left: 0; width: 100%; height: 100%; + background: rgba(0,0,0,0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 2000; + backdrop-filter: blur(2px); +} + +.modal.hidden { display: none; } + +.modal-content { + background: white; + padding: 25px; + border-radius: 8px; + width: 90%; + max-width: 400px; + position: relative; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); +} + +.close-modal { + position: absolute; + top: 10px; right: 15px; + font-size: 1.5rem; + cursor: pointer; + color: #aaa; + transition: color 0.2s; +} +.close-modal:hover { color: #333; } \ No newline at end of file diff --git a/static/assets/css/navbar.css b/static/assets/css/navbar.css new file mode 100644 index 0000000..721ea02 --- /dev/null +++ b/static/assets/css/navbar.css @@ -0,0 +1,94 @@ +/* Top Navigation Bar */ +.navbar { + position: relative; + top: 0; + left: 0; + width: 100%; + height: 50px; + background-color: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(5px); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 15px; + z-index: 1000; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); + flex-shrink: 0 +} + +.brand { + font-weight: bold; + font-size: 1.2rem; + color: #333; + text-decoration: none; + flex: 1; + display: flex; + justify-content: flex-start; +} + +.nav-links { + flex: 1; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 15px; +} + +.nav-links a { + text-decoration: none; + color: #555; + font-size: 0.9rem; + transition: color 0.2s; + white-space: nowrap; +} + +.nav-links a:hover { color: #000; } + +/* Search Bar in Navbar */ +.nav-search { + flex: 0 1 400px; + margin: 0 15px; + display: flex; + justify-content: center; +} +.nav-search input { + width: 100%; + padding: 8px 10px; + border: 1px solid #ccc; + border-radius: 4px 0 0 4px; + outline: none; + font-size: 16px; /* Prevents zoom on iOS */ +} +.nav-search button { + padding: 5px 12px; + border: 1px solid #ccc; + border-left: none; + background: #f8f9fa; + border-radius: 0 4px 4px 0; + cursor: pointer; +} +.nav-search button:hover { background: #e2e6ea; } + +/* Mobile Navbar */ +@media (max-width: 600px) { + .navbar { + flex-wrap: wrap; + height: auto; + padding: 10px; + gap: 10px; + } + .brand { + flex: 1; + order: 1; + } + .nav-links { + flex: initial; + order: 2; + } + .nav-search { + flex: 1 1 100%; + order: 3; + margin: 0; + max-width: none; + } +} \ No newline at end of file diff --git a/static/assets/css/sidebar.css b/static/assets/css/sidebar.css new file mode 100644 index 0000000..96f8463 --- /dev/null +++ b/static/assets/css/sidebar.css @@ -0,0 +1,167 @@ +/* Right Collapsible Sidebar */ +.sidebar { + position: absolute; + top: 50px; /* Below navbar */ + right: 0; + bottom: 0; + width: 320px; + background-color: white; + z-index: 1000; + box-shadow: -2px 0 5px rgba(0,0,0,0.1); + transition: transform 0.3s ease-in-out; + display: flex; + flex-direction: column; +} + +.sidebar.collapsed { + transform: translateX(320px); +} + +/* Toggle Button attached to sidebar */ +.sidebar-toggle { + position: absolute; + left: -40px; + top: 10px; + width: 40px; + height: 40px; + background-color: white; + border: none; + border-radius: 5px 0 0 5px; + box-shadow: -2px 0 5px rgba(0,0,0,0.1); + cursor: pointer; + font-weight: bold; + color: #555; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; +} + +.sidebar-content { + padding: 0; + overflow: hidden; + flex: 1; + display: flex; + flex-direction: column; +} + +.sidebar-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px; + border-bottom: 1px solid #eee; + background: #fff; + flex-shrink: 0; +} + +#sidebar-body { + flex: 1; + overflow-y: auto; + min-height: 0; +} + +.btn-new-pad { + background-color: #007bff; + color: white; + border: none; + width: 30px; + height: 30px; + border-radius: 50%; + cursor: pointer; + font-size: 1.2rem; + line-height: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.btn-center-location { + width: calc(100% - 30px); + margin: 15px; + padding: 10px; + background-color: #17a2b8; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: bold; + flex-shrink: 0; +} +.btn-center-location:hover { background-color: #138496; } + +.btn-add-note { + background-color: #28a745; + color: white; + border: none; + padding: 5px 10px; + border-radius: 4px; + font-size: 0.8rem; + cursor: pointer; +} +.btn-add-note:hover { background-color: #218838; } + +/* Sidebar Lists & Items */ +.list-section { border-bottom: 1px solid #f0f0f0; } + +.list-section-header, +.btn-toggle-section { + width: 100%; + text-align: left; + background: #fff; + border: none; + padding: 12px 15px; + cursor: pointer; + font-weight: 600; + font-size: 0.85rem; + color: #555; + text-transform: uppercase; + letter-spacing: 0.5px; + margin: 0; + transition: background-color 0.2s; +} +.list-section-header:hover, +.btn-toggle-section:hover { + background-color: #f8f9fa; + color: #333; +} + +.notepad-item, .sidebar-note-item { + padding: 10px 15px; + border-bottom: 1px solid #eee; + cursor: pointer; +} +.notepad-item:hover, .sidebar-note-item:hover { + background-color: #fafafa; +} + +/* Collaborator List in Share Modal */ +.collaborator-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; + border-bottom: 1px solid #f0f0f0; +} +.collaborator-item:last-child { + border-bottom: none; +} +.collaborator-item button { + background: none; + border: none; + color: #dc3545; + cursor: pointer; + font-size: 0.8rem; +} + +/* Mobile Sidebar */ +@media (max-width: 600px) { + .sidebar { + width: 85%; + max-width: 350px; + top: 110px; /* Adjust for taller mobile navbar */ + } + .sidebar.collapsed { + transform: translateX(100%); + } +} \ No newline at end of file diff --git a/static/assets/css/styles.css b/static/assets/css/styles.css new file mode 100644 index 0000000..6896780 --- /dev/null +++ b/static/assets/css/styles.css @@ -0,0 +1,339 @@ +/* Reset and Base Styles */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body, html { + height: 100%; + width: 100%; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + overflow: hidden; /* Prevent scrollbars, map handles panning */ +} + +/* Map Container */ +#map { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; +} + +/* Map Crosshair */ +#map-crosshair { + position: absolute; + top: 50%; + left: 50%; + width: 20px; + height: 20px; + transform: translate(-50%, -50%); + pointer-events: none; + z-index: 900; +} +#map-crosshair::before, #map-crosshair::after { + content: ''; + position: absolute; + background: rgba(0,0,0,0.6); +} +#map-crosshair::before { top: 9px; left: 0; width: 20px; height: 2px; } +#map-crosshair::after { top: 0; left: 9px; width: 2px; height: 20px; } + +/* Top Navigation Bar */ +.navbar { + position: relative; + top: 0; + left: 0; + width: 100%; + height: 40px; + background-color: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(5px); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 20px; + z-index: 1000; /* Above map */ + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +.brand { + font-weight: bold; + font-size: 1.2rem; + color: #333; + text-decoration: none; +} + +.nav-links a { + text-decoration: none; + color: #555; + margin-left: 20px; + font-size: 0.9rem; + transition: color 0.2s; +} + +.nav-links a:hover { + color: #000; +} + +/* Search Bar in Navbar */ +.nav-search { + flex: 1; + margin: 0 20px; + display: flex; + max-width: 400px; +} +.nav-search input { + width: 100%; + padding: 5px 10px; + border: 1px solid #ccc; + border-radius: 4px 0 0 4px; + outline: none; +} +.nav-search button { + padding: 5px 10px; + border: 1px solid #ccc; + border-left: none; + background: #f8f9fa; + border-radius: 0 4px 4px 0; + cursor: pointer; +} +.nav-search button:hover { + background: #e2e6ea; +} + +/* Right Collapsible Sidebar */ +.sidebar { + position: absolute; + top: 60px; /* Below navbar */ + right: 0; + bottom: 0; + width: 300px; + background-color: white; + z-index: 1000; + box-shadow: -2px 0 5px rgba(0,0,0,0.1); + transition: transform 0.3s ease-in-out; + display: flex; + flex-direction: column; +} + +.sidebar.collapsed { + transform: translateX(300px); +} + +/* Toggle Button attached to sidebar */ +.sidebar-toggle { + position: absolute; + left: -40px; + top: 10px; + width: 40px; + height: 40px; + background-color: white; + border: none; + border-radius: 5px 0 0 5px; + box-shadow: -2px 0 5px rgba(0,0,0,0.1); + cursor: pointer; + font-weight: bold; + color: #555; +} + +.sidebar-content { + padding: 20px; + overflow-y: auto; + flex: 1; +} + +.sidebar-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +.btn-new-pad { + background-color: #007bff; + color: white; + border: none; + width: 30px; + height: 30px; + border-radius: 50%; + cursor: pointer; + font-size: 1.2rem; + line-height: 1; +} + +/* Center Location Button */ +.btn-center-location { + width: 100%; + padding: 10px; + margin-bottom: 15px; + background-color: #17a2b8; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: bold; +} +.btn-center-location:hover { background-color: #138496; } + +/* Add Note Button (Themed) */ +.btn-add-note { + background-color: #28a745; + color: white; + border: none; + padding: 5px 10px; + border-radius: 4px; + font-size: 0.8rem; + cursor: pointer; +} +.btn-add-note:hover { background-color: #218838; } + +/* --- Auth & Content Page Styles --- */ + +/* Use this class on body for login/register/about pages */ +body.page-body { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background: #f4f4f4; + overflow: auto; /* Allow scrolling */ +} + +.auth-container, .content-container { + background: white; + padding: 2rem; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + width: 100%; +} + +.auth-container { + max-width: 400px; +} + +.content-container { + max-width: 800px; + margin: 20px auto; +} + +.form-group { + margin-bottom: 1rem; +} + +.form-group label { + display: block; + margin-bottom: 0.5rem; + color: #333; +} + +.form-group input { + width: 100%; + padding: 0.5rem; + border: 1px solid #ddd; + border-radius: 4px; +} + +.btn { + width: 100%; + padding: 0.75rem; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; +} +.btn:hover { opacity: 0.9; } +.btn-primary { background: #007bff; } +.btn-success { background: #28a745; } + +.links { margin-top: 1rem; text-align: center; font-size: 0.9rem; } + +/* Ensure buttons on content pages are white */ +.content-container .btn { color: white; } + +/* --- Modals --- */ +.modal { + position: fixed; + top: 0; left: 0; width: 100%; height: 100%; + background: rgba(0,0,0,0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 2000; +} + +.modal.hidden { display: none; } + +.modal-content { + background: white; + padding: 20px; + border-radius: 8px; + width: 90%; + max-width: 400px; + position: relative; +} + +.close-modal { + position: absolute; + top: 10px; right: 15px; + font-size: 1.5rem; + cursor: pointer; + color: #aaa; +} + +.btn-secondary { background: #6c757d; margin-top: 10px; } + +/* Sidebar Note Items */ +.sidebar-note-item { + padding: 10px; + border-bottom: 1px solid #eee; + cursor: pointer; +} +.sidebar-note-item:hover { + background-color: #f9f9f9; +} + +/* Map Note Card (Zoomed In) */ +.map-note-card { + background: white; + padding: 8px; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); + width: 200px; + font-size: 0.85rem; + border: 1px solid #ddd; + white-space: normal; +} + +/* Sidebar Sections */ +.list-section { + border-bottom: 1px solid #f0f0f0; +} + +.list-section-header, +.btn-toggle-section { + width: 100%; + text-align: left; + background: #fff; + border: none; + padding: 12px 15px; + cursor: pointer; + font-weight: 600; + font-size: 0.85rem; + color: #555; + text-transform: uppercase; + letter-spacing: 0.5px; + margin: 0; + transition: background-color 0.2s; +} +.list-section-header:hover, +.btn-toggle-section:hover { + background-color: #f8f9fa; + color: #333; +} + +.notepad-item:hover { + background-color: #fafafa; +} diff --git a/static/assets/images/spotnotes.png b/static/assets/images/spotnotes.png new file mode 100644 index 0000000000000000000000000000000000000000..469582ad25a42a8203bdc2451bf8c0e432addb05 GIT binary patch literal 208861 zcmZU)1z1#V)Hb^5k`n0-0Yw-}Vt_$FN?K5nMyZi*24`piB?YBZS|wCEM?#Q>LFo{L zp}U7T8{hB$&VR1srO3?edG_HR0Q`5P#Nazy z3AuLQe|Vk`)s=y=ezq0x1);r?juHTTiK95PCIVlRxoJH01OTe~sT+eLn;Vue1TMaEdTyPr&o+o#8 zM0MO$Y#rbl{vNi5{<=ob{T-jn+VCjCD9Pphpx_G5wqDj;e$GxVo=`spo_`BN!QZdm zhVXFxyTr>;fk)};j$Fn%`dlim9=2SvB4WbNMMcHAq-8~{rL3hSWTozKiHnL$LPRAX zV&cN0(ojhmsJH~z|NP+r??)!@VPgkI;>r7OjsF(8Z|nKo1McPpcXi>qTGaZPtGAZ|54hj| z4&vd@h+x@@$|Nq?O>XZL&1Czh{9jfO6w*^mewOyE)JmmlPo;>905dYVq zVE?@X%IZo_kpETG)vNziwyleef`G4pB8>3kR~-O257oS{WaMYDe(syWr|v&XcFEII zRfCycuoq>zMoi$!Xx!3sV3sz0Q&r&Y2f^1owp$hk;UB!_n-Yp&S{iKTKk?=g+y+N#k}dZR)6$2l$SQ#}}c>Z4!gzsw(rNW?7udJXB3`VSJQ+Xhcu6x= ziYh5WxGIV3evpR@QfgePfY*+B=Pyjjf9)g8bvGIM^WIaJ2AcRdV>X1#i`b)-o-o%m z{vv{lG^FB_MrWPuL{-y7m6?)5xR1AX7284x*GR7UMjRLE!CS{lF4F0+eP;0HVdkpP zfxe;GjbE|0_ham1Txn$D@8&EoxASp(tx+iAK)ep;c}u_K}!GdsloWH zQ78*k{E97-yQnb<{M3aIAdUHg!P;HV{K}z>9gNvH*5&M!tBUbi^#pf4xo*T-ZJjaBi1Xoj(F_o?1Pr?AHmJsLu5 zfw2cT&2bkLs7z~W9(L@8bEw*?)WaX0kJrdrA3Id?YWCdqh~^iTF5P^*3M%I%U*@-i zu@?%upOSbh<0=ndUPIFXoA}%OK#l2_#(_8UM2_Ro9=Jd*{Y(@fh4;>>mT*oyXbazu z7X1y#`l5{bHX;{0c`$8SH}zOVizaL)&qA)|k;#9r2$hx%4o!+`-p`KK+{uQ-sC7#} zRHLbWz{{>?@xxbpS3JW`)z6}EW*31_qA}5G@{Gr9?q+QKW~^3klJa9h;{g#)$236_ zz$SrPJmaRv8=&9R;QSG*MU4+8)`vP>-frd4xsZcpO!}Q&H+cxxx>QVcL`;&Wq^ZS~ zeLi0=(DnQ_Ta~(d&|NKONyAc*+HWmk%YLxxrj+yc`Q-bO8Yd+hpJcWEA%EM|MQIhG z%u4jM zCg!8Ad0x+-#o=~Wi=?Cl1lNfq1U^pHoZ-Jnq~t(-X7*XVY4>3F*2Zlir%V71lUqFt zqaT)EN}k!{Bj*t_;+lU=esM|+yN5$= z9~)rDycaRuq#=VaB=(L#skRA+NxUAs@bjENNhv$Qb^tI-J!b*nHhPp3yD3&2aL+Jn zKpEaKanJy8d_9PA;ES279A>xqD~z+iB7o(}yOdp9Co9xSo|I3YWc(){1&wlVpBfy> z50y1@>;GKmB{jLy_3P6oh0fS=sulyRZS_Llwzs=XpouwXBYMNK$$x#1cTup|^5}t4 z!O4<_(VUH~ip<$FYk(7P8xIKOvvi>D0bmq!hCco&Jw7uB`Nl3lnt*5Mj#kcuW0l@6bNwZ^(Yv3wjU|zGoQvn!v zny6i~S#m8h^O37qTfd37fAv0$?_Q~pdPs|X#;#fG;nU4oUFfYD4e&GHksd}uKCeS0 zj0&=#CBPn9_W7B6+SYJ05{rdJ3=E7?lPwY|MJ~wsuD&%YGEmf$Lk4Uvz#o`!6s3NB zNkqg&Vnq!4`~`lHFJ9Mnh_bpq-u7MKa;U#9fB^lhwF#A+%t#%oOQ@3LRcg~Vn9VVsq$t*Et&nF z_wB*cu(CJSDu!)uvL{wj3Bb*fJ-a7tWdSD4N@G#mo}Xxu-bk3=SzjUR&dKhrgWVyk zREzdeemel!JHdNM^g$fI>7_B@HhxeMaOR79h>=8&KAm;{vsWj3>J8I9PSzObd1B$doOeL48e_MPt^T8q_ z7TZuM=d$W8k6J`zBo%Z9@_HjOT1SVTgsUh%p&?Z4%i?X6*OQ*tdLwW$+`T7RWC1H0 z-<>9QmfJfl$mJy1rUuq|5z4+`jA$X=mID}o&tIOWbC67U>MX8Erri<(<<#pfRq}aY zYfb1F*(^EW$#=qjuuF86Lh>h}Eq!IK4-uPs4-8u%{cVp=5{BPZ%1g#W_K9P>=KPqm z3Xh@hZx^UM*kfyySNIK|_^ud%H8kTWO$>KE2lb0tmYo;sM9FXL-K-LLm*1E#6M^0F zV(ELg!Qf{)PBPa71hnfecmyp{G_{EbxlX=ay<|sg-LZTb8)sKu^)G%__&O|2tO`v= zLP`Vw?41nDLw{a&}w}yCI4(a?Fvf*fm+)+#VzMu)q z(#=c#nn|_cdJXWS2(lz{lNJ)#hj9l%@Qy9ly+qdzjf*%-7|GbH==*1+%e#kju)LR6|xH(xl#^F*P3N7r>j#`!oA*9_S|i zp=wa4#%mj*!wc=BEBOu&K?$}%X1{};tGn{mF9TPs7?bZ!N0|Fy7}0tTUs2l~M#?)$ z_G93Pm_er#-L|TzPT))?C=TB*6HZiNf`Vs+HCKi~fU6 z#}m<#!`%Yr7|bad9A?Q8v**3@UNi5l_?0IoV<_1t{nt{G2KI_cJ5iEZ45!GLzdNEE zo~#D~1`x|-_EqmOKbW2;=Rgs=*5a-7r9A8F&Ef~Er@Lkuc7og~4F@#|5ze~LYkP%fL<%u-jR(IWx3Xuo3p+4KNw1|n+&sJ)w5i$w^_`Qj zrik)|AE-1oh$g%G`vmocN;c3J}Lb)&SCy=;l0qOYZvl08ktAo|cf41&sk~d46j4Y86l=|GU$IL}*oCSyXwWp0U=Oy}^#UY@A;jE^(J-XQ(0z za?3mpj6a#GyzCMd;YI9?dBqz$-_K(!EBOyf;yBtGVF!B)!^wy57iy6gPY+gic0(!{ zi+!i|JTnqN6E`JGobL-e0PnW6AokNX>i{ zqtdeKD*K+K;w@baJa?c|#X{uP=JpAq8R9jfHJUfRTN+;NXb1#cLk~o*UKADr{D3t*nJ?m=aUh4Jcvc;}Vjp?xGciH=;0C0&QY9sk_6S`q-xe*)z|su(-3+D4D(2;5EEE9Ls4TQ1W>X zbCAO=ypZEv99OvZ)+i}3iOUOLvvcjSrb*TwuHTnMk0Nn?q;oG}9yGb^aLs15VYsAW z_4`4o6&!HJ3XtI0M7EIV>pw_!{e-_@(2Ydd?tX%$yA)Q%9%j9EaAu$2c*rt1Xkg;F zFxfQS?093NaW!zDxpu_Yxxh3F3m(qRPwwqI7rwvlmT9IB%^CG}WgXJ6?yHMec+6Z) zqK0iF=k37Jd(FKoHJ#iMjx#kG&mZvIQB&qPDoAvw%os%Ed$%JIjfq9_us3U>!(Zh$ zKB;SVFLa6ucgAUExe(6Q{eguBZu#fGpYEdJMa*ak%@KM9lXfBIjDxtym;$Fr|##8r<&D0BO zV=Ee8SJVdYo{D!n*63T9wl2+kJBgU7yCbO9q(yQXzr65inBJ>r8GqGgtv&=?Frfp9 zw!HyIveAyL8BpVu*Jd6cm$gZL#%etn{g!XLQ>!%^g)2^mTv-EcGu5{4P?!ClxO^W< zL{}wC57q3K_Dje$g4XDc&Yyr$_s>rtWKWXk z<$SJp?K0=;A!6te4VU6q>XWycH`ESu15cTV?OfW>!E*X3@?lPwZU>*#^9HPueDDu_ zW>Dn)gxcx!b$zbX#RFTXe)HDTm_6eb1fJulg$n$D;Z2R5fmy2bvj*11nRF+7KMwSz zjiu3>Fi)$7(Pv=lps+MWqt2k~!=PiX*p<%M%W}pUT3-JzvD61`%pja1{ImP^FvH-f z6OkhcXEDZeJ9nR*Nx&yM;LCeM@(}~0cS?=J<8?nl4VxE_p?>nE8v#q~=zOX?IsRJE zKzz?UkO3BP<)P)eyo3J8NjK0im1`bujV+xt`|t?IbtWR^OYy?UF8mL`%QM2^?hme_ zW#Fe;A4fLy5y7!4;9DWi9@lL{Yva*%<5bLjl#Z!oO_-^9Bfw^tKtJ`f*n6=Lbr1D@ zOpssXsuR2Dvs(EL$2CWN5?;j5K7hPC>uC;h} z(r4xgR;miCnMd-ozQRkRt}kGgc?|x@iErAo&_U6k$^VlfsO&$5jQErs)yZd5ILcqi zVhW4^VIGzo2X%|5-9u-5*-^MwKF*szXRm?c(AW9|H9*SBZy+Z&d-7vBwgkazPDKV@ zTTuBn)_NSoa?XmGl~c(tqGpR`>bKAMu7o13za_JDq6z0XMNZHaCH?jN9hqV=;CG%c zNy)Am@LvvjYG&#!7i3AY%>X=oT)3dG1ib&rZOVl1az1+Y_ZY=A7Ks1qXPaR3Mnv~w zZb-B*OOnMs6@tfB)II5f)Ag_WUOA4XG)4XrDz`cr)-rAg;HZBXQf3q_Iy-#_@0dKu z63?yYbgJ%Nc}pow5k!$@tC?H!*@Y)n=|4~_l6$Y0VA*@PqzzL>%dQ2@|3R8owdfHS zmJ@l4a0+|*GUF-GsftqRzN4PW9PN1JAx4h2{Xe@V-c+eY4^9)}Z_GT~#3>2=RQ8%&&D0T9)3p6I4kdV!?lPzMJNmz;@ zq;i@~3soEktGNCh$!v(%4@?Y`tE-7MQsMY?SoEj5=C0i8;%I2K1X#7o2VFAXi#?Vj zFTgL>CLX`A-q&G659S&&$(<9bxdalXDk~cCkM8jH`Qn$}rFl&A_<^ACfc45RfiK6a ziJ%vK*QNbtwd5YB*5u2s1q4u{i|~4X$ubV_f|5}{V&#u^9DN?j_aVW}i?oZiah;eun%jqDt1<1U9)}UDwQB?^fT*oA8#?76 z4qyTX?On?}@0(rKHG`G(T~R*GhW4z#Ypm7Z_2Jc8Z}11vn+^zvLK1QB4sNo?jp+42 z70cC=RrjW_^|phxLfH9c@BD3~ZWB^z*@i_n0L~0T5Ooz7&5Qi>QN9*PToGyshg|h^ zXSu>R@BB|R2dh`ifs30#m`s6uAwgV-9=(mI*I!*Wzxg~Sg##w>b6!#pl>Qgl{#SgG zlC8tUw^=`p)gm~gvrqY4VCT$6Z&(MdNtY`o+YiWtqJRs!AicMHBkBp3G+~<{hqQz^ zOY15B)ht=V_kD^HYd!2yyW{N!SARIA4sH=-v_i*!%4PazcMwUDGY&f}f3`?V*ZX_; zdckz(Zo*?=_i)iV@v)4rl*>86@6%Fxr_7M1FZ~mXP`WTlv(AAS8DHK(_|)sQPrrXV z)!Mu|d@N8*p)5IOe5X~jYkRFWHr)wECD)Kduol>XKneW@Vqg?g$UFlO(X0hh5R@}%v0HLYeEj3Pth2Z1yM01DyY zrsJpkW}}CGzPVp}KERR-b3;cJi06tG?2pCoLGwfg{&a8m-_|okB9P~Vxry8C-zI}W zyI`L%(I|X%dy;D5sRu-sK^f4br#i3_H z6=%4xrZ%c5tgE^E56s+a*a~2I3KL$4DtZO;L>RR%{UF-5Q_da$eKMGSI09g+R2&bW zL2C+S2{p`w3<`$QPtfi#mKSm{LtLr9=bVA8iVyW%q?w_* zDbVh5@*q{5Rub!>_0(t7_EG@R!sm7uGnDkV0}wY3O!;n~ApcoOGjfKX3jdf4xa@{$ zZ;=}DM>t(_#WrJ$#1NM+3tYVHz;(ZNA*oo+txAJKdM~M@ZM;7k_r{L zFnwvJn#=8+{EpFt zU3rbxoU~^tzw?QFTp@}louWik9Rtg2l{)%G*OiFW4A?Y04EIwEn#7wTo2$qiwng`& zX6%ccX~SIFUt6vD?5||7S6!rKLJkU>;67Lm4UGkPBqXR4kL}A!NY!T@ijYCs?Q{*s zBIzQR+a+)4XRzz#rWOR-8I+8x(L9cl`_rU`p0N7nk>jJe+&qi4wmrD1A0hgZd=6D@ zS@EfuE0oI;J%ZY5ZJ&1STxO5s#z;F5dDTy}y5w40*qDr)wROM3e%U`YOnG_nU-B^% z_xucMc3tQ9I*?r+f2(i_XncWVZ5$ZX4s5gEZija*yyI)R3a5W6_sRsF$6-n_KQPKJ zT=RFOH}$Tg5g_Tpaj?^9jcXkwXr~%?`%35Xjwn~>^CaR|`BQGx?^reO72Dr%FKj^+ zHG$tXbUKhx!Fv}>`NGO_x2Kz;tg|B57}p)XMoE>g*R32(PyO!kl&*tIxAn)zgPw_k z$MQRKtVgxYlFv!6w;fKa+#*b6BY%!zYT46~Im=RvnCgNNrc%A!Dw$J_pbuN*NwN$i zf6}~fS>eCoeZ#d+`AIhqc*2U&k}=Dn3s}%>74N84{?Dyl8=*;RZPGQBXe|ef4lVfeG{{Y@gLW&SW!86kw@LM?o)2w7q6PS z(&#akfZOj_6H9K-PjaziB>EBn#~12sVhxb5Z_@b*LpC@N9qjqAlspxx92h?g8>s4c z^-Db4TuPd~wkO$yw*&`0yV>iy3UDD6)MCR~xkdhfNMDHwZ6SBfU;yk$j*~JG*<9InK%|Cu_7dQn?7Iji$B$-fAi-rHlk#ujIBZVC z{b+N0hM?`cth3*zd|{!ivllns2vIafa*?)L{7E{epQ>3`!FdAB@S@LNsPM{_rPTv& zhivqyqQ)v~j&9bKSq4|0@{2elBnQCim-X&#j|NfUX7(NeCK9*qSY^c*>c4cqFba@| zSdngY4XetPwmo81bQ;LjJRt)6L`j3>OPe=Q?|^mgH733jgS^U>B$zi1f&u{oN_*z=!rBtIJusDYjdjP<#kLAC?0^X^ zYK(jZY-*IVoBO06*sq^bgy?gs&Pc@9U_XK1zRoPyd5nhxUS>BP)<=xl3e`3=D`fdFQ7%M>NILf2nWzd0$kmzM)`$48fx`&%vSsb<;HYO|h#g7jQn z2i%HMp(yG`#=M&8C@%dmvqm!WTiqF}U{s^We+dzH!ClWqSq+pgRvP?8!1Lc9ES~(I z6NJk-GsjH%eT2GqxWuE}v(Z^Lsl-T;%rA^%5{ClgN8<*|ZHM7wrQnvqGs~&})TKX| z1eyuw?#exwj=8PHYQCiQZl{t}XNlGMhkDw{yvTsIH%SXIEt*1+m`t zFHmtQ0tNY#JVrx<_X?cUJ_gQ%60h6(&{%zq{jr|`D07QNo*+HEFy% zJ~NyAhQ`0t%l^Yh-Kc2#{gC|a_`Uc}REW$0ZnuPVQv$Y|QHYo-=){|%nkxlnY%E3n zd&yVoptI&+P@@Suq#cWx?%b$Cp! z8-Z-u5%ZU=XD56E4)>__^VaVoNYTY8yyNH%Mkm17^+Wde#mVY&fSf2|sn57!m;8Za&HXFs zCI1|EJY)%?mwTA0i&0ilPsmomkzBb~+~5nbY2UpS3RW?ZcXD4cit1$giFVc67J!*+ zb2z*yTlEjvH6-Y%SBJ<(TYTH9fZSrock3r#%@tO`F~PS3v{<|l{Jfphx1`PYQA!ytO&tXOU!kODnhfr_gBU=(z=O{g2N?)qmr z;)47u0WZ%73b}B)UjmyirPW*;IE5IqR1nUx=E~PWs3X#kcPtXb101!BI(zviK*;JG zKoGbO#6+$fuppDO8FppvisUzlYJ$5Fc)et#zeVB(peNVQmXF4URuHtqVB#Xo6<{WE zOQ&zP$D67Qm}&U~r`l*h!@@4@fq=5_7bDgBx6vSc`O}|$oGs>$T_6pqc03B1Qzc^F z*WqXfYZhf1htFmKMD=F#9iXw*zx|xKdysLi%KGZfY6c(JZQ#5b_*mu{W;v*oClOwl z-&ae-)f((%M8G_sK^aF7X{HQl(I8%*`=@k1l@qbOjuQ_;*y3*isg0DL_u}tfa8VQo zF-_C8&M2q*hPhLy+nKnB=*? z*yM*+qTaMPV>Mm3+WZRQf6}`xI|q_S%wB#Y^&k@bH4}FuOl@%Rp0Seq4%Fg|I*?B2 zNxyQ$ZU~s~>(d?q_8a@oknszG4I#b*S~JDqL&jmXDjbq3`ya~W8qWV+DPM8Mx0CUs zPWI1K2PVwxb_%Y2U$SQ+`R%j|RxOYXeUD(aT%y8M<0*HOD?ZcMld9I@Dr+vqYc{7r zPT$|G$?_KWK+s1V)^)d&p1g4%YHTEX_c%C4)oO#dLW<(^4B>Bk9fghhp!l*3E>eZg zy8xI~_=2_oW9?d{CHLF;)OaA6;dJ!1R3>8ntIqGfs(uMm+w{A3JMq8bj05|J z#`+-E*;9gy%k~y^DS(ztSjFqk-2E z#9?4OfGy0+#t6J#mds~}FEOjtA*dbI-SC*Yn38)wTF(1(AMZTzv1qoq^(Eh+G_ehC z-C-Z;E$JWsC2v@wDsNa-V>aDk@>NufcG1ck+Wxi#`bjN2o71K16<>hQ19(ECK?Obh zGedd5-^(sZAYQuseX*xGr%98dSYqrE&b2R^Rw*oht*?R9yMV=~BFU#GRtk4X;D?7! z!1Bw&|BiD7wNTF$O-^4Y9B2Eng=DJwzj#hw4dIokg}hM8BU}9B^OVFPD6bk z+rmGl+x;Ns8@fK9)=mPPkq2?U*kb-n^LJNf|4{K&9_O(vVI9ok9t||Ddx>S{xXH4k z$`!?CUFVQp4|Y4eD5ck6Z(9 zC?Z=qxMN@Bor=Hh1H>6~H|3Ff+^e1?{aeRvbtWSkKq4A|&y*p?JAjhAN8@w7G={6% zhrqa=bP7s+$5QIqQ}>R@t@k<>jz`O^1V3~E5>6uGqx3y3+mG`Iz7LpM3ME2cR_V7k z!PBa|4n0`+&TS}BuFBAkuSokmJ@3b4>E6)lU8uf^G)9v?xlg6`*BW}2axcD2MeTD0 z7&U4D4u!7MYnv=m*W0B?NM$Z-3ZZG2aEKfa3tU+o*|CITE64oW%TFgoXVn zZ!7EYBvfB{Kxhv(@RY`gDr2MU7AZ0Crk!hU3$j)hk0xKO1MkE!d@<}KRPyB7SzoCO zBmFq&MphiW2lh3LY@}(^_2xxb;@THxFym`C!Z?)Dk0fq9>2)}G|LJ#G`bz#AEh)3{ z1JfU}fF8l|0ANvVh#sU}UjxZ!m-Qy7zo{_&k-NjJhBAR?FKwtfZPCzbJUbdqJ(8@OH5{dWL=xtm7?aN-mFK(qi zY=uKc`!%Iyk9Tkh4+1;#!Y`9SDEpw)mobCySw%a#9has&Jj=K634kB#<>MAL&-^uZ zC4c}1^Z?&}s!2$jff&{A^G=)h28SDW1i413@0jB+SSN9<*QBdQvW(OdLt{A8HJt7FwWvH#=KqDy+1HcyW)%QM;D~N5wo*NzS12T-4+r2 zS}xiT=BX%(%4U|GRD?tEcycJF!yc*`L84P+FCwS_R33jOreJQV(yX zrLXKlzUfj`W#6WIKYDZc_=4r>dl|0ED1n;=c=TIQTi9>?Ag}NwkH=9RV(t>_iiIrVx zS@+#TQgK=BsdK6Q7@g-U2U{tKk;&d4JfcS-E1p>5hh?32slbGaR}iE<6Rq2F!Zt81 zrK{cYGt9$9gOqinZ^SY9zYc2yAw4FM#c|dC`dewQB|amnkD!YZ8+KwVhB_u(CErKv9cRFlSA93%ZFs^Mk2h2_EQu-VW$yzXF9lwW?{lQ ze5#g(PPcX31Z#zjlbap8bz3=&GZ(U1QVf0j4@o$rsCOTh z|FkFq3Df?m9%nj?Vw+l_0Q2=QFG~Ue;h3w!VXl3@GCcFA@?98*uNsjT<7qG1Vjt;> zkv;^F!JFd+`T?d{9d2`?C4qGkPGa3gPMQ6%6U0mFG2MlP>H?zNo}Yh%o5`%^!CV87 zila|M*bAB|mIwPM8*MD^Ln{VgUC)FW>AU{0re@Ko*{*!m;Gi_rJ0HFN#A^3_bxwC}xLT>D`np2g3 z6f6Fsn@qVpCj@x4Ly!`%kE=ND9yKtraKN23`4bp7xC9U-a#N2u_J3vpd7Ei8)teQh zh?ifxXPVDH>_PH#WCb=X&rjK*oPBcNOEt_>q);H0uCFeBv(TrG6`hVJPiR${so0^* z+eMJq8GKF+W|O;lgPpp-Ii2|Xs0wL)ml603>9bd~o@dnBslNC|-F5+gGu561br&*k ze5^vKE6tg}?0wF8$EH@0X^gH<>+d8y(P{tSeqDml+LgwpSL0x4!OrEN*2j{S7)``8aq`r%tJC3A3e4IJP4U?7&6l-n$s zhhOh1>7S6YN$8oi#5;@w*od|t%T@K{_strJ6XAG%Oa>89$kPR$%Rv@M9c2>KI>KHgX=2xZ+{QVq4n%_=hR-bqhRaOq8l-#q1yM(eSPS0FIf zs-Wv=s62_Y8*DUA88Jp=hEyEscgshMM5kCL+z5{$eLN%CA`bsn%;9+57%2{3?p11;+vYOAJ2ky5b!>5XKviNd}Ua!D*GNP85fzFM{ zef9OoefIa|q4J_gCYeLsx#h{Al7<)=#=naePiSPw9~%v%!P(TP2wrjLm`OrNCJmHx z8m$YF2HnvaacXG|Kl;?B{2O|W+pw#HdkXM+#>YSC{?p}s+vpsa*Pz*R6}d-7#$Q`p zR`}nwqMO@l_XGl%2|#G_3}PT=Jw3EC{GG<12CU1y_FeYl^cH?Q>ha#GInudi{F4lM?ywsW$|T?!7`D>MF~!z2!O(_xp|y;wYUGTtoX(RQIi zpdk1;3u2GCuwxxa^mc}jGo=t8P7|^DF^ye{iuz2Euk3mlC~2q?*;T@4W#T!@nzhg| zQq#9uztWC)Gj|=1-*V_mXZR4_ul9@=lUVrj%i?pLpdNu8mX}S`Z?J5;=1!Q$X2M-hmbp`)EVvQ zzj${taU!=nC@u1B-;D-4>ZN}d9d8bE{JL(Zw9Mk8q)n{=?t95j-Uo}+()9Gz3r(T*hTnrGeZ_l~D;AL|U+{;X z`4#v{>OKqST31>>N&cC3i{)#m-N)o#tc_OKT%(|i*P*po$ffIYx;$Zlc8%(-(Xm?M z_Vxu6VMo&YUDGJA!vIn&gNmN`p(MIio2df?xtNb8dbV`NQ0iWJeN^BZ-vR$j&?c`t z-@qu6%n{QKmc(!JXD;wS=`rT8d{uDXaalNx7K1RO-N`6QryX8O2tv;k*m!7cmg2fIOSc??8IbfPRDXq!I%*1(reLG*W ze){?Df?-q6>bD`m0n;DCokX9n`F3dZg5-G=d9RVd3HRRhKNU8d?eG15QvK6q`&F>% z(qp@y6EbEfi*Xqg@a6wpEszy%1@V!G+8WhAhirzjE0+N0hMl4w>(`bn&u+Iq!v$1V zOF8bJrs5u!{k*~!&=}BSkv9HKjBi^L8LkMgcamZX0lxOi*#=6}9hq)fe1&qspeJfR z^T$Ig0b6)(0zpHW%kv+jQw>iB(}Q?jL7-jIBo1U?Wy>L)zb|bIFCnOJkl{Gq0SR0+W`YkJQ#4efF-kyY{?dEscugsrR)(j|XZAuYdxYDssh09?OdXlOe@_lfPi<_;KRkwYnFh zfqmwm5Z}Kbdp#S^4FZm1Gksf}cu>vB1am0#mOZnR(DS#hofu~z%)LwaluHr+T3?D~ zaM;b9O1naECs zFE?l&fR|HSEzfE8D&UBgrC`FQe)K8zlkyo_jUuBmpfTQ<5G)Mrmk^&8$oC8txN)V$ zXg;xN#?$CG%Ocv>hY@K}SP>mnFM*HX(*w>xtg+=w19X>|L_yC_YCIK^=s5vW<(K;1 z(NvrYFA9+*PWUwhe7|%Z&6>X0g{qenmpL`>sq>L;eR)$gLy3ZLadz1!{5(J&*@qqBaE^NOsQ{Y?-I2!kQ36aNh zTXvrtn*@Ol{)shL{Lpep#q+)Wfmp6-HkbK_k(qpAd zXAh2=@EfufxclM?W6~aSo4KG#SJ%ERcR{R|mz(rcuf1~?{J0V7 zC>bpP_wpZjy)wx#Tw~f|?&Qhog@H{G8PVjp&eNR!IJDkbPb8g`R7O3=Gj5_{^BcRs zzq>MFwg9#XYQTheaYC$CSVXq!uswfMIO-~G%(r_@L^jAAG{{s{8mt)I!@_Updj@C5 zX>j6ihtUt)PoTc6qyu&wqP)Wbda1G*wkC{9V^1?=eoNcw9(&M^HFjuKaj>V+uA&z1 zS+~dP+s9-@6^9vM4K&!AJ?_#Ev($ijf(F1?{EdjoY4*YN=9Z~geCz{JX?iES;#m|E z%m-q`Z<;BfkOrBS#4i;7vSa+*AjUT{rP=w5{A(ZKnqQT0ORr(r%uOR2E2~RQ8yqo+ zSZi`7y*$dNMYl9r6ztf2Fw!2k$-&2+Dh;$j??Zj4mlzejd%IA}kq4}L7iGSrKifPz za~H_K)aq#$DMRUdQ6c^blms&5b1$7zZmx}akUvK^W6-aU2o?nTC}=@DU>BF&dsxw$ zvXWH>0TwBTA2}1a*!WjlsdvUD27maS!9g7Fb(eYZSL90mP4A~)-i!=r_R?IrVER$U zjVHnL*DLDUwJI6k|C~D}31k4<0Q5@y6kHV>_pBy^Rx3rmFutv?bkvXT%**{P166mJ zPKuxLn|4NNvpTr!Nk6K6;K@1s4P*qCmla6yL74Mx(E0e}HC5l)3J9iA0NN9kG|f%Q zuAbhpKTgOEra`lN2fLB1aJ>aTQ5nLey(XTH8GRg(qNK(rdF?}c*4JQ|DgCSAC!q& zse8xoj`oYcjk-!Sg13t=KHj{OcFXd1`i3h6;Obg(KW0~aQ=;BNtrTBM+plA!YS^5D zzRNGk;d*2KoJLP&kc|Dk@U5x7U*p5->s)rB{V@DY}$8mfKfEVA*$pLQI2fnl8)xEE_X< zU;O%kPG@qo0xs)kg#XpZpf8J9kjRGzLh!{p@M zU-UvV4pwg6Q~E-m?2Xw!lQaHumc_<(*J`KP!P27tfMmg3p6H8-nE8*X1a*}DrqNto z&(8K2WVZViW3>6HdGkrsWQs72Xi2KO5S}UlzpADRO45VW8#>0xouj(dr7wy`T?2M> zo;W0IIM1Fo6uAW3tU?+E43rq2`^vxRtBW#jxcKpyDy`m01aBPAYFBryBE5cQMUb?0 zb5KoeTDp&d^F7EpJSPz`0)tSih*F1_WmgOsY4hh136WX+S)P_uXl8(#pteoqoAAC4 zzM*|k-WH)+9P4*ouzkkU1&jwsY-klYEUCXA8 zobPKoel#N%R@r6eOPix1F6?KSfa={H}w& z>mZ^czb)#Sau~yWZnZV_V3u`qjo_5WfU zFS=`ZW!Fd$%sxtdi2f0hT3^Ecmss8HtSykfE|<)6hU8a?*@vMOkuqSr#KMY|;&!22 zc8qUy%1nh-riBPftR(f|wkgZ4L^ZleNpD=y;;#~uBA4iWq60p1^3-PT=-CsQrL1%L z?lqytu4=NLCF`l&&c2bj*Q400v&;2?MK+9fTA`i4^P|GwInd_dF{w*it5ml32M8;GHy;hS?)_VW$p zc8>o5g#ps!HAqWVM7Z-}R)|76QObw}jZM1V6G5*mpCpnBYIH+s3hdtRZ?-n4y&C(x zu6X=MH3qu(t_c6#dn889>BAtcO1*#Fc_j-et@abP-H8H&;u=+X9!f0aLyGOe7UbYt32;o5 z{I@-%%1po9317OIf-SJ-q$BExrAb<k*MF;L%@3sI_~IqVnM)IeT7d zCt>@a!6G#twc?QV`FW3EG(Jw3peO)XPNW5&a;Yi?mRY6uir3zxsx+BT|Jto*Uaa5p zISH87=Pu*4n!5G7EeDHB=b>qdH!Q#%i0X|zb$m3NI?Q}^K9yd)u zZ{tKjGv=8^x>n&?s1BETs&IQvcl|UE1LqxT{lTSE8%qmGwurI)ePgL-{^YLe9g89* zL(1nu%TQ;h7yR+HrYYYF_2tbI+25uZXzeQdgL;q7^1oJNamw!%((fXHlTmZugBo2 z)hP#9wf0HU4oQPE3ql~bz@WHID(X!g&$@KeM5VyN;#uu+c&a$QOPbk?N;Q?vQftf# zv{Ct?8BJIctxfQEX3z5h2EWZi(kNCzk%8x)e^^?F3l9?L%-0-5_CM;c%Z{UXJb0ao zIBJZhd_N}bJ;_`AIGI!JcGq&!`G#|LnreI)RVm`PrK1CTYwv@WzCdW0?kQVyh{;Q{ zb-7$(LlY=r_KYd~W`0w!70KP>6* z)dN!g*92a8;$=qth2z)hv4M}!sO8(^t&_Nc9f#7CnF$I5Kzj<0&A&I&CG{+exq_Ee zL5H8(hFne5G@VF_anjB3(}or1ny9F)TH7c8Jj_oAuhHN4L-od&y)3floeQsGcS6_S zUeW{Bfi#k5rRikKyoSr_E)MvwzQApE&wV8QD_)gYXg|NFUh;&Ma>8EI0hst*QbLb# zwAOXyZe|m>-8of7Wvc6`c=LLlX^gpx6XwML$DD0^ZT2(66Q;PHZJhZV`%(R(d*?)6 zcge}?{-C<3W3B#llq*LF%l*Vl@p&QcL^Tc-Q9z`e9QBGTbCac6vf#+d!}cmyGPNxC22wJ^i+->fp{1tN_HMG zZ|WE@CZcg64%Y8FL6CczZO#oZVF=)85L!7zoTF zzZJppbrpo}%v>fYB2P>v2VOApS^IQUwx4qDv0>)vHJKhw=cX%+1r z?28l9G$8%WH#i^s1^w zBt8H+Y~L4>u?7B46Ow_aQ;Bor=)c^I4@u#vbd{_?0O@wYowj8kv-_M0SHB- z9nqQrvpfhamE#%FlUP6y-e8CYybQ_Y-`UU?HNnKb_(JhsHLOU3zbyQqF>> zpVHLPZh6Y>RR6=Gec^{vxbRu-nI`gzMV47g=k?$go;?eE z0fG4pt#e7()+OIiX(QS%jx8u!8@wNT6SmPds;k1g?hij)6asNf`>%e8XIm+Uu%(`5 zHIloSrVEb3*jjuHGF+*naw@f(U2w#lqih(nJeC`t`Y6ny`Ma3pYntu)y@c8YPwA&} zC)7A%yg#R;FR(C+bDaT}w_+Ph)7G4mQ0>i9?*tU!6M{MY2gZduY}!4Qn>-_8kM9(7 z1|EV4k_j?9#@k1RCJNH{y-_%N%>b}H7=jI1!9CZjf(=>w4IzogT}wohqRM76J4@2e z@u$s;w@olY7UV)WK<%UVTCD+9D-=N{4LGlIYO1yP7ukOcJE$(O!4)D5TSb)5$pmm3 z%n@1*XaMUZ$jd8pkqkC!ns-TE-9oGv20{=o%d_4!TKW z%(=LDiDmu0gRksy6-y_OV5v`RB>~RswF?@Q&SUCqmU2){g~&$h8+=vu0a0}q&;|H! zt)A$#g@NG*H&d$g``w;-98eok*t6PW_lT_RGH*dq(zrqGT@yYV6PQ5XLSuLqiLJ_W zHA*(-8m&l7R2Tu1b3u;%#wzJw>&5MAHt+lCq^z`uOCQMErC3UxI8D%3pqVhA1W7?Z zKo}Gx4%uL6kyNbd*8KYH&i*ru-FBx{O?MUnJvt8_`MR~G?bF2yP`@j4+e4qvp(9!6 zpx>-5U1wxl4~#OpL*74mn%ikLUGlS?KME;dd_{R=zIaZaR%kN<`Xu%nHs2yT!l4x* zJ7*V3`b;-wW0rd;!%0^1f#c}?L`uvjp~4>U;Q3ozbr$I~41ot_4<(2^5RR`3m)z8o z3dN3cv()y;iKg8*Oqj`q?zvp?21Qf|)_N_%V+`75J zP8aFgSs9F={;`ZTmH<8=ZNTG3x&~k90D&rz40JHWSeyCzkR~>%FnsS}ErRkdNmC&8e!B*^dclm+5LK?2?hkj1 zXB)x)TWL^cAL6<|lY!oNlZHH~<5>wp1tR2>=H^!%A&l7>E9VGHdnDP(SD>~LnXoBR zo%qyzP<5+V_UFvZsHcL@%3EU$HiFV|545LWP^*SFy14J(0()1(oM>y7Tbwi6*2h`rJ?q+68ZIM_W^ME+e|z1k@VH#&ncl$B4sHxS z`Qkvc4!F-XG@pAIY_g}>hw=fP-~Tr5HNF4G5}LCqfhNC9GfQDlhz&Boyl3bJFw|vF z*K4SsKZp+?Md(Su?)fhbq8rrR+>HZppI#rXyJnV{4Sn_@gKaY5$N2+>MQ$+}!WS5i zY$hX^8#MuIRGDLh;R4BtvWUzENCU8+C2!aS2{-7|1AgXsNkJ+p47emAc_bA7jxlTtIDA`n6Rfpr7hZ~JuHEkdEuC@ZaWK9}fenWYc zH=Vt$&7O)j61OeS+Bm64ol$nMmR=knq%f}mmcIc68!XylyS`$BvFVvYh&uN@SGzb=tOgezgFZjja z+QMrsMe$1tZfyA~%n+g4vEcXPY@9=~Uy_(oWS;>aADnEgSVE>wo#8r3?db{N?43wd z))93BLwwP+p~ur9viTJPGm+0SM`~3is{tb0cy$-uD3<;19709;*EoO=bD})#%scL$ zh|p$CyeO0}D~hJ5qntorO``;RiIURP2+GrCre)F0a=BX?C<)&NtEGwE1tFArmzN{ZX8(tGjAco#Gr{WX%FRj*Ks zf#LTu`f-Ea&C^et9)Y43;?iZlr4HL73)Li{yXwNHnxlx7?~HD}CFK+KFu{;37Xa@Y z5T1;G9h>`70a5wvvog=CEr$jpW0OZ)1ZcFnGY7)gRB7DUw)VT5#}%gKWl15K;0$8F zdM$rAfu@pgxTVqr#D|pMU_P93PPdypz9W8_t_bXD%D8}zpac>2*rhV9_t2vy)G#i8 zHI*B8I6+|8j6nR$BicXw=PY_(9A#!VKh=I~GEI@-RB)M5-<=pXMK>gV2sP_;63pcX=PH+Q0Qum$-KxMCk?FuYT^JXn4#vk zV`Pq%L(PsZW0}IXQj<4s;Nc*_-e3D;ZXn2kd=&)Gu$AiRBIevQxlmC-XFkl6vwWv4 ze-znky-u_{_M4Fo9AvHDm?>uZG92kUpcU7is!t56IP}Dr@yg90=t=?;)VOC!xGvIg)u~s02i-$N_#~C=nWwQy_Bc1Iw9Fgh~q19*?ALD z&zV3oPuy9GFe>G*Rw5X{n?nVh@41%^e9rquRA{7zMBI(`h4bacuvV`R)jvKlQq>VK zH>AqJ=(fD-Y!pybVTP21k%aga=GN=t;5X~);$Y^*2RUgM(#oobX&R;??^=on-7J}^ z%@5Gk99Pj+Xh(u@wX=|qXUC<`XAf%tTdvbki%yNmnyn}H-y+`3xEIvQ+BtN8KSXUT z!293`mFguMr1&njCG#ysc>~2P;Jt<9z5-ySCmutg3gS{<2A=$jKwjQtv!6Uj6N2?L zdCT;=7(bB#Apn9mqvt>=n+dKMXN~t5jix;LL3uds`|009eC;#-`5z5}&N4LxTqT->sgu zPw_A4HZrP=g0sezS`88513JA~k~YB=A|()*ckP4^n-0Y|91sB50*}Y34F0DPwjE$^ zaQyZDfXVL<8~{PmQPH9JX!wyPkoWu4l>K6ITxfGvM1z53n&#RG9bGvD8S}XjYVhYZ z!B{h>u}96E)lCa}1G3o@JfVI*3#$Rfg{Y>(AldzVYLM|q!Lp7d&xdQ{#TL z-{LdDBnK7T)#S9eB8N+O_K85GY%9jsZy4!dKa%jNIQvoY;MQ^Htw!w1M3hm5U|Q2` zWl@e5(W>gO%WiCgO(^O4F{7I;WEwpW^v8agVjU29&G`~?7dWZP^}?e}-v_XT2 z%dF)$BY^;lq_Qi9g;9$5WC+%LVT1|bWwfCPk2x%j^n6Peaj*zlkmmu~LKCd_X%PQ4)2}1SX zYJFkwAV26+5D$6cZ;(!ci!BEM@e-UZ4{qZJYLev^ot@o)%7!cj0bVVV2Wx^K#Hlv9 z^%>t*%LbCQ`i2UUsvK_UE7}}z2utY@hQ$Qc(bQ;Zl71Jtw z+=vz;LrTPlYE4sC++P+v;~Y7Zj{kT6u?-8t)L*C9`%YMWjYwqc!i@hxoxS0c*{3br zII3s2a;A|vf2w>YIe+%uTeD$>-$;VsL(Tq>Z6fjm8-oW~%7W3I*~tejE0Wg&Fu4KX zCl3U51RYg=D+Adbx8W*v1*cJ=;IJ9<*lpUw6siE+hm-AQU>mzgTXh|=8yr#q zNqjI+uAXWu{quv+4|C*j)cN~U@ezq?jD2b--9M?LWMw)$g>eV~$fry6DsB1%Am@Qhy3%q;!S6+?{Xjno&C-P>mJxF~Q)>daZlt z6N;oMhk_@m`DaOWC&(Dy`sX=)H|YSrKd8Ffar`n~i2DD(`W z5r;GB24`C{`!FsH2}LP{?E**}G=K@?q@x>A?nGkp_Z_TK4rtBDT!L%N^37M-RM5$%sr|4$)2Jmqvey5 zV3ALJ5?y63pBD+&+ee+p6}yey@fX|`_d{)swrg57Tw5b2r&W4mcujrnKSL+%^g8Z{ z^OO(l-$dl_w zNT)&745d^oKi)z~IGKT8QqSSo{?LpwymMv< za;7+#U*tJxGr)>=YO*n_A!(Rv^~6-CtqRm4DH(ogWcg``^485fd6ST=S&dThUv#@C zD08*J?s zNx($hdp8&Q++%#u`Nx@Xg2}=za^gGI7iV#0aGGDuqnz?+nN$Lr*+m?t!Ph+ym)@og zLmMCLcgh9Vn?{n>z!o15SQHtcc3raD;D9#!sHt(^=j^67y>soJlKMx42Y;w!J*MV+Y z7wJ)ws3*nFoQy3jdB4D2D1Li6OB$kiVaE{}qO5MA>`!87L8sH=%r8z5 zw(jBuk;wpxA`@IZR7+qNfLf(a=gmp)^sYna{Rk*n&tNBNn0Kb{AW>h^Q}PshugAnf z1ua*RW{$;2?DwV&5fSJFH8=|CTHW5t%FqZ*AQRd1Vp(CyI1RdGAqQ_$w#Ob?E`1zh z>~Fqo)GI(aF(wM7RTN1xuG@7fqu)=s{zBXBh?uAb#yCS`StNoRpmI3b z{3rCf5ZHD8A@;9`1gh+BT&UeO9VwEQ-e_bppQzZ!YST%5?k3aN@$iZ-ldv>ARSOQ{ zCI2Dz3kzZ+r!$Pq*V%92%f}zx+%tUJ)P9Yx3We(kE#a0qXUjV88~PA7zjg;U|9Us? z^X-<>Ba|{j%P~(bFCTf#(-d%s3d3iICCf`>JCU#UfdJ;ov@YL2^eHEZGstrW2x@J1 z^Ohmt42L6mBCLLb&JnS{n`to;cVpCtvTZjMN3f%Zu)3n6|9X|0ArlMzNaY9QyZ2;F z9`H<_X&&gNRQlL5!DB|ZpEtU3{bcl^Y18=Jj!#;Vo31GL{H0^-DOxaR!i!PzQVJpu z4IGlFa_%NB0g{tsuCCGJwefl=*&qfpKQwl76XsMRlH>{-ocD~UEK$8BuKMJJ=`QY6 zeHwDUCV9qKjBSy_q$Dwz1dJCGer|$Ey3w=RH?{ZULES8EKVNgakSe!_WNDLcZ~#2QJ;#=*#cBy z*tL72^L}%Gx^=ePz01!Ar&LwVCc&c&M^pzBWmkau&68NeefGKSe2)8Sf{YW!#5BQk zKuHUBZr?9>UW=23m_AW4$fChZYi%liu~xLcgho&P0HTx zx#b6Or$R#V8Mzyyps}NsL-~cMt+;UxBt2$+lG&w)LD-q_g*yI;TZL(1PaUpzoFaN_ zLE@s^ATG-3fv+omxWegh1svZ=o#(#B#xD4V3j~n0+mi%|j)+(40>K6s82v?e zl=M;kZfSFVaqW2^!Yq;1omfgJGDZgQ4S(*j^i8+%6x+0EABGZ71K*ZHeuJ=i9u^>& zZ@M^DXpogfl@T<=T5#iB)Vgkw2L$`ps4075KrMXXWBNvUnG*VHK}lA`z7&*aYO)Uu zz&R0Vcx}K>hNF^Coy-w7S6qWovx5Mdy*gedjx$lvs%JqSNDLCJd$%yASI9Nt(I;R$M?MsdLrK{3a zDB_{BXft}-X)su>XA5)IN<43V#%Z|DDo4a5QQZC%R_Eo!x2xIChhP|)v-H6$R=OZ+ zH%;CCG=zs9 zVcdJajRUy}!ammDevR=5k3N*1#S;STTP$fLQGrM~bj=1IcuLVRV|Q}rl$JXBEwavgBOKT%H2 zRizIY8MYq(y&z@2R=yF4>ux-3r z`A-GHPvI9%ZIXKKq@0N+E+-v?re`DN*yI#G#8<59vPW~(WAmhub#1!6eG1UY+_z4t z=iV6N9Q>7AQ~+Qi7&{`}m51YuIVsZvM<9y`Vh~xx_2;Q>T}xo_9&_eV@SO5KWP9QA zBemEaynaE2lvsx&@(kEV;FZ&W!x_gXe;8`?+xiW%?Sxm-WX*c~i<*L~igL33IVgjQ z9y-zvLjTPi&~}cm@=%8Q_t4z~sc(n0i2K%xSz}L8{zVMGi5Odz_sQ2M)bM+z7q8~oH_A=fC7rInQto-GaM1H(G zo34zGq}y(3fTv9}jjaI81U8m4I>KB4;Vz+weF{}T=J$>Tnckd^4fsj#c zPVHMJg9C{3!EtE+>4VimH`sW!g;s`bM+)+8n9t+;Afr6;kC6GT2a0ctNTT z?iT};{@Z@n(#;%kRuB9;{hmr84MgMx`2~9>V@#;Xm)t@1CdxfMUzaWJf3G#p^!Hey z*uQFh&Uf9DvK-%KD?K}d;&xq~^yPKn#_~XBjF+Ab*$f}H5kdm|I>8Ds4$O>EY|BGKVyyS%vTg{PnQnC^=l6b`PV79q_JF$zS z;`0NA(-{(ZtV;9|blj=Gk>aH)VXA%Zow2r8(#HsT_b?q#ecyx&RM~d5qCj2QhP_uz z2m$9^{?LSp(z}=E=jY&B^YJm-g5s{6L}eZXDBTiOXS@(Yh9nh;+@!1@<>(>g0c48O zU#L^zUtV6C4}pv618R9?C24X-#wavGH5^^LtOIxApkFMPvB z&)zCJcxk)vixBZ1nU$q7!1HO)gwO+I)W2>y{({ zw_$t9y=->L#^ixS6Lm>sSVU8vGKp{gHi&@b_%}vH2iEarPov>^}uO_RNS*Yqs01$@@qt%Y&^M z)C0*G=gJfqtPwJ6xAGf=LoE@y-eBkBm?2gG{_MnApiusND)i0CZ9$>)Lz!&!gtdGA z)7fh^?oHgH%sg!MRqIRe#f3vubhI8JA)y!hhaTL^hi7C?yEShg508h-m6es;IZqKQ z-5D*rALTMy$I5siebNQWGg?Uy3ABmQCCVjOJxuh$h8iza8p+x^ zI((hg)fe3d2M5O>5Gbjru<)0JxHuB<;&tjUwBA_hBA2mC_kGmyIJ2U$9x=M?1<@Qr zq;f4fut=0E9lepeBENY;GfoU z<~S2yais7yM=a8k#3zkxjsVj$U?F{TnaUFXnpG0t=B+o#NkzV=y{rb2d^K8lIkK;PPp{QvWSpCW)cF zsjbc1#nRFey^F^W9K?{M8rFq5ecS&TBFLsc zKaz!8;8Xp%H2RycUEd1O^kzgzMPo4ww9tZzlf(&nQYX|I%7tWyMW7$v)0NQd6E;TM z{3g3=Zc-b0iHxU0k4=@VrJ=^c^%SDg?;by2F_eK5g$aL5Z!l9`F53 z@1Lztau?DZdgfM5kNGK-&W9M|=ncYDs5_w}%qn=Sc^~16{QbX>E!!0$V=PJV7J8(3 zOrsj~%Ux|1x|IMNX;n7Qc2^Ug?1X^1*|;OW0E)XM@r{tbdBQC$DqU=!@&}&TJ_&z~ zS{O^h#8R)mPh9UM9QT1XEI3ioYz$IHdhqVxM9WzIlq+be*eDIzAz8C^J5q4MdAXA+shX~dL2bWenQW~_ASx( zmJ`SkVTX>}f;NC|ap4){*mD*7aL}qDXpQf=`H`*46})c?1~SY?J%hKv+t0?bvX$tQ z;mIVHc=9!fWkl%nEV*obbPDbn<(oGO(72r+MmoElg38f$Mk;?_1`67u4aOvgb_X+O z`w|_jn@5-XgIpiU+@cV^=DZlSfG&#FWdV(^s8O*p60N=6mj+>rPl7f5T}L~96-RUO zE8^by4hd9wLm=T6eMM?vo>7r{+x0yPy|??fkmg8p?c1M|Kw~s6E^Z14A%u~Ukx3jJ z9JYzWyB{gCc}uBH^26~_7);K8&D}&|A5%X)j^NXknIi`auWxK@IP2@LXUtdV@)Cp? z&UJJ-FYi3T*6-ORMhP?*?y)dbc3TPyko0`x~KPxfo}RqR!Gf1u{)prNkn?^fA*cN2%Y>z z?Ye7Mz;FoCQ=6x)uRZN23JV_HHTZ|E0*u0*{1GzZbtQHCAZy`38dGr?__p0;6mh4B zEj|S_@1W0=2NgQ3DyF)=1YB>h8;R@CdJmwD6;f#R4#UC;tq!B128)Txsx(z>`(FSJ z^_2?0E~->8*oCuxpdskmoyaik`4YSBRpJe&c3{IBdQUjm3Fz;?xp-brHkS4*3YawL_}FHE~%)Z@f%guvu&iNBODhXfK_`VFSXW+?Pae|Ed>9T%ry~4{In)Mom)2bJYi<|cX z2*0nq0rSP^4>7C3Kx~0lC`o!p<>r+O>0*wM|4#@4d<~< zWVmOKl&+PK1zP!N&ye&aUr?GCI@g`$M(`Wbif2#VXW=Aan4x@e3bo$tGNeNe@b7bc z0Q6#*rPPPvt3%Iqjc6zum-C*wp@+_3{>7Gr!rXn50w6T*54H)*ZO^>m38^}~nfKa+V9 zl?zHo9sH~Bb!r*&tiFQvCv&{N3E2m)c>yi^LQ?c3#H965EjgZLeK0QKZK<8IoPZ*b z$a7wSVsOX(7r?tjZFctrCl$C9e=8}AspI=E?UBNmCJdHQmRG&g)V9AuMdpn`@!v|t zclkOa5$bC4NHC7>8s!R>HJ6Ohu)yYl;lS|^Rv)cnOzJQzj9S|BGce>VMyLJK!RNy` zHmn-#6rXQtC8`5HlAug!j@A2U735s5)ON|I_m<}yI$IFDpv5Lb6+g+!$~qqs8rpe1 zL|4gI+tJ|@8GfKMc#F6skT=~4Omh;w6SrBFe-TbPEDTsYmqp$lnf;r->322K4dT)Mb>%G|T zZ{SCN@^#D3jwM_Sos36S+m8oWwDXe?9me`RT6SYj<`pEm;my7g7gNr3G%9Hva8{LRMLxg^pa`h&iIKxJtX>oX54%hGv(awZE2(=_Ef2R zB)YlCbnC<+Z&+1Dy*%2~b}rx^o;WvgweN5i-x-}4ycm>d9R(cUH>~Dkd`{c_V7rmg zQQf<+1J$;@!@9}6nXH7yzaxlSGY5_qJYVIfD;VBZXexp2qTA+vQ9#IP`#c7$ehddG zxcsd{!D^++5z_8?ty9p@c+U0c^i>{fX4R*`)Wrfd?b>)qboD~jt7?t}hdsIiP$zG@ z2`~`D0RxW8-Yt^V%abbzz2l0l4lMY9sb%kU6J0@8BOX%2v-eYm!I_&D;u6{{zfzHu z7%HvN?-CB!3>e@4$)N{KlvqrM(5J(iW!;6V3!6`zL|-H}c34pJ8m{d11<5m!ug;XB z5A-l$NXs1rUGJ3WCd^ILR&MRCzkIi*XH0dJ0}4h|@rW@*+>Z6iCEkb4`$jBEcI^ZN0+U%8HS)WIl*yhfokhxiW(FHYDW5{Vry%B)nh zN|8}Vo@BBvfVu7e6PFdSTWE;2M5d_e76iBOKZ_#BQ+Z^6*{JyygZj zTiiT~NK`UrwT71zTShnMcPv5pc6PvzQ&ln@$xsv}jSfFfftzERim!Hurg_p|R@c|{ z`P|PpWUj8R6e`Ngzgm>f^9i$IXX+lnSetjm9jbN}2Jnts^|~*9r1-5up5c?JO?q_q zb)ej7M4cf?-FCIb1(+MSzTWBk_8?1zX}b$sV5sqDmUC=tiu4)TgcH|_htnw ze%A4Hwtw~D?I9E3SrC=BuixLD|hDH~$9;ay@`chRxr7%pinBNF<6v z&Zs#-%bpPsJ)qqBK13*J`TcCjGn~LCjw@ zArpqMpn}hBx2(+3(|Dp&HyidS=Mlmo z+nJ~XLqMzZ-)$LM8NmC$)w^YFOlK)gy+m~`)A#kEl8DFoz$q{=Fijg>4`{(x3cO&` zgRb2CtB7#_h70PwBtr30Ip1(aeCUA2+VPj$srK2D&f5%V4e##yqcVu{;R>kIw`5Jc zZXH@eD0qtJUonl+SiaA@dhbYnz85caLT{h+Pp^|z);Sh1eK!(k@O#v&R3p@}cvAD-OlU)7p~#h9sz_J!XI=sMq>>C8zzN(;MRO z73V=Hrz}v4`V$Dxn9lEY8#z2YjI6_Ewg>phFE>tYPEsIH*|H=1G5$~Jd>)*gj3T0rJ0}iA&T-W}oj08ZdEb`28kpD?KlBN3J zAT<_%fL0KfX-sJfjJ^Cq77r~R14S9?QK1+JM=NH4-1!So^Mp}08uN=RRg^_bn{S!P z9(*d?#Fe!XAT7~(aaQ5L{Kfn>`W8*c_-*w%%((yyDL6pDac2;~j=El+PEJmV2z@&A z3ewbwr_S7LJGpGw4JBx2!n8lHYIMllhId@jV|=Mbw*~YD_=(Q>xfYr{Z;pZ;o1fon zKw|Z<=#8qhTMr5^IG2(8Il0?8kJ+Ei1f8E%V^EJHqlr~wkdLY-4?mI2&l!hTh`{2@ zetQ;z!B0671LlTBWZ=GFzxzXrK~zF&m;t?v;!G1s%X0t{{5QfvOp&?$VXcJ>A{ii< zW^U>I31wJ5OP-jPG^Rxm=IQXVJdUJ``>S!mLKQph^_Xmt%AwGLm^gRPdaK)ZyR(n3 zmimVH9Svsl`uh4Ri9y$s;e*I}m=iUH6FNUeoTdQwpJr~umR|9sR=)kxSoDLAxC4gM zNOeh2i?!Bz->T=OqpIRMndvZMz!TL7-w|P>?P{v7p5ALuNl6K?zh^k-)y_xk-e@n= zkQFDZw>$=gNh>Tw2VzU64wy9+s4pK{LjS_Ag`RXFxB<@gx@FK!a2uKs`f%s4gjsh8 zhhU_Gm9DM#{63~zqL6c4o71{Ja{~HW0Rj+6Pi_mwZZ|`Heq?W-c# z_Mh%80Z^XMDBy$s&nRhIAof?Sq1gj%$4lrNHSMmE_xGdh1Yw4xQlPTb;SPkP+FeHv zFhY+i%^n30CvCb@Tn0lZ(jK22tZkNq(8_Gy4QSZD+cTKH=%8f#m%@DH07$@Ato)`Q zxXKd~6UTwltj^kyjMRJ*j>Apl8@^`M!}OnM)GiY9*-(bbi=XxuoIjgelQ_>qiiW(il!CZa0SdC`JExjyWUMmnJX0f5!mWEGUv1rUj*zt&>-Xc z!!4csnY(ESJ%|dd_NCkm8*2O)E1%7==G8Ff$-}KV2+!6#-&VQ-YYA6T9^h$f$iJxa z?Hx+0QVF+Uwq?X1ZORW8ZgGrm`(#b-PR8y{k4s|Al^Bd~pS3n|y)dww*3G3^Sy=%G z_-mw!ii*rA(h(57`u01bw`8(Hk%liGCiC=Znv8Qj`T7dIEZwmLDNXS{es#N3S|kdI zS^J1RXcG?%bV7cgj{&m*IA@a3rF9V@G*0TBe?>C{i5sKZR93;zu;l=*{y1*J}17I_+F zvj%0$hfJ>zC0*)0ZVg_6VB)fgemn77tfXav^1!0PvmoNI>7kLI!m2zwb7=?(224be zyB>)EtPlv8Yfd&o3x(_>fEB+$;dWRo1*tJR-?N3FWCS2V87oq$&R`{25oKpvQyLat zFj2QF-(HqrC)5Zx^ES%Cq4Shdg7YFPFeNj{2wE;xgWQm(Ck*iuale6U6@1VQ;}r-3 z$tEOXNI)+DJ{k`(l$1zPVNMUV&F99AFDaG{w&q!lz!W%;6c+eB(N|9`%TmQ9clGG4 ziL$T$#dJylXf56^Eom`-=y8IEhHkX6wZ-{4^ZE%ttWJ71>g;nqsw|1>cW7~%fdcR0ltVbt^u|<~aC85gC zs-i{W%TAf{wQT?M;3JNLV%k9e3leU|>?_$#-aYPJhuX;V{@eg~W#KfvKm+|lHZABD zsIu|*3XRU=Z*=-#t;Zrj(XtmJxgaE*-Gnrf1sgHE=WYWF{p45T1$dT0gD}NcRL7vm zs=ogCRKr@$KSh#`0*OOy8KLfa&ZFIPoW-$!`%K3tvG5VF%UrvZ+50>pe1(teQc4V~<9?FA%W#bn5U$d=FeYZ&k=qCzE6mZS+%B9=7R$-LI(*=YS|4Wlc2 zhFFy;$ovGsD461T6Czi_lc^q4B2fu@=is+<)T-(RVSy6nXkuR1-N&2b^|gfsjf*JS zJH%s#(_U2CTrQY@Zd(TfuO!m6=Fvil{zxMLk@G~z zfaG2j)hqY;N3-O$+O1)1yM~xi%c#>ulX#|M+>rq@F$66ko%>_f3mzbKzA7U&-9p*8 z(1$=`34W@$ocagF_{wo-n^ptjHv2pM>!OKqv?QsMFuz=da=kvzelg-eVM*yQk!K#y zr+ss;f|*TT?ACLONB3Jtg}~3}{}>}VqO!PJ;VAwEkzFe?T>z)A8!)NGL6B+NSraq$ zd#BzMt*aw_6;Io)YFb&c{UIxx#kSQvq!#RKs;!DX9jr!S^mw~q!>n5xMO*+l+7-u5 zRAcHjf8k7s5Kkh^YTkI%r;^@MwYZc0hmoM>uzBZ$U5l%~t6#(blqGcDQ}3j1CLNiS z!r;iG<*1M)0^C>0x^0hEtM4@YqaUm);Y~2WACy&^p_BiR5jjxRc2}- zkVu&MD-(`*oew7dK0G|Qm6w;ZyWGO3(4Rd_D3E(S@(adRcQ?IY2e;GAA{>nYG{mP! zWGBelyyaEcD5Rq}Cfk_ph59d>!n2!3Efon4uc&X>3_h=o?sL%;MxN#qRLr1Rd9j-0 zseUC=xmK>wr>UU^!p9U~Ce~e!=|hhSK~X?MZEi-t>6onwZPYyGSaa}6OAok$QQ_*J zm9m#E%V)<9ewgdsjF``C~loxS_ z@{;O8E(xBWGVN4k6%vRrSQ}!(4l{zo4wv(sdaof660oN=p|k7J=TA@TL*RsMTwG!_ zP(Bi?8L6}!RQ;rB%2O79yD>i>U4P{)W@B~Dyrt!`H*%L>!ezEur)?*4H5&HsIY0IvD zOn*@6;{S$1Cy^Y3Sw~55A|8b!#lHWmPPIF0k)ZTUmP zkFnnfE0_H7j1qj-Qd*XD|?9nz#!l7 z1mZH#m`?^xE4(sequ+P2mT+&WM7%uivaNml!Lq**opVjVDUX7i-81J#lQln4VfcLr z0#B@K*r8P2K84WJi?Bpa0)8BC6Dij-m;F2{B} zht$GuwisUYph$8)T?MQh)1O;9&QeFMb*0s(v$U@OLN;FZhoWM!&-c3$+5WT?hl1Il$JD;E|?`=O8VL(V|al6gm*s!1D7 z3(;=hg0~yi#8zt8qV=aqTSkd_n@{TGCBs-!T!W4$|M_kK{%R)Msnz%cdmv%EnO^~D z@4qSyKLYl&WzRbM!rc!<;s|BI3R1ju$bJO~z${|=4(f>%3b1A-@+9KA#Cf;=GyVr- z`$V#FdzVt;743^^e?QtaBGT2t+O>daa1Nn}$LbUv`J3j1BUs7cAiG*tKfqlcWDCO^ z0|02={OkN5^#eyQuGXqNj0ZvTHm|)B1?qirltD|TO{NkVpS0CN@p_OLKzA~G1^M7S z2?+_@@eJNOKwY*6#f=RrDINnOQLB<|iU(Wjr>EWKH#7b{=-+XP-|Fz}aM=~eN{;`8 zF=>Of9HMnRx(i(10&fMfR4UcS6KH*4_VlNnO7fVW4qSg$NC+oI@Z&9$PGDSBuafW2 z)c(+y{(^B+M>n|yhHs1l@V8vJ)-|9p($a>?hFT{*q)vC!@~qUnO}ElqDr*!}N4&Eh znY6px9Aig1zc$rmmGr>w-}rCr=kv@@$^SNGORO4LcD)`s2nAAiPcJ842{QICG|0H? zoSgM#_!T~?*k=pWl|c%5_Uf=P5(DMtgT?hgzH#5`-=hElPXYx{2)3#Hl0ux!R72k}tAXXQVkuAPWTDb%uJu<|H<`1~!D& zfj3TrShb=XalwVhnoH)hwRKhyHvhaGvMy{yK(@S-#}P8r`0a4^#vct#1T6I49b;i~ zhA)7kn17|)AHj^a223@-JvcSQRX?PW8GMl^|G&KNkZWM=WBQ}e##$B($-{70+AAF3 z=?!`IB(-sknyPdP7_d{Fu~9D6LQ{w$@j~Ex0Nn}O8SXD?xLU~(mw>_^hP{QtK~FZUtL`FtI|U^}~`)UXG@k>mdeCW!u_J@wF^f-rec)-O|nRyd4u{C;_fSQ=$|% zEiEr(FSWIOTpq^L<@cPxP(EPvrY1w~C!qLOne;@$rdPc_o4CK+70$0iwq#}=?eaR8=usN?ALsjcTkiB_?r?hTb{U`|rRGQ6LNLUM`W**%l}9V+zQ+b8>V1;`>_yr!4HuDC`>R@Br>5qSUS zu#r&)>lo`lth=$;-N&nD17|(Q*nq-LVpBK2DOMBv%is1Exc_77Ed!#8wm;CJTR=d% zLVV*{pzaK!j*wU$ zlC(xdj@IudnQHtW2cmyQk(e!7HoCeM&bce_)YCMnTwSaM>LhZ0Q`}o$Ux)N!L2*2^0>?t;!=((Y_&WwFWa9oxRYsA*K_F6R&#F2|arnUbx3 z_TOj>&Gh8u$nFeqP*KLn)(VdaPH|$xhgrO0Q11n$qpt%dg(#+SCaT3D+7mHM8qa3R zA-}sN3$cs5BT#JHkTSFL6%JB!GANERz;|WoEx`kPD_(5PCgLR-cCksz zc~5Omd)A#Z;ed!IzSovH%Y&2+*-dS4ke-?8#|`9mAGN>es0fTw^P^(1r^3n*rkx5C zIt;+)>-|vq-ate}#L^Qgvt;SU1L%>3oL>FO<-}g-sHLvSSUrG^9Fe3#y$5|2piS&{ zEe6%o+dNlWuYB8XANZ83`TmFu87!zQIFc6;d}?tlm3-7R2Gc#aHS>CU_6Y&TSAZIY z!54ToR1o)y?}=CxQRYMd8BOrTj`tv*idqZ(;~9VZkLLJz1dZ_iT6G>>2pWdY9_Xr#Q8Tf$&}K_Z(XKNs_+jr#La0^vwa9z)K}h zobTsIWS9)W+gaRh9GL*19`aghf*T;pwvlfLS$uLdT#t77O*FT0#7ci~!DglnIhsOv zSVRCgV+M}q@hy-jHwosSCqZd#!3G?8RXB;$4IhZ8n0jX$=LnM>KvZo7^?h3=klaV7Q`WyEqe#_jh|y> zzm3Qa;CLr>gkPHn)39YcIeOwKqGg#a#8a=6o}U+_K{l3mNLDt|Y(#ZG`@5FBZ4M}{ z2At$i@bO!UYu&)K8>sT*y%M`c9dZ%jGMtli+(EdMd@2NVSxDxM>wXOnv2v}EZ7(P8 z!Zn-${uNuodf&y1T*rEjow}I1TL4NP>g($(2OPTQ+!gb+7ZK;+drJm(xwh>Y!i%e1 zLJJ~}l*Alq*Ci(}!U9rE!lgOHgrkHN)r^t4Npe)zq)#A^t-oj5epLN}Pu9jXZ=cT! z_`5QbY={eI?u4LyweJkAoy*F#B;D3AKnMn~E=gV<2K(*nuH5*j&}Q}8=+n?>W%9aM zO^g0mo2-<$R(~KW1T&N{Wo#dC!`xoqxgAteClp1Y@oi2K+Pol4zMea}lUV(Y75xvv zWYM2Iwg3x&@&@XeUlrjlDcgZ4lKGquu^NAfzsfJ#PLIDDzF!P@VTn4FNY<2^bC38< zo4esc^4@T40vI#+EBEs4?2>}{Rn|=m&Z5I$<7Dh&=W@FCpMJU&Bxa_jdac*a7&ZT_ zy};qtt~kMMQ66L=IeD%i@9sH#)W!$yLDGmpp4PAnq(aKs1y;PqkBUS;Jy{a7YrYDu zc^=V&{u1c(r%FCR=qM@mUaWAF(S|mhbz5UU8%E2~f5R5q>36=p8WT3=sHYVxC3Bh2 zvlJ|8=Ry@S_8J--;`Xi!;`h*u%&aSiKIa|Tdy!|G3_k1Hqg=AEqjt(Wu+!96>E!!w zbYcF+f09{Lfv~RXD^AWc+1!_andLa^C9b5k!zaM=UwMn$jT$iWa@bY@7~&|*?c{>@ z8cfAmcSgKF?zb0I9v-k%<|4EZ+m6QD6~IRr!L6M06J~B+jB+IaayIN2hZE>105QCK zhZn#^wt)!v&}Ztz`urTdMfXJ7h55SIUgL7s#7U2F<1A#17uvZdR*<~@e!U9~PAh4+ zTdPmIu_;Id<{zRZwS~Eu zbYEY?A6iFMn+t6_kf|?l_qVaL+RBJ70 zdR=u*>&5|}eM!RLpQu}($J3s$>YEWm>zCsw^!8rCEWD){RB*MqV#zzl2yYA%%kbY9 z8pc;#T(0$=jXMYQ=!Xy7t2uzE<4hbB_wZ)*Aq!R2|9AK?79CICGFBl>IRN~ATRxGJ zK*TkUm>2EV>0{TXLeWVmw8AH-3%H|V$Vz9mkZfn!teHfQl2I^z?JhAa*e!Nhcg_pQ z6XIr^+=SM*5c%#2RMrVnbClCb5N(_G#2V^<{FrLVH1vJ-mkeRnNY{5`4Mtx{P8&h- z17V$ZZ4s4wK6~LweE_N3TjRa-HC$v~Q~y)+ch1P*h10@x!2k$gR+_J0Z)N@4d;r|1 z<6V_s;^Y2;l)Hy2cgJ@j|+mfVVFa$Y#!Mszy>1x;-lxyxWs_*84ZW=9e;U0yPM*P(g_C3ig)B^_+0eIkMyy<#^{nUnC{&G|=%Nee(-YBmi?4j-N{m^DNGM2>ZV07Y$M zk$8k+fdR*dFrWuG1uCPKn-_W3)t~5C#Vw%ShZz*7e38JwCl4&hc-tPdS$YYhvDk9v^;)W_bt5ytwcMzGQ(U%6pS!&ynr&2WmyDL%--@?VXO( zV@Ck>G?ZVN)IfhrNx)b`vure82P;5~C)$5xB9848ht4tHuGO$9=%pkZzH4p4O(frNOV|Lc8v#$$~Inj>|!C?DA zNRQgBnoL}HOAmVNru=vvuF4+!P`MS0!pOHbZmYAxFjIR0=h_hwV})3G{EY z#IO$}%m*K+-rD>g@O4KCx((O|kyK{r4zCA}vL?QL7T4B!_ru&Fl$@vu)84Xc-8rz3 zS7ld-IK#a%S1A0N$GTeZpVK<8KTE+Q`R%U1zrRXuboCSV(0ZV31P-P7a{~tnsRW`I z2Wy;XU9@75>Z_#qv&O{_BgMvACSvf-=U*0*v|lLB)60Nfmbq4Hv$k?^alNazWCdV} zZ+my0xqTtziM%6mi}&u+FLfp zMNKK#^4Hh2l%?9=_h(vTLB#29k~-_-Mz(81Z^j4T=q@fk{BcZuRFYp1X)AA$qhz{W zanej~WkboqD7s7n@(YDEs5Z-}9Z$3M>$D|i-v&lg{u1K@tc>}b%jkWZfm*O6j=A`6 z3+CTK-o98$1Ic4N&=+o} z*v4cU9!eT9`v)D5(@niHu;>kr#5m`0=L_qX zZRVQv|7_am7Pkg{-4EvI%tzeT7QW&tasIt65EK>`77!J^_uAvxIkO@SQU*4xo~Kd3cxt5=xLQ>$ ze`n_y%(dS^B~9U7x~qp&%5oJ!UY8lzKmB{!8@IpE5n@E7nR8%~I(9KL!#U~%-S9Qn zw{6?FneN$IcfE3=;`SOk(bJ?ppyH*w3?a?>kFN}HsX+z6a;k=R$3A|Q3RNl~wu_Ew zp2!l!n)N$q#um2Z<@%=S$TQeow&xu5Uq10b*b_kD_Mea_z%L#dIFSIHTX*41SPDo@$#Bcal0s3?~6K2u1WU$>Ueuz*HPRei%^1akQ zQt+!44t=RSh`sTjH8!(9JLnQHE_`s3Vu1>qfndNQ4y8{%Be|&0CppnS9kw{ONI;uq zI8RsY$NBwBM=(9`m zu50&b*>w0fqR4BG3Dt`xWQ>HcS4loZXKg;92DxkrJt#*`h`IZbjrQHERM7M{S-F8@^aUiq_ z3%UzsNWW_ar)qmL=tk>Z2OU_+@cBS?nHkCmz;}$Ul7T-EtvFi@DFD zIe8iZ#AD7tJ(LmRPMe~hnJ5Pxa624?e?nadJsMm zLc3DuB*x1BR(yqdnEczy;-Z1D&(-ms;&)uV746~HGj^V?-4jiuHTDReoq|c+@$v#b zZJW|>mz=4qc@QU!mh+alZIGw;0rEC!?1_@To2Jp%EUG0=AL^63$&~Vg0$ZNTfRGv! zfhm6JNFq#*Emxz2m{R zqMXhzWo21;a&gN|KG&zrtl#>pGLr0<+V;A;1mt}t=0h_Cmh|SBDzr?(@u&?DtIsh3 zb+<5zI1@Crem*}W?q)_o>@taDd8^R(2yv0en-4j-S@yKRAXimU87lqx^I@a5wl zYkMl4`A2>CP)CR_*5#N;*#GS(N?aIq*sjoJjnvWJtYylz(7A#7$UKlb3uN3~ z&Ug6+HX$2p_N;~T?yW7~E|ia;v6xlQ{Q@|t;=+K~CcV^>_0ng1B-ddCEBn21+`{4x0Bvzi5sEW6D?QOQTPNl>5IKfLGtp+gjW!(tx1z6eVhH?wNb@V`&=yxx2OB$aU}a?AKM-og$G&9H?P zymXK96i$mx6yv*m;ymXdS^2|fHT;AGfIaw>HR9CV_#o6*es%9uC_e4_x%d>0E;k|x zX#wnatx@En_xQw)?pKDTS058qb8=LK9-PJne>8-y^*?uK=HcQ}Z*$t{Hy7@TBKiEa zbf38Ydxew?EqPdv+&!Pmq>}UQ#!S%91j0kV7%1u5mRjS zc^tVbDF6fFv*!pf_TAb~)JZm_B?<&tondoBUl1*HqSk@KmASDa_bH8Zpma;qgS*gKW0Ne4Y>% zvGGJGcM*B+(S)gn5(gM5{tV5Us*{rJa-EmUku)DvX;yt9&M)p&>!&@9o8Gul!eYn2 zJcS!*Ec3e71Orp(>9_#v*V_qcf{ayXbqTc0(O(nI7!bnLO~*QC&9b$K=7ZgF7ySty zJ5uY2!!#~@HV`Ktul>!rGdKra{46f^jkiIUkJ$LBdK#qM;~up+43~!`x_==jBx!9P zv}{pGY3psc@Gj0z>G9s2*it|-S(O-H%E?t#(& zwoL3tN(31wrk%J%LWdJgi98?%L50rk6aKwERMz}_(5o}_bf#7yY!ZjTABsy;^b@aliweb{O6M6!qQ)e7sT_# zXxi(Eh`%l)x#?(gnzvIjnx;D$gz)6hqrJqN;o;zB;5=l2L35%{ucS>4rs(U6*f6P$~TODLs>+37yzt}G`f*2dUAjTI7GaiA#Cr$-jiDa#)oVUS2(MH&G&Dpv2nX6&UVuK z?PqyX*)4XPY7h~uQX?$Zg5V?#AcZ94$06;J?3BH#ygRGT)QfGOok>WUsj@AnsiVm+ z@TfNnDXtKH=ibLXuQktY1?C7c1-~y}qy`%JdbSog#;3pe&Ey|QAip;rq`#nZtQ@FU zlLVOnn$};xe$DiG6+8_kD>V?dH~PFsH)+M^!`?M|W*yk&9n>)!?TOdOP=o2-b~_*Z zV%-*fM6JrAzi!~`binPkyRss)t@vju_7lOP<=7ClJw_sf(vpA~l(D1cdvU*z2e-849wwE7@7 zhdwwr(m=?;AFTm3!n^qOFjYovQJwoJB;CN6l6=a9(${w0K2pr=M*Xye!D`tLPE z1=lqytA0jtNh+tc6IbpzewmwlhXCja6!|n{4R{%Q=#dvp)I_m-tJJhTDgt?%H5QeP zx6@@uhahNfNz(j?$>~GfaE_@Cy`FWKAgTk9`?{6EBEJQ17}me%4*%3r;3=xH3)mDUhUGeIJW}n8tj?+@`o|954H=qj^RJnw z6XGmng{B@302LPCtiDX>hI)102-MzT{O2_481c=z9`=N! zA!4>Bg!nSF{e@-W8D?##Z5s}d)DzoXC1I=7t*N{@0GI`kN|F}_$~0%WQog`0aX6PG zFdkOD9Czxd$~fE*2H0G(*d>i}WauUzuzBA35do8S03g@8Ox=N~wvY>6w_1Eou3QK( zCNF}GecMe0BQ1yI&#j)geh3}uc()e8ryV|O;|UN+0;y11C4PJ~*W6ocQm^cI@j(iu z_Zd8O_sWbX#hk6Ji7*>A3^_5%41ws`ZlDsKu_E*>){IfeqWzS4}*$I>5?tsX3 zX|A|UCFY0ZZMts+m415`2TmlTANM|0HkjRhaxoKn!&yAhM#oVUF;WIYjRy_bix0a>Uf`{B$C^o|5yg-=TH=%UbIe{L2E$l_X$f@HJ`cf2$*IHElDb zC?gJ1+|YjmknMvQI?=PJu9%33h*0m2k72V0EyGKgD`+&a-m~lX{jDMWX7Th? zTXqt&tSz*&u_yfbnYA}aee?AEyBFd^O1Va2A_L_gi~v8OZIg!N!&Pz|zd!Ok^ASai zm%_~$s~Bvh^&#hPkk*!FgCJ;rI5`HjS(VXdH_9j(7{1KAe( z=ry9Uw>&9bVz>#QX8BlDP&!7Zdp*lTBLWb?l}5>sV&7iSI>;US3EHw0XK82&Wa@y_ z4Wh2c)fE{N`byafJRn06Tbx6;?#8}CTSewq{TI0BZPX*{(8vMjfqe7ExI$mq%b>JF z88mDxEUcyV)f=mrZ=S4$6YqJhr##Mz`0c^jq?i_V>qZi@oOg?EI^Zm7+o;Ctq;;fg zs>av5SlQFBr>|oYAC*EEL@vWF?(wVSQTb8$Wj!$~4lkFCInV^HWzM@_S=xN9zy@y4 zKSiL@KuWxKc@`LZDU@Uis}N|4g5uB~oo+nwxO~M&#R-bp%csOTaMcYkoQ0_z}C@6<#Oc=&$_7cQ8mNVF3xqlsXp0$igJfSSBpE9rMrwW-_KW}W0e{9Aj zW_f(fnwl$)qf}DIs9E8Kj2xZz9sD4JTCLX73Rftl5c;MOI;Sr|!v(3j0YCUPVC9U& zse1R1!eNydz-+M&uf&Wu#h7Za-WoNA!W}4lRTX3KFL}ba6IEwpAr;Ni%*==BsgQ}bG~|gGjqRxieH>?x z+}Cz$g#MdF_e1Lpd!Cta;% z3nAWAKqzgEY|BfRF%KEF^w6nG-0pQwppQt(Ip{r;543ryI5n7|sz4WS6qfiTYPw|% zG(AJ@H}j%uj{O-q`A)CP${A;Py$eAK;ja5hepRdN_@#}D@F-Ifd}G0=+P4@mlAso6 z$>v5tEPsnvzN|6N5snO$EF2wK0yJHV*J;n(uf`X*vIiU)-+cTzRYzObR9ZIq>skL} zz@Rs2R`Ma|b3U8y#TfX=Ry8gRxTSy^`s|*4RMh30Xfb#ITpCvI*ers*`b7bgcG_TE zn2k7B1!1xf8jUxz!<`{wHGuZ%RIMlD&iG5?KksipnXd4G7m4gG4O$8h{y=3jYykI5 zhSKCqhRJmQg?AV!R|8USU+bmUjBUMXO9kiT)OO$8cu6rue$z}&PDb3^2xYuN&(w*& z*t2S5I_R{b%~71cSYKG#Kw?qbwX0_ZO_u>u(>HfIAIsh(B_%a9+wwUSyKyQqit}`} z0-yA%QTY#)zU9C{ELH9v+O|~lIP9~@%lr?<^T)ZcISRWq*}*?g7Q-2Su@M4F0vVtm zQ^8bDJvo@!Q3uFj11ns0$3KXB%;w1@w&}D%z%X{=l1k!!l?gFx`_3*IZX@~_!i#PJ zLD#WQ<&$K>wEC?tp@Pq8&j#pl7_foNo9qVZ!q4-ZiW0y$ixmySeAqp!;t)w(?_v{GXm~0gNUEUzf`tOe;qy3pw))AvGU^<_Czj8y4xvXsSl1tj9jjC` zBM19;f9yh?+mLTbh?$==8ERYn1?Ms4^#Uq+uR_f}aoRp$cF7cfgQ;8TTxkEzNM`3* zn>G3+az#`i*8c6z$mx>&U%%R_Z{vMck-04WukxpQUHnYr9qkPGiuf)EYV7CmKt>Mq zFAt`f>{zQ!5h>*Wzn+rIwSPG42TT7=t}aU5GX5em0bwf+ie6?^It!iudOwhq!hOp# zob4#Xq>%yPlDKC0#lBRys~q=L6sGS+qG&dzqrfy@uY}1)bL)Qm z_|>jU3AVP%zoVV_t;4?^dcscsrrAy=Yz?NI455_7210M(Lt6Ffz9k9Egb3UU3v~SXelaQ)FAv zIxjk0l}1LG0{O<@dE-U8o-$4Tq1 ziH6?D`H_+w)h*!r3^GmuxH=JipsM2Y0oD!AZvT41&bfT~C1aVNADt;)XN{ddFBEJI zdLic4yn_SdI;byaVPo10>++xA$++nJ3x#A3!p-@gQhTnD%4j6M55D}dF{D-47^fV| z1NY-hM%M7H%T5iV2tF|$j8Q-0z$_ltld##xSzVk7h*CpA&NK;sQqf3Uev1CioVwz` z&G_G58NtC(Yqpp_MzRorau(XIQjEsV-DegVm(#hxxqLDOBwOTo>O3l!_ngYuyM#P3d`_Mt8iUE;oc_wG1a+q#OFgoaeEPI z(hYIn5J^VM=6)@UAXA9^YefNt=4Z}kLPKFscC~;9A?-rT;?4LXpxHlSZ6IHy9=SWN zR)@bz1)BhIR#mljffAVaYrs9?1O~n+$<6rMTPO+t8l^N6sg!4CupB(k@r^ZAhAPxZ*XY{EoKyx%O@dMjB$|A@lr3b!CVDo2 z9rX#9;Axk611=xV8D+zch|dR_$N@Gr;Sc#D=7|KqIY`1 z`G>O`-Cy_vjo{4(9qn@P7EN*W;YW~utqwqueNXLI3C&iXH;a?8v_4* zEcR2D{ z6zfx(KNoo@cvseHDhBCmZ10h;(3xvB$Zr@FHY-CQke_2a-4q7xezf{^Hm^%NzV$Nq zvn??mEOzxYek{}Zi+#!$$n|?Q$z(@|wBRz|jh2?WY^y=zLhA7u%;dQZmq)J%^cBTD zl_R%BIAh@DC=^)0>5o)Zhlt`=2%;ExqX^!Hrzzbl7~io}aGA)JutiqYy*@_+&^xIW zg8e2!ibW13mpB%HS3Uc7GOwv2)w2}(11|XIRL?*o@sQh_IGHkG`3a6>VrX5SE;Rb@ z20e+2k1ijh1J*R^)(E5D*0ns82%Un0;>)4-k15vB(9oM{7=nW^cAOR!^s7J#eq%06 zg@QUb?R{ry7@2Fv=pDu;aq*&hx37PXOyE-nP^Tit$>f!{1oR`3HTVnMuX8OokPgHM zbI=G{!|Gj0WJGDP--E_#F9akf_NmBEkD{KQrQka?sf=D4DVvUZ`?W3N=Pk)eQpzgy|!A5b*-FaOCRAQ44BB`e`Nn5#I`VFVcT`j6I8o5or#A5DUep}fk=qQT% zvKrg;RjC%MvS~fn+U#M7UKy7^?!@tbj0eyquoGDuF@_khi9$^vtA>uBU;Z7Lh{NaE zo!d6c5Zpdg7 zj*J(J(MIgb-=G2-@_;|_q2gF36i@j0TNJ*$YzGhfI;E)Y$kJLzl-|epXg^2l)9w{I zRaaN%#q8SzGW;IBa5-o_$?dM+b*mWghOC#8M@#scxLW3E14*xY+&4att2P(AgGNB* z^~rI~*%tTf)Z5eiBOzD<$OzMc4DnU}k|0M2PdO7b>_aAaqPKbm4^Udc{Fw#X1Sa0R zs>-}hKryi+MH7b6UZUoO1+-nb6fUx>qVkf%c3Wt1l=8++6C|4&WM35eLL<3+#8gXs zWagwPO#emN+=bsCDhS{VkR{5w<)|OZ5j_+6VfP*?6+MS&Xq|XHW(RV|`$Jt%O$b|44sD@{3IL8Z zsOW5evSnl&mD>|DjepnNS@-nm;)y%94IZi2`_dEUBa+|1&Nk2|q6f}s&emnWh$4TL zf{*{i#HVf9;p*XOE{9Ijq8Gy0b2HV2^*>(`Xp=Y#l~QC2UnU;mO|VPpM8dJyx|+@g#(4gfa#TS}H6-aZ}OsLh_z21Ea{7qX-!H4a=9T#jpBLY&BN>x~`$ zWdOBE_m?mTl{pmEMXFuq6Rv^IHpCBCo zt#03}E;1pynD=|nzgN2jr~4taHFV+_&=v0yvCXgycQi&7$3>alfs6Iu1Jwip>1vnb z!4w(Gd{cN+V-9SQUlWRP2cuEoS#=ZOKDcfM(1oxN*vXi?hEZ>pp9Z(E~0e51SS*4$MwN z5pe|oNA}l<24Lw)gdWtLES8j|urjI>jB#6gXx4o3Ws{j_eqT1Htu({)zpHvkIx{S- zMo#SzZqC9X6`0TTim}TNLK*8Ac=P&FW8B)>Jh;gWire5vL*Y&8v0>_#e}hMl8tdPU zdoU9_8+O;VccC^~f_!Hi;oAZf>P#*lY>HMqidmds9q=~Q`AfD!u!=q-_*wtPo}}dx z(Pfi*NUn|iv!4rbs1R{zk;(3>kba_mph{EC?#iAh9#j)_M4Nw9t&Bgz!d73bLX#LK zKJHF7c5`!kG%@X@`;*S9Ml#(e#|T)n=u!3yG7q)u^vy4e+~PUDJ`DTLow?9b2xjo(M>bxV?12`7!5b54!Z-0D0;wW(r`7x9Sz(@ zFL>@L>}7W&QXx_l*pzz~$pB(q2oNPiEnrMppwuvfL=Qn~!IKENf@b-{??yiP*JLu# zPe4fVL!@uz)WM3Xrw6I;f*bG7*BCxRd8-<&cD|@M(rM!!QcWnfh*W=^X7%OhqKEWauf7cni3i_(VkgeO; zyXRhxUS2m(;4@#j*p1Cb7`bVQ7ewahUY4DD8d9T>nEcuO|2=*y(M0tZo_Mtv%;R^) zo&$DfH?Nt0K-_b0QoAM(4EhJO5FPK0H(O|1{jNP%?@STj!6-dqPiU^WfCIY};r9o} z_|DvTGnZ_R=|Y7?MngvyxMuA6W!qcBvkqeJGr&ez&zKWFG)_jPI&?qxo<8IJP8pdi z4a5cEI-Fy3`RZ)Cg|)>m6-U$AD6gYFecDI010on(jNFKcQk}3`5$wd-OO!@pDU(dJ zRd~Ta6JIQzd=56riC;lA9b^Py)SqZd!zG&rgP3cCS8UjF63o2=?DZQ);3I!-JEa=4 z+SZ2#YFX*`=c+BOe0=UKbY7)Zz&b911{nn=3e3Eh@+nA69M=L}*#1`slkFmRH0R@Y zT6#B>6acH1+-K+-8g#rZ3sYgVU9Y|N+@gcf;4$Ymo- z;9-L+KlS-b!gE=kk<6_uhcLtX65Ob2e?CQLNxaoqZo=Cr6Q0A8OCvC5nmXu+`7C0{ z)f`Ux`k+VIa~|_KDL#!484-UuQw$(Ci3i-5pA%10lG``xa{AT~w{48C4jgkuiI{uE z*i-w6nO#NH_`-XVsAo?$%nQEIp<)kgoF3GEEf z1s6|myv_gbMoE05l37$*LsxlLujr2I4?EVt;@XleqIV9wxygLd1)6#*oO?K4U)Jz2 z9tLCfr@orDM;QU|l^cy)lL^|;GX~}DK&T1UGz3{OeFiO0=S?|&}iKgW5P6V!2Pc5b3ujoT+ z9DSrbg$7n}UP2$JRWc90-oCmN-_xxzJ-rgx0Q`2-Q&JjVN9Hd2=T_{k9_UKHE@Duf zcp9-2&9L^hRK#qfOmr7-f=dXT_t^Zf^cUuSOCI*FnUuI>95`uE9;kRvnTxvm3`B_P zAqty8@gRVOfkZ&7Qy?P@<2Ze{ew=-4uX*@4^^AI^@$y#m^vCK-f^a@U%e=BjB($T6 z-1Z>Y=&^?VXd7;FN#C}g0|SwMO2X!;j@>BD-NC`my-nESVN9 z__U^x16A5>>MW#+A(DS8xC`I=i(3r*YKB$JIvn#qsktk*D!H=}(!1!c5OF0d{7Gx` zzw;*eD2JIt(fkYBL## zrmxLg-YRc={b`rA`*j*{JY%{q#P9fCw@<;NZmRCPf1O6(MiF!74s=-Qbf!tW$|W@S z<*=l|Q;=?~H79UyAnR~Yw& z%+y^2bw+Gx_F?t!#oel(h2iZ6fjZZbRRQ6jFEEe=mH{PT6g-mFv3lHZDB7}@c|1+@ zT@Q@Rk64YV7Ph=n7%&ENC#DepB=?j4AK!5Y7OZF)P2_=d_4^8j(H-nOP88Qb7!*#`P2EQc(HY|w{$h?cAElIKcw_`_}N?Uo83Wd(XS1Ie%A=t-Dpq&i(G8Ul$r9?f0BO z$!_@fp5@}bLF2TvhPHvO?rZ`NYby)7lhG?<#~1D*#7<0rOnO94$4H>}hqx`Z?=3S2 z8`!vK((;bxD%KyAUE#Vn-KJHfxAlEMX;bFg!IBOFEQTe_W59PPZo)TmMJ}Pfdgk2e0J<*hbK_ ziUL9$v+HKlh+&acAJ1%SCt6?pbTDN2F@Hq%qR`W%slk5O8&BI?3{& zh7){G$t679e5;|$o@Z|+P`Bs;#`Q(h;e%_nd|{yz^oQxfYtm@+a0dzck@h!SHc*?&?wxz-lO!MbUL9~@{A{g;ODao`(3lS| zAZ3{&D@1%%>}&qFP4Tad6GF?Y!4p+8?8qvc-$OwUA1&QcW?%1Wc||xPD& zYcMK2vqq~c{Q=kErUWrpj$%n)iLA`JwPq`g6U8*}>Brq)mjf_*H|g7s;0)d-qjS8_ z$SR#}>N=*0g=7Loa*d%_Re^Z#$ybiTw#zOOcg=lTf>EmQ4~ezmm6A6bTQFWowbr+( zB(t1D4a%js0MYtv!3r`7-3qN1uIiiGG(ypL?72l>d!0JGKfCv@I|cemExL4vTvUVy z+`BWf|7~wjQByl=+$l_Z;(_j@Smc|{N8|`4@Fh&y0ZB4!fx~s@RDvTu>(aC{EdBR| z^<##eC%0yJ?J#>#LaU^*&W+U_m`3c~pWo~)_DEyRHYL7!S7WpFDN6*$z^@y3w?_=6 z<=Ag^q2015-1E>EG2m}5?jdv`=y34T_$Hlf${NoN-P^ZsxRdVvlAM~Wn439)Ivpye z8z@A~v0#sgWR72rX~mH^5}21c>@y|L;2!HC#k{lN!b-JJz-Q_gCV%T>)kd&VC8oSa|g|W-itM<4|%MN~~AvECQYX%WI z5DZ-_N0$V3Jst+)o~M8J3{s}iQ9|A5CCOf%1imW6Eax3N)Fk%QlL-*Pu%mhP!xVa2 z^?yw)%>xmd+EMcOB$OF>-Oz`Hdbs{a2SfUW+)2r{pQ`ne)2#Bqv zQN#~poYSm%2DO8adL&FwGG6`(wn)y-Xk!TOPkp&6Kr!B^4oX0VdwH(^gBB{bw+gA z>oeZ(&y=qE-SHwS0S4KMve1$#qbPf}pkUyb_ex-YEE@J2 zVT_{50?vMiy^K8n%G-SmW^B*P2tKK;1Y}9IdD^B5bEU?x=}_0GBu+EkU0YqDm!5$E zO#@(7)W#GBql;?bOw>ZCXT|9|ZBg(19e#D+=F_pY_pHjUk-&-iH7A^jMJ-iCtW7;t zgd77Dl9QA3;MMw&6m4tu$=HEtLmv{xz&%50?O$5<#%RAHH#eGX)`^6wOLW7-&^ocv z8T?Dy6`0Zg_gXEO<04p$H6TSfVyZ`oi3Yj=dAxx!eyFdK;C9UxLK}pj7OH-%yjvpy z3LPqd^R(O%uWt90Hu&u-xlyH5+P~WR)b7{e_ri4(IDxxV>8trnkLHx2|+@`4e2yQE3DB# zB*Dc`=->TIx?9PO&MiJ3R|1Rj@$uDksr1NwDx>*6Tm<{$D<*c1cfcpGqju=g;;zC7 z?uF6$xTJbBIX8+@e00Ck`kwY3gJAkyO^HL1 zz>Q#E{(@~}AucWR3jcUK3)sbC$5+iT<_GHIGw%TS!=efqQbpkXpq?>wd>CF5m|vwC zh^oGf8hl;!%uaz6CCRyQG^TM^fqT?yez(A->z^dEb5P zZ}VgRv+lL7I^z;IhxuBA?}QV-Nn_*7NArzZ4kp(aOS#mPE=8MgHBPWnF zTx5rUH{hQZ3AwC*iDu=yqr7zOyy`UqyM>i4ag#;vhYx>F$!GB0W#y^5n~S}5<>FT( zA(MWt%3yDJR;Djpir@6Ey3($Rfy$~nujFZu@0yyKz8{^z?mP%8GGPc-ve0k2jgfb2 z?7gP;M}0Yem+qEZy)0919nL|QnvvnPGMXjO9AY9H*h&^Z8e+g&icAf7mamFzcQPZO zF`gETZ=ec=_bB~4^@JG$DVZ( z3>p|a-~-Z%bho4{Ns5yZvf&-E{RT%aKbyj}|7%fI2Gc*Yq3q7>@FF;`#Qo zx3^am$QcIMh(5~9DFxFCrX<9S6$&`o5kEWQ&Kjbe1d#`htdQ3(9Z4sfYLkji=~NrN&cP*@e>$EfrxkJxJ$ri-at8 zSNu0QXZWk~YqO=e?dzp^qpWB7T0Vjd5sY)RtMi?|)tbV(KMJIr&g`AEAC+`{2}vb- zqCX$@3b0s1ZoeXe)B>hDUDkVR9S@lVvlgQW(79ve)8yilFE;>Q^2*4_@xyOPer!t` z+~5_;G)x|%*5;1F@NLeK^B8*-DB~c1F+VckF{A8<#CwYYyL5V5JbZ9b%M5%SU zGaE0h*nLHL=40v9H~$49%}m#bFl{ zwlRu(y-vBXVz)d&`3PscPJVpz4zuH-!9F?I&x2Y!czR)*kgFm_ofaO%5L^IBo%e+G zlt!J(Xjir18~{cd!f&%s=fiQ@6j{(2vr!UgyiR1DW~EH8xe%S&M8(_DkC7^BZ7I}s ztTs*sYR#TmPNI|tj*qSV!1}&>!19#Wc#~jYY@q&yo~aeXQcKnDxJ5+S@?h&p^H1`S zd`X(!(vI(MUrutgh#^7S2W|Cs=RfBgOKgVifBG3B#G6#of_U-VVPQVx1z3~% z>wyv%?(xlC!YhakjSzp--}ID3;z1q=j8CcAefmf1eE~>_eE4p_f653+*&EY+XA77q zG(+pU9*BTYx^!U1DuSSxg_OJpdL*2=FQliL(xW19NE=09ssCYR!155%Eo2>`dI|XWX)>jyA>>Ow&5jZ%r5T${&%#tqLZ-q|zIXJ%WO3-h% zZrUb8=_gr5>|OHI=uvlmPaI4)7VP};_f+lOXnrEcmp^goVKr!VHvaNupOu?mXiS4` zQWhOEIF1z-C3yA9u@Dt(oqji{kTX2S2{!tq&y@m`&l9u-82)C&FxdV5JslmLuc@zZ zXQkQ!P1}vh`6-V@dzgv1$Afsu#AllXt8IiYVQ2Qfd(lJj^lADjiWENR{a->={^APw z=I_K+^buX`JO)H!FOU(QR9{bd!3k~`dji0AIG%GdT>x0YbujgU#@6u04&I^@KJyQ= z{lh!WW4=do0V3GES<~>JAx&+gRM6oNKQhcSZ;obaYhv57V2b>n2y5^&%@4SDX0EnZ zd#e^A6hbcj1|nKVx7dgb7%|5C>np^a*FU$zu6P@0CM*8{Jx6mp{;Mr6m&%sFU%kJ1 z*$4p<_X@pXc8KiDo!>U=c`QmUBUt2+^_!JwOG`)9@|i%uNVNHMvC&F^)Pq$fZ;0#8 zJKrACYjQ~An3v|=uwnU)(DKrpYG`n$ez-Y$a_>|8y=V)5c9k9e8XG~8ocpA>CS)LXUG^WvP5hpOHwv?O%*sm&6oOTMca#dbV#*b zM@w;b3VZOkej4xg68v-zr{Q&wNUS<|b8wqFH9MOErRN+5Y(eUK49Uwpl_Cl6qAi6< zngKaG`>6mw#lw&yXkczovraMn?ndI?eZQW1DAq_L*hHHj*u_9juaf<6;Mrkly!Ydc zp4;(H2un2_dt#v;-r!6@QPg*@K)@VOIPooWZlrBO%IYYH!F|!dIeL_92<>RbG9PDkiaUU&on)CRHi5)#8l(`-LGFN0)vkaAXO30 zk@brmjx|SNBY}Qc2Y_zlPx=6S;M%CI9^kJ(H3yi4?K|x_s=dA4IHi1$nvOt-zDdHK zFj?XrcL#5|mQOT|fB8@q{bulm{k8eVZ#(cX2}ClL4@MoeTJtZ^&&^T?RTBD)dPgF3 z`0b8@@Y63PHEu4o8D*SzPM9q>)bjRdq9Hv}^-qVl(2EGV*S1)lyC_i>4!JZ5BlWY- zk6T&-J+v=}DWfQe=E37H!jh9Gkrc^GNA)gvKj3J9<_{#AR^X1kFlwNN#`Zj_`+7TA zhHqIs9-d#Y3bJ-EmDn-apN)Ye+OnE7oj8I{_lo`V;tw&@+Bv?qbG$*Xm?!_n{$drUt)KW7uhB{P)%_GfgiO2_4$;rl zUn3Xys@ zv|E;}-#_r%`+UwGgUwm?8;SS&9I>OrC_VS{c!ZuGpdwuj4T)X1q=>|1WZga@P`etg z7E%;w7y)U~#~SEWtCB~OpBrVf{b7+`;! zE(G_UYIvU>P8l5~!zUE`?Viacjug-X8c1g0`g>KH3(?-3Vr$H#%LhX?Fcr<{#oa%j z8V6BXF@@Z3VIqb6sW&HmFvfSVloof&PuW(IK5F@8)GBJ!GP6^nVLcZ{ln+`epWPmo zmM$KCz$JFg3HSPLGu)Eh9CCi6ban65PlHo|Z=7O0jztaMVZOmm!Kk=t{3P3LR;KJ z1N!Z3xSgb)*)Yw^gFA{ak+bVjXQbp~v(QDS)`60X|IOsCIK#H}_Hd^B+1u5%sZxXq z1x;%CZkJMGt=wY zu6y~8#{ItQK_6ME;+=+~5ozha4Q)mSNc2t7RF^u(3Vps4$D_rzv~#zO2nyM~ZEi)@ z;71Ffvq$nhSh|tOlvjq&ZAT&&MmhEqs)2rlBtO>0ITq}Pr#?;Hu;FMZYR%#)cSTcH zGTInZ&a8mGr2gvE&!TL;4NT)$zegoC$|gu!{Q^9rOVEAO$KqWH6K9 zE}XbCM~cMXX{P10OEmZJLS;o`WAV`#m47)iZGZf3q|^72`vyso;kL*;C*50L^!B>a zgEB+9G{x2?e9@%rw5Io+84N=U(;=^LW1 zIS7-*zKxb|_H9yggw6$|Qp}X|0+!d^U^YM@+4!|IwUb+w<1behpxlX}aTvH>73H#q zIOq6}o_Mvg6t6v_L2T?&49(wbXCeZSq_3#$eZ%m_%bG0;#jzqaW$EKN8lWZg#a;Fy^Um?{z0OY(7@N)bVxp#CmL=kN zTbW*Uux*sGN^b$l=bQ(HOwUa;8>L%#K#n_m3hcg;G4j3JVVnKh$j2?d0?5)-_Kk!2Ymk1Qa-=w9bpZb7( zhPJj=+0LLxi5~a!5?=%~JxmU<TmKjcfw-_j`qe}M#OqzVT`HxxdF%^svM8~wY;cNd>lUV zeOCnUJbCP)x7uPI^Ifdj^gLWbL{mMP&|(20YQia#>TbByPZDD4)#tzQ8Al)VJ>XLL z&80NVx6G)SN@d=|e9$8jCY)JkJV>P*8|gEh0&D!m%~2$fPkYCIda<{hVd4)yV&HUG zaW-prI&ZMI7*tmPhU_y()~8eOHJ8iXxcALE8zKdAGgqe0e8bG6bIL z%RErGZvOaQx*p3IhhF%eHOh#0swvlyna~PohI9TdZk$Fvw4|8=mm1!pNa_>k$Dv6G z2gpW9kfkX@e>#N}avAt6eB_C7q9htYpvr`Do#`QG`@ZihQ!zkPUG4ONeJN7ED~cpy zqu}nxU*>mGV@S52b9-dJr*NlN)c)GApv|>s>Jg)MaLmRAF(MWN1f#OZ-@5|nX2td_ zHU=35p+(ZRt=A$8`rkpD^eGo2aj>-u zl}o_F`efAx&}Wc|?h*+;WFQxhA!ubcPSG)B_;XW!v|V@d8eV=wFqw2MgB{F(Y1=pc zv#oY3;H+nTbqPE9z8A$gy(whZh?=V7;`0z&VS+#A?QA&*Ni&CTN>h+q9s|pD&n~Na z0x#v<)^KH;+%OhHHB~bAA+QSB2Tpa(6NJ_ISfa|1jJp&U3Si@#7h3~<_Rmj`)mS|> zYd*`JSfXhmTs484_?K|Roj*xB1IQ-}RYx9|CzGK%<>ux(V6w42*!Lu5l!Fj)6Z=n} zwkf+FE{CeWY5^{{odIIU52KV8;{0|g(M~Fx?v9Bb60&eH3BJ&k$TDi_*xWVF)&W$Y7$G!xQ%f&UBnr6nxKwq#(^?y^1*5)m7434fd*I%wG z0DIRd!;B;fRjM+i(Rd_XjlzP*Z3D5|bE-xKDtgVl;npa$xZV4l$ zSW6S^N0D4uE1Wh22@{0qq^v9x_wareRVV$v|HEH+VFQ$C$xzQv!dSltVK*mB%|OxZ z=lk?<2ivI~l_*;d_43;fS zfu&Y<|58V*G>`J~RLzMeJl1jSJ-<+u2)NP}R=Om^hWgzly(Wx&?P7~q$ew8_@L~FE zhn4x|M_IIFVgL|S!O6Z^Li)GGy7M8vrm2o8;hY<$h5vwcPS@D zY7`Ez18i?9SYTQ)OB|ko;BC+*kPwMKX*87@wVC!=D zAR)}-V*wPrR1o16LM$m3&!qk{zrLEMg7%?=hdc6%Tk`%Ufi?e)j8loVCZRF_Is8H~ zzJKNZ6(5jegA3tU`M&`}cN+8dfT#pfxjtOflru@kAF;+R14s0fIsHL8j-yAPC-A9= zG!U5cqcXal&+_c-70fzpjH6JMbA%rk0q3F|QgZT@oz4*&sjCPX*}bVw`v9GYIsK?) zYF^YiTF0Twc67FkCbF>jB88M*8{>jX*R%HF>;R4mN>n z7JeXH&!!A^pgatdiH1T)7vV*on^tnwVlKUHaGI>^o@g<&oU*GQbbF`EQ~57!U`p`+ zwEFnwQ&YC|S)Lu!J;@H3M}!0I3e!n0H!=cm34eeu?;&AweHwJfxKTK>fhV`fGAUTHc-+_HSCGx?&Pkl|j> z%s$i4?Y4B^`!@yGd^KZ|^LBc$haLs&*VgX$=Id;@%$BCY^Gn??Hv9BI56gKHp{LH! zQs~41eoDa<_(E-oR@CVtt)vKhHAaqVnaFVqo`07Q_NM3YA?%e7bZ-sKCg*Yj439Zp7+it3<^3%jy zKOeQM)`&8^G1>pVCAr^+r9;{5XO831&bxP`DP{nhnt7)d%iQ! zqYd1XE(8hWGwD3euw3n?sn!OjLV07-dQ3fD3jm>x@+8MH^? z3*fXE65@%kI4aRhthmaV2yr8dYKyuYi7h_~0WPY~xhu)s9R2vf)bPfr&Glptlbrv` zzDRum_nV0n%7L(&5EW-6JK#khJ}XR>$u=ZquahmEh0HvX0w}t*Y!mQDe`|ev9RFhe z>C>k@0Pyj<0BEZswKX;DHR@D8u+EIylW373T@MBhDK&9fw>{pw{4nvkQIF=V#v;k( zMsR;*=4bdWuN8+2Qok5a7q!;^Xc&~_buF@5yV_+~9yzVe2Vc-IgM9P?#C3KVnBM$2 z%sj{-BnhvgnItfmN-h0X6pqG#VJD-_Eb!ACNt|El2p26b8&EO{9*8c%oAFn8k1q>Z zRRj%KW&z{YfF)mC(K}(CY^O9Kz5%vX zuDFqy`92P(y<0P=oJ*z4NtwF2e4c6D31{U6?LFX<#bM(l%7)fk>cZ{UTFEAP0+DFBh55boNeXapTP)J8 zB>cN&tD0js#SXlaJeNGQ0|$D{#yRx%b>SQHR0~#jPT6e4Z}!m~CRQ4iz@1j0_?b2L z<|svaX}Q_$Y_$@|KCq<{m7J#;U{N8$_5I7f#n+G~V0d$;=ZCXTDVJ^L@N{BX>@8rr z@-a{nHu}}+!ZZGEGVB?B_8pWc*39Fk)phjWAe#t?V^@`LQwHnkYZX6mWB&~w{)61P zc9OeqBPO};E2{wjM+CIQy##A(=X(LhGj@6m}r>H+2z0{n38 zfoe_bmD!V@nVFf0Am9`-VILg7f^7dMt1GJeS7*zL=Th~<5aQP!{V#h4u3rThZG^;z znzDC|mWc5-Ce8f9OIvB{|MTxFDb9W%J$vOeL~X}sj=)iaN4!kc@eh1FDEVIBYZnce z>x`yQ#L8pUhg=nx89a#d6H$>mFtXNhGSj%ed0N&Yg zw1Uq8kq{0@46aXLEfD6nPo&D6v}L0Q7r;R$2rwES6%-V@F2^OX9{11B&$({{CL`E| z3D8v%CK}isJ&AFfAz zFV0d2Bmji3PujB#rqLu;RJ=9qyXFEYnv$&_kr7B{&{B$RqmLHsai%;rPX-BzY+BXm zs>VNP#$nG{J}Rp2xLo*rB`IQ-UM=tlZbgj@yAcZW^4+I2Hjc!z)AHwd(VuE>Vq$Wh zW|4iDtzLG;1iL-+vjXcEV0LwL+~94Fz}bREyo!a7 zd^PMQ?}5#LC0AXirbcd{=II~K?y#)}62<1)6}JlutK5@Sd3m7d+>}Ho6N-j2Nsyn9 zK?H3^4$tCdoujO#wJ(S$BPDFHNizL0WT&SpXN&gs9JKEmr7VOJFv{TVd zW-6)})6(KY?~yN3f3*lKW@bUgBy-;b)=zZ_0w<-nx4YXUrPg4ILk@abBuv&0qeAbx zuuwZ%i^)|D3vp&lwoxd1raN59b= zk>_TM&!7Ju(j^a|aBfgN?8#cYLzsUO@}pEU=k+}>t51u=oD~*g(_j!m(OFK49;r;Q z@wf79KnK7`KH2HE8+JAF4>FWJ%OP9$8*2Z(OS3AjOfokONf`3jprE#Z$7%$5{vV!F z!EcQJ#Jwk&;(6uiqLHWri0!=5ARjpEebDm{sad^G9!2rrNaroxO_GYY`n94R;C*O| zOJxX=qQa(2c;e(xgjnNm4Atzw-%_qo)Y@Q(Wj4*6;AMz(=%|*o>Y^QrVH-;K!Ss7)U+u2ju-z{a?fWD53r~2NXxXh3czU|71 zDjRKG*d)8eLx=A=3LpCSyoiC~*LTULxx)oWM9&YvvdHI+zbn;yCMPG2OK2wGmR>{@ zai01Nuoh<)4pnbXtBwiSk-BRHsAJh%cU_2u%zXX7i@+`5muZ_9trn?Z(Cuc|Tuaji>ER_A~vF@}?_Y=sGj z8Ho;A36nEOB{RgZtovwqY@VmhOFvO560Qc_m;~|>WCl`(=Y6>@1&RgxcGu|F82o@v z&3i5(Fxah3U{3;bB0S0rNhjRz8^IPg5{g8Gzg6blduBEVQnWR{SMca0vVv^4t+9u4 zG2ojO1zTpNOFz*#_myc&sGD!T#ZHyZ1Bq6ShgLQV1+)0TeP+#)?pSTi@T&o&7-?Bq zLcH(aU*Bg5xCz$)>Hep99yXlz56yD>N0rq9#iImuzPEb#JMI)Za>Mn8_M3c3Y(P?2 z1t7H1iHQj>AdlWi0A$myzXf^d-rk-Y8ylOOu>KlOFqP{upFi@`X?0#J)K>B;g^+?u zh$_)5#Cc(L0gY&Nb*ojMA`9A!f%=HS5dtwjeZbLo-?D6##xv59&lTCKII{u3;a7RR8&>(7JlzX>8xIHGdg)@Q~McE4o#G z8hKFtqG_d*^?r{uJr}4m0u}-795S;qm^Eke`(=#}mGhL|G0Jm|RqXnpd`q4we`JDT z{5UHECh(C~hw|pqC<&&L2t={2XkScc#`z*a9C%(nT7j~iP4CU==@jAI4N59!C0!tr z02RXuhcFTa9^m)U3v;7I4$sBJVb&;zVI=r`Cv3xcZV6%Pizg;mROm0ai(=j_I;NJZ z1)fXFP!Y;uyCg`GPSj!UWZrGBoWtc%XZpv`N;(M*2pb5;3kwT*fF+l}?%tl!+}zx4 zlb$VjXT8dxEgA4%APNL*9T-}$JO_PCxESLUCiF>IJ^;q_MdEqvH2?|ACKQX(cMITl zthE8(CKhlh?l5t5yxi^UlM?1FV!{XbLr;f1#EvR%MzuPlR*0F*on3{X>w)n4xZE*J+1#Kw+P*04Mrl zCZ^mM#{J>j^l*X*>qj68w}SD3O#9C5!CBDs3TO3;@r$(sW@Y{E^O4&;yH6^DGYV!u z@NO^EaH$ZudZlj=67#7+u{B}5S<~ox59hcc3Ff3ajzY^P!OEIZDQL#p-=gW~_M5NpOh(fQ%zLK}>@Lu;}vf2Ft9AR2ejY z*4qzgy=|HBU%J^XHJz|rdp-h@%o_$oEUeh*Xd(B<`)eCD{3L@cvCSG6S?q7b^K}@v z50J5Z$F(IjwyQR7d7If4c3ifQ%a;cl{WgxaROAkKyr;^3-|0fD$J5Pkj-kAdzt?mU z3MTVR@6*Nl{wW|9mJw~AUVMwK3+@so$)b!z*OxD(BMyX~=4jRLL}I(pTF!&7-e#bCrqWMjpsl|L zMS^y-UbCYakG?9Rhto%{Ss(o1GYMKB$a0ay4xV?tJ#sjTedO;pO+yWR~7GEehX zm*mnsX4zYBcLE`}`$`r2p8K|(>14SbI+6Jq7jkr4x6 zqEczt?(Se}Z2bBy(3j!AWbX&$?Pew>aMzw4HBNh@iYo1a3-@a4^qJ069}?yD#V9w4^<#V!su6ZBCCBa{gvxRYXR(wXLscO$fg8J-yQ z!Vi9%lXyADH$%BqwU3zV7+o)~Tm*5FCsEn_5CLJz!AYtD=qUuIQ2DlPKy$&TX_VR2 zglU5Ol|#(fzqH8L+GnQsLL!!ZSKnjy4c<)?1}sEsy0_iqvOBHDXljw*Bl}nK=ur9W zl^=)sn%e;2PYy-cfs^eO!B5I_ciCUg>1@%igSOn46r`T^My^=5pN4Fm@7hT%g;9;W zQTG+9eD88|lB(L&4!TyN!BdfsK`l^=XCVLsO=5i8^qzk%Y2%>q^ZW*uawcwhtUwO_ z^j5yOs!A`77Pr*vTa^8#b{S`6lIx!!HFeccICx2hSt5?dePsL1kP_p=#*a8N^(cWL z6Tvs~*j-U!)NO1RL*b-i*ssyWuQ1Rze^TCi44?VFS7qRH$Xv`dB5pn*ToC8STk^eND6)WGdBph4XO$eFgirm_}_>1Ty7gznRNWukMlvM%Oe^K;*u0H^2cEQd-&Awga zGvyWJ`RQ2#kAP@4Y0tlG3NndqJiBW&Qbi*6GooD24*o{SS|oQ#C^9JDn)}^NqWaF`U%S_Id^qCC?GsF7xT|ifS#Y} z%B+?o#zfM|p{~e4pNId{piSx(*;e4a)!R`f32r)T6ap zPBv6&>GR28?}=dfirf5d0@55a-H)w(%4d?Qj`Og`RdF|MMAi6F0Lb$Bdk6l`daZ3+ z`E@s?jSpSF;+Wgu5ZcH*C;v5hX0Tru2pDvQv1HtS{9R9wWeBaD7W^+^iC0KVJ&Y4zM+R;98Jc; zm(Lk{hj}g9FHE4d<#}OW_Q>a-N1w^Dp7uq0Z+x0xqoXyv%g9y-M*+2@|J>8?b3i=L zBiUh4+oq*K3j+nBtFN<1=QiK^P;a0|dfaOM3XkFIHzc{C746r7KOc&=0G5~D3jXAV zaMOQ~0BiP_w!JM!LIct?(;oWiWZ>)pOt_Yz$~LBsGaEOMp52SVAWj+Z#CW}aEhX_H zhP4Pf`dPD|lxj8nwYmR`HXA^3w-7Ihyb4;r`V8Y3{AqC0lbAMEGKjJ9&Bs4cyvibs z*B}qUeUtf$n+b@DLVrL9Z$Q<6e%7WpX*j{$+rd^CIL4&Y1VQP}7Qs^`x+U<@n1Ss#}c-&fH?liExH^Cc!2Bh*$Gwt6mvU^~R{fRF! zIG%do==27&0NGAe6J0E>G=$K~T}t?bbiZX@qmF{UGw?8$$%W5(qHdZRq28QF`qY!g z7JTA5Y$zOkIJudgmC`zg|5D0&se|(N;TK!MS@xNPk1@X5GG7UIl?pKV7>G|6+m6O1Qp70{Ga7H(ND3CITZ; z&kW;T^;>(*SZg1Y&5PDSr1keR;7-MQN@_5cs{cYV%E4xW zx_jKIzMZS5P&!TE(lKP+Q-Fyd93|f!CUm|9>|}g3h`LXFVzKtH?BtY@q~ScD+jX|CQYl367xvEm^{<2uM`#mx1|yhA>2 z=^x->Fb3C=3!Hi)xKg$vG?oo%r{^>-EePQ_Dd7fFz3juqT=fva?6|h5J$Ww@bw93* z7^40_gj=gk@!S_IgO9bsF~U?B)PWr@&Yv~*y5{bp%*8SzS4fsFZ46CsK({{?rQRZY z;CJk!R;s7L=W2X}bt}*dxZ{Mhtla-EHrkF}y$)4f9nCy&ta6UKM0tfcE_^E*brnr)#)CupkTMIONu+MCzR2t{xL zjY`k1#>N2W37NR__tT7IOIk^@4m}{q?CVYFLelqE->u5*tb}xkoa`!Meb`mpgBHJY z5Xy6iYZCJejjA8_a=7M)P6hEz<-nag#2Pax35yPf%DHa_w}1V0TE!A@df*uQC4$mS!Y~7s!pYwR0#Nty?ZVKd!ozNmA4b>*R z3atL5*DpNmR|?C%)DsirY0ZQ!Lmt7YS3}^L6T!oF{mijBIF6Lop#lta#bEXy-BCiJ zfX?QdRf&;wN2_;_h{mE#w>VBv56!&iIqNa_ObHURq>6StAZ0VPMdUSi)AAZKqse#f zGlIb4YsS*ZofZJe|n&a=3eIe0D2;ZWPsYGKf4Bw zrgd_U^Zl2H;QYGSiK>I47s|!)c&)5hT>}tVYo7%waywx&0BPzd_1CByTi^$wb8QRYiG)O@8{L>?vRer0=V{TSdlN97>xG#ftx)+j-Y} zWry%bdk}%D?;tNug!r=%?WJnJ&%w1cPm|H?hJc|?-dPKb`6Tmhl&Npyf)um_*G>ds zsTv+cg(veq8Z&ub^2IT!O{Ag=e9ZlRupCHDf2NeH!(tJ-ScEH=5*O&1nM7S0}vC&{LkTRcGM9T`#zF)b6k$`ueSOkPaE_GSq%&n5mSN1tNLv!iS-_F6~Do zZ=QIM?6B0c7L?bv78R0fy4G2b<|e_c(!a%px@o%#E$%8tc_-=eBPXTAbsuN4ZSfS^ zbW0k=;WC`|X)I)&WAJqUu>)u{9BThVqlrjm4Y?9D z^-T94-KusXANpw7WwBp7 z6P*r1Uf--e(^-R0Oc3>M^9@T|xMy38oAD>M+Q(V(xW>+Mn5~AcBXK)-)Bjks3}qET8#YP;GnHt=xvre0z010a?f37dqv@c@EjO2d zeTk_bXEJxsx;yxpc|ZheXP`g_&&&r=`+d1etIj;5N=VUBnTXFx4lpyD&QvxnN&{9^|$HW`3X`P%*Fn&d(KwwFlkh z%k_*}mpNge3e7jBW*!|;t+e{)2*z5%T>d6h?TKLPyA^9X=Jt%=-BAtyqNyj?mY;}w z4D7~w6*n23Aqki$T?Q45KnoJ$l!qGW3-y{6+BjJ^#dmR^5Fhlb5Te4_pH9Zs2b;Ub zM^d=@qh&=lvb`{mG7m`cvfllN;)TRxnt7dXR-4JJq>&N`#vf%I9Xf@xuP4P=BjD%| zL_t4!A$|6p4`{RR02dtS++TSongLniECENBK^6jS^}IuRh#_Ck(Xa|u?-dl3eT!0S zNmC8~ek!uC;#R%U0PGLo~*LIDkavqn~;n zc0Le;PsFZl){clK&8!7eQc<*2b?0PfXEYk;u~-e4BE#Da<3uSyDA1{ zOGv6HAYa8#^vcK?bmFg=018MT74}H;@voi=_L=`WnXHP6Y>5MtP#l~S=t7xQ40~&_ zo&+=i<8MuRzbz%l)A4+e7DiDftVJ8gUWGUrd8(6k9O{}k_#>uYfVf|EvNKw+Yp57<P-mpl^(05g z%bMHw5UZ!TKOSOg_(e8^^e6aifS6n{>pPeUK%E~2fHf^-#PbKcibT+&(9<6o*o$fN zm?g2=4*kE01(hucJ=uZ`Eqp!ME$+=g!t00{d?Z3j8Y3`K)C=|lsEx+uaRGBeQu4s4 zTc-K4h2@^&J&hVsQFt@LAD<09oW8-=r%xfzXnJSvL0Yns3DWbMGSefNvI+s!@j1+g zxV2N?T!o!9>1;4v(r@)g3zU61C_M%J_>W~T+;zCmJlos#`j56Oxpp<18Jn^abHWxq zmXtJPP=Yvrpp>Jfre%x2dasd^0?cVqB;TW76BtK{br{AXU8BH#COj&=(o!wcsL{sa zU~fPY^8f)pC(N@4reyPxyvN{TBIFxWCDLu8(n`oF>v5vA#BwoK6rH49!~o?h^CcYr zXnr>~R$1@ZqigFDJ?>fz2MQ9)Q~7n5VgkeZVFTWXy)~#p>8N3fPL@3e#Lvm8h-kTf zOaM-h8SVd+FcMiphiVCO4l60i-E9D}euoVS%Q!R-)w3H&B~e|#Joak2pb`O$4PAAz zk?3OJ0q39{R;3}*u4ux$bUbUBxBs3)Rd>gaME@y?;=hSYu?_ z9EZ!L<+0}p78Nr%R+97ky>TR^YI9$2^7Z@6j-^)uHpH>;^hTSyn}b{tOI&<`+A&C( z+GKMS!55C2O)fikr55!2+}ywKi^htlq$>nOZ0z*EdE0(XstNN{m9FFsv$q!*UdIgX z@lsv&1?@~oKz_j)Z@=z73B|S+K#U@jWOoE5k%y`-H(?PkhHRcIrw(cY!nkQw#FtV` z`2#ea3;XB2T&&w}`P@lZcUR2q=tCv$uceder3*fEL|+dKFe%8!#%gU9Pkf{zFGH)4 z`x^O<_Y(P;Oks{KB87|G1mxYjG6#QiTtG9$!@$q^pJZY=`L62~G~?avg|n{y>U24X zu+=A_nhgQEb%Ov{O*1g%b)qZA!p(T3)jI-mY=(Cj`5~+8Gc?|v(E&K({Lzr_ngr6q zI-^>K#XiX;!=4QlThvf68xyO~GTT;V)M(on;9vOs4n&T{_@1u&a{7Ig$a7I|=8}H7 z3q`iRP zuce2S5hHuGRs!tJt=j$N_T8}C16UBKshWIz zDr76$g8Dx^xFB&;PtAcb`iO)zBHX$P2h;mPuh+miAsHW5{Pj<$hytJ{`xT`N>grGA z*e&q~;d9A~Tl+5!%D>D|IZRuqXWAsKl{GTa+Bqu-R6PJ*jeq#Q??n&O7dqh>kTeox z`=Ubp;-kO50SF|Q%_6aj4-Jp==H-+GsLkbaL)UMlCO%z!hHIo6RBys_T}h2D>XCnbQnrNM|&2aflnB?A`Ek z1)uisLqFqW-n{X!K6X`q3^&6e#2tcOU#4LG-dg3=y5QS6@Gou?GXp2OiuP6^8d@Mc zi(BEE9cs5Y!)s;VnQkGpu9y%)LIuaRXX#F-yMs(iV2|=;3&-nH|%WJx3 z7I2v_)q6r+gj-5fuzIPvxP5)gk+dhYfhkBd?2s05;NbHHFO~F%mD-8vx9aS-k;ivY z$#OBgb`@(h*-%GC@8*O4A%Fi4+Bi0%V~1aa6E<1Sw%fI4d-TFa(a<#f3DO}RZ`NdM zZp`ZX0KdHV3ND|?*q$%!UVpuY+2#N!$E6_Ff9%r!THHc0jdd-?wWMDjkm=Al2Ht0S z)ttTj>*$D_TpXZFRPsd?P$Sg1lc#p9g9BY;^U$wsoEEXC*l{@#4=5FpEi;l>-OQ)} z4NkFqLLl=k3{j8qe$dgwn{=cuhJ0s;>sD=tzMZ)!ytmF5Rdi2YS%ygG^@$Zr*zlNtcHAl-YmtZ;y| znG`W9c4kTT?PEsk3e*U`pe?*;iSkrO$_XjAcB7!0! zAR!?!O6j3AQX&e{DCI;t2cuL(K^Q$6l~O4gT?0jO!epaEa*WYz)X3-Sec!+9xi0?V z54gT{&iS14KCd@3&<|vc?dRY5AYmjR?m6Ff_OaCWq@Y{Jlkit%Sdl)9PU6J#&M30S zTE)ioEnkuONuOSkH6I;jy5sGW>=3PUNfTj)o) z-(HK2#rx10on>d~GTe^qfVO_&MT{=;9r#UXkUG0G^dEUL{@v{p3jLiNyBLRJEclb# z{+t`Q0x1+A7ORs|syR0_mhEA$RqSXyan)0N??-M^kfm~>cNqCd#D?jioCJxb-13T4 z-p?`YDVyOVpqzSeb~74O-XyO^`CnSfijdZ2NFZYBO{6`YZ;w!I9Q^&GNWK8D;vX?~ z%kjhU@XuB4!>On=i}pJJME*G6{1h53-||XcsyM4O@Pn>iDs35fO>TM#$^}59fmg$7 z&9RAAMO_5wFXzGH#?S0%AWWEb$0NQ)&se!kEsuBj1dqdqhuR9}2m zeBw)NnL4k`#;*F`X`PI>>SDhpj^`(C>C6+?bSPZ39k%iXU|1l|P`&#LDPr zZbiT?_aipcz&u=?zxGY z-1j73WF)DoZStmg5)fsao-Vijk`XBi%phNUa1CYF>@}sie5FjD`Db3pa< zqYzk)!k2}8R7iUAs81kc+GbMelK+_Wl|gD$EX(qvza8vhQkUfJjWPF^e_;Q{{WI7H zvi9)PZ2-Q3$5F3xMOf z^H_vdW{62Sy5{Ev6T5{QW*Pzg2b6p%9(_7pU@}qdb8@MTC3l6*Hd*xlvWuvXQ{$UJ zMwp09#a8sQlaKJTZKbh+abI2#)zG__9@wWf0Qc>@p_BR(`0*L(K<&i<<7w$XbvM6; zf($oiwuC>umW;Gx7FDzm%2G)uteu zPuER(Vh5XfiLo8ezX@{S+vHsXMihlI@%l-a5dwIIBu5uqs1?y)IGZ@QO>*@x58R$0Oy|EC0(c zS?8pRT>Y7;?QZ6i#AMbU|GnZwxt4T=P?vM{+oi`hpn->2U<4=xq}^?p!+K_monIE9 zwMD57=U!9hz!wOuJg$4f?-!mh_l?5=uQe$T6tWuMIim2t=KG$b9siIj6GK6Hh%Bs$ z`^~=RT%i5OAXiInYp%{4-=yZ}1o=>uPIty6PNYlXZM5ud=3imrlbxS~HT#S>BXiUp zexmFRh55(TpQ-UTHxcG#A(2ypwRQ4VZ^1+yQ(|r`(MAyw*GH1-{dIV*ZdzmCL?z5` zGD(3o1hNl%o(&elI?{T_TPJ?;J$5jB(?9{w9$Ba}nr$3x>^ZK3-3T@BXT1Nf90Tkg zFwu|5TYxJi6wTmr5@8$2$IlbE;~%%I3P?}-^U(EdMXHZE3PmIgLC9R%w4%|}G8SOx zMI_WgO=_qb1$m}#kW5Mzrz2;9V%2Qy*`0{qai8~W zgN7XOlu^-_m!b>5@UpB#vKNdoZuxn)@IMmim8)zi>{xN|E${jqu4z-ZQk;PFgkQYP zU#_s`=)(~VH{7qh54;>U4`hUU@jf!Y!Bwh6Nb#+bnm`l6pz17>r@Z!m^5$4 zrwM#HrR8v|J8vSJOf5~vfbScA=)W}7@ZfsvsE|!laMX<)juFe2_dYMr)L(!4H~x0q z9U`=j)kEcZ#^Rbgj2rYUd&EF#qpco()~wEb#d!UaaDbC!2H*vs^#n#%zZ<(mJ2q5_?cxNrh$Ibq|-le^bd?Wxa75S zb7mYPt84m?@^(>sSFppvKBZym(*xAA;L2&zB|~n0Tfww@nQstp)nl)WtuVnhHm7t8 z5>{d{hj9}4b)Oe~#P-1KdaQ-cfs?IMv*iA`P8x#9#&>2@Da}p>P%EVVYs?k{>W%YS zl*>0CCtMcrNdCfWzm%yx|LZK`{m(elzddX#`jwd#7{Pa41T`JAx&lixn39GXwpPBj z#Zt&*-M7Sa>5joW;4p_M$m8i3GKznhDgMMltH#*|z5u**v9cv*ogny6+x9+&R{v|0C4JI{4QUHZxM}oruzw-O$V5U zxHPHvZ~%>x>!8|Iy8Fk5CK?aHY|8KK89!BTvqQu9)>3TM7LN06DetRrA{*+mxdgK+ zoxPW`85?rb)Ez2{tYit9uQfP0Ne;1`mchu)*OSW-?OL|s8`COFp9LgS7n_~D0|sJN zUhH232G>#Z?<6-aXFzWnJ`&Mv(@77}UUNyN-H$ofw{vGi@|W*4y3+A7vB~k?N@dqu zKC3#ZjjhG5!Q|Aom6vUZ@Zg&(^Z<}faJr2kqE5#?K=>#=2s$zVu}iHr{r`jkaa9ga zCu|ux8-4}TJ&l0Pu{!lxrb}q4cvLfg9P>L#LRPy^dLeUFN+npJi&3=)D04g zy%(!m5y3SjzAD#1d<P1(@`45&IIDTqCnN6HRS+n-u?1q*0wZ8bmLEY#=u*>jr% z4Zp@^>2?{0cs_z!?)K$-=;l79Xjj%>2Uch4H4)c6(FV2R%39$i{dT}i{zy0dK>1qE zdVXQTGS(9p0Bb1v-P!St-#9r|!1zf32BsTe7AmpEKANSq>+z(w5mhT$$v1PdXu4!a zlM^pCBzgSOUtiV#rNFs!QV??3Z+i%^GJGNs!CJ4_dd0^Hm|p%zT5(2CW{P1$wKv+q zgZwG$3`L@ZHvNoO{4tZW#n=9S9oK)b#tXM%P*iDpz@ZUfaZ8669`f= z$q@ZH_`X;sWcO@F%}D}hjxad}^(a2o$Y%7~u+X=zSm|ip1dmJKp%YOEmX-H}3988Q zbE{&{mS@xj*=l<@r~X~yq119bzoUYn)4o0= zFuSc@VI%zCnfiKO`ud8*;_YQGvNYz!x@JK!$i`)5{aVol31c9)(+iu>)^zZeYMG|o z?mK#XI51#cdnrr=e}P@hlf* zH0P!H$n(-LohgH)c!z)9^Rt;cLDS5DJ8BAscD_Ca%>DjV{iu5hzCc-bHI%iK{3Eri!Q`M}h$frfYas5? zURjf%Ax}MEUbV*f-K($cG2j-2klCGYAF=Zb&+(~LXg&Ss3R0H(c9a7wrflHzlyjea zhxMotya9%WSr(-tikUK6#}d1wEA*`hzT_0>+2e08wMQFQBc`98046qXs2EqTogR~) z>G2Fr6>>)cp2=6TMKMwyyp@V#vauZt+GdO+MuL9`fcfYW`CKxlhNGW4D7ke9_1u~^ zm|VXpKyq^NU^aZzJ|qH(-{Nc?SVP43(*@;)KoUnPJ!~re+agNw@4v58RGiB14fww$ zP9s}qPOcyNDV$uNh^>5f(BKK$A$XXSd=c%nDyVfR4&*w#;&uGy_Zsh0nyU>RVL==- zuVU=opc;xT0x^TOcj(Dzfr{VIJwE%!DaFDZ|y_Gy{L8tR-R! z5i$^r%r3?QyJaOxGRI%I*)CP?1jbQI+J*$%2*r_w`WYpny*i)m&bomA0T$2hjK7i? z;9++DD9e0qgW;An9&oQKh+^~37@bY(uiFwzOs@`!e*;JVvCz$xMenrb+qwI#ETW0` zq>=-bjK>@1ukNwo!q*_df4MpxPRLx@$CDd78o!!kx>+6?Y~4Ogp_V))w5+`FV3zFI zssG|v@Z_Sf(PD9i;oH8S;Z+g2o_y~Y=e2`!NZpPr6@F8WFCKpgr6MY&A;MM41jUHc z-?^H&3m-R}?%R)}a@sfSUMO@1GkB`c3d>OsP0g%V(%woG7Y&z-twbbrIPcvpYQO@O z$r>}si5+lvxeSVZ)?)h!edc%eKc9(oWtK-FLgivHK8`YpIXDs^>jxy7bN-f}4bI$! zUcB1C1lam;Fk}a?jh48TI#&m2y+gA3yW(zzuO$Z{68C$(QR~(mNQfn0D{{;EPIB29 zOI;CvYQoNax9Bb!xTUg1Z)!0FQMgqZC!;*2>%lf0xb@;sDUlqTCz>KE0Zw^-slqyD z)mA#s>+d7c%7{r;G`LUxvQa|jtVqk}^HGsM1}nR~X9o}ghgd`8WXglsTsNa(|1P3g zit*TW^(CP!@4VEw=vv1@?&m623~zG#Kdo}~8W&)3Z~S>ZoiQL`8r6+AJGl>Xs`vz3 zjsR0NpsIXwl}_vNp^7@?_Q&C>R{u&smlN=pxOkr!%$$x+5-S#(4SrYGJkr3Qu*WZ( z0oMF!aYr2BFHY3!)`#rJTPw_Th27l2)c$C92A$T5=i_M}5rw^XfgVcrWOCr?%Eho$ zH}p7F+tKpx<(XH0%?T1C(qaLD_=U!Yb(K&CZEA{kQqXWRafx^q?#uY{s3#d7m!QvA|}w6i6A ze2e)4&CtKA)<{zH_1ovXw)9nY465&)JhV2wqasY3<{DvUe@04`>9>8_%|=Yy1qWaq z?xw`JwOwgzP*KReKdK#IHstF+4}(;ru8g_yOdsC_!Fw_v=d+E^7$!~H74W5?iY98 z8R{L+`KD(&ey=vq*pMWPhS~*n$w*4Z#V!K{eS#DPNn;a;Z?Rc&7717fDr9Z(FJR+u zAIn8ocpM`D*$`Q-Ey|O|taxqESdITXAI}tu4?rPt+`40g-|ReiTctHFX|nZ3{q=S2 zVZk-K`A`BuEk=`6DhoxMcVCFH!p)Gx7it1N`cpqP2IcVih0~14n6|{Q*dMknUd#Dg z8#K}QGB_2b1WWjg!X^Rzl4NImDbv_wvhzdE*e&o#(&~K$RRea%`u)CEjln775MWyC zk2fqz3_y*y*!iD@{di;@T6MZ}4(6>dr$pQjmTq93svUX~J>GeHEG#&()WYNS_+sVI zqE4x=CVS(90H!(gtK!oeM$E)XY!pSFKL=r4(PX?Prl1kplS*PrE{-&_r!D7WNONga z+xh%iv_#+kLb@Vz_7N>$5SaD1Q1=Z#KzcsM2YS1!6#9Bastot0zHqBK;>68+!Y#2S zcgDg2mX~PZnjy@`bHN_+@CagmMXA5HC_0{GrD$F)IT&9K+7C5#alZNwSuu|rQD<}v z9)3IqT5zL%*lN7oxvG%~<#j4Nxy z1lc5}n=b%p=@thydp&c;PRGB>>Ie&8QUYd@2=>w|!E&bjhZ1!hZf zxgt@1mUn!7Gjr*@291t!?1tyln`oQKOf$=ryJfC!4><}g05yTFlqyYj=&yJ^M4Izg zsY|1*aqD3hua2{D^bT`AKz37R2Nbax95!=si`M3v&YnJROzIv#69MA`)zwX#-&FNZ zduY_t8Q4saF|0}zKq4pF@bqnbprA}D&}AxlwwkEkPTq-?b#qKEyBd;EY?a9eD|;DN z8dx}-37;4aYx!DjH}Gorcd=+@ZxmdQZ;JK6} zcF8XW+%({bZMxurEvS6Xl@4M3pyp8w|0-$y)EJ*m z7sxUNn$UKS3x2Y~pBW;XtQ)M&H5g{msgwOylK5NU$8#%B3f9UvRB$+PHI_Ajx==MM z@dX(VWb=x?rbo$S*mA`n&5@=;nN61j)^KK$c+J$-!HdSkPOd#uR( zg->s)vC;6f`--2MPl(D_1NYDj)s3?Ld)k>vug%rN zmZdhOG5cRGh!t^TQ=}eh5w|QA0uP`H4_jPqksL3OPUj^U5M#OOyx9UaykgoC@=BfM)+Rq`uJH2%(_lVr6Pw!qB{NssrP7?6IT_H$BsPCwj{JFp13x@z9 zenHKvaM<1Hc&a*JIA0W&uqKSqzh@UiY4*qfW6FQQF}K_pU>?EFIi+SK{!c8SIhudH zQ&@46A}SwMjl3buIawS-4MUS0U~Hq9J$z#H_6y&(A!Gy+GC0r52`uo-bb@NMXUKSf z8x69^W%#Cc1xNGo0WEzXonReJ6hx#gNT=}iFD@9TZ+yLkv&-aiCMr9>2O&>vjNV8! z`J)#L)TE@2f%%+_IFB5haVV@;&uPMvezV-;n2_~##Cx43{0#m$u`288n2;5hb&{>C zHJ9}_%@x|7^W)oB9lr;yU6)eZ>hWM9c}*KDcH#UssWIImCbd{|hOnDvO)^);KI(P{ z5ZtU~)iDKMMhucy)_;wEmGf)}z zSE*NqQS?T%iEUIh@Re%$iDmoJOd&-uLmptrj$^M>FW2$ll>-R&Q8*@jE z0u|cOk?R>7;&>iIie|bM;&;&RoY%bk6A2vjuuPUQXj+|($Z-E|LB`~Ux&J}0zI|p- z0;JMC}l*I1F(Auv| z+R9~ae+KI=3P({?JGFh83kR0At3Y-%(!`^dAD|s=hq?3|&CpeEhgszZ8(Y_Z1F}*_ z*oAaerfe#+*VaVa_Sg_rJn329@#xZUR%B$(-3QNk6M4_XtsAY*r`B6v7%`v?<4&p* zM8mBzc37u;okpd|ol=MtY*!-Ypcm8JTsx3>nB}}C)t(4_Z*%AQK<*c``k771#5w`P zM_n1%6Tr=&+yhO;PZYZTtb9oeD`VJx$)~^o^s0K<`P#Qh#3r>{$H2H*2o67s@-Dc2 z>EBIb{{Uw;TZz-=<+Jqs7?2{IzE%CfHRENmTh9X8z@QxoMy66NtIfO=Xx43oP^=z0_LjADe0NcmnlH{HitkWC1i;*Rz|*7#A)5Zmg%A)&xWWmdyHn$BDh z0L4yMnm$Ct(cXOm02OKT1Fi41sQ%LOTiz{rw|o)szj_Ii`YiHmXJ7rTp?J1A4=BR~ z3blm2n5qnjuiSw5RR5;1y@P!C1xjbw43Tv#lrXaWktzbAH=AC_$5TE&t4g{T3cUhM zRB3=y`t*|eg_*NhxeK!83bOWAR$&_nCiX9;YO0HEP=9|+n23KeI&h}ec$C#DiBH#I z$@}~9rfCGp;##!C2F%FK@u*G=)7@B@7cGl*U0dj>9zVDPJI12SovXT1O+^L}F~MsU&zdeTgV3ak9#{;>e5MX7eh&r=TJve@WtN`N*dbkOMVk5cE%k;Pxc zm>d>!-C6Dvm|0l>m}{=SKD}a)jC3|H&IWDraw7Mxgz+TuWA|)hQAf5N^`{GT8CIN< zU0XG$J7>nyXt8SP)6t<264CsLU@gvlYb_evb*yT_%L;|{ekm&_s0E^(pDR(b$j3VM zU`hM5M2LOEAIe0Uvvcltp{0uR&~SOr?yOw=zs({@22!U4&L?i^qIuE9kHM)mvX`pS z4jf8+_-#8IB67Q~fBBlEDubye@F#w?WkNsssU$)Ze)H7>VRH2qK_|E2YoO!_4MlQ@5p>#(F=v(By7QH%O} zckL~UyJ|}3guPYn_TJC&%gU5=&xt~89Rlr$>lHC7uX_xuS+^4DLJ!HJgF_)uv@FCv zbDB6GHhoY4?!zrVm{9E8V1*>_C744<*j~@*(t|rfpY+W3Zj@!+XktUT&9dXF44D@# z&Cg1&6on|!IP?w;Sf7&);jQ17_uA!dBe2!$kmv?-0rCgH;y++628go_ zl2J|wFO7pg5EYYyKX$?&BK0nlj;>@%%=PJQof!Wp8toCV#OclPiclR#A<_Vzo%K=t*(8gs#^I@Oihz#S+6T0v4^7TL{+?}GffWy&MzLZvOxci9jqP+w0RQ% zQMi+X!vlM}wo3KGy)R(N?p0%|Pz3Uq?>X7>+klB{SjIXJnPgC=GOVG8~~*4)GEu&o*zd)}Jc_PJQ(&>b;# zaig7HcmwZrBUN^C0bNqYlT7RnjISzvOqCDM+zQbb=j$ROG2KTJ<6=!xpZJ7TpI(EC zyymm9w>oI3!QWl9sdE9fnS->68)87bcR82d;zWE<{<4nm=F3Zc9NMIJUp!7}oelsN zz1hE`6vbk)A}p0L_O7$|_r0eM`!^o&dhzl2^YNb7e^AVtcqJV>#mxS*sVTTH>f*Ct zxc;YiEG@`u6;+2HLh*KVP2JuK{zz}IA?d7m`0O$)JML5c*7dW>C=MjQ!a8LtmV7XH zw5YNOg;|oS6$_oiN~+JzLi|n;w$oqa4Buo_0p@jp!a1t<TrX(jl|MDvEF!9sWuiaj)uRGwN5yLk1rO?I4yQpJy|TKbcUM9UGt{2mLGZNs-gFKo7qH`CwB~T}{U2Iai;e{j5|?lriICCBx{N z33^ZXL?DWHl;uVFGD?mhogqKufySAu` zWn?87rp$nO&fyZ2;YnH|VB!lcBRg{$gB-@<9!@iT=16eJ+;c3j{scY;#S4dYL8H6`4byT) zajXvS)(lK!*dFB20Rpf>F@@-09?{(iDE~Ih(sW$p8*Qu^5MNgHw#C69IoGoAAurm! zwBxp26`*Kb#h^4A_&srGCN}zf1U8 zwgILXiXi_ySq~+cx7pMG9lUN};Fj9T))#0~MRp!1=2xG?!=YjEV4in(cCJTkobeK; zl$~>w_FX)?TEEdJdcob|o~^0uyELNr0_!Q)mGazV%N(+3L|_9+fV%T4mUpt=0l=t1 zuBmx8i#$6x8CmJxE>FDqxY(Inq=+w-i${)OrXnNVSm8XH3x%K=D6+2E7($s(+@Ju& z$=x_2rg1?QRbCC8=S;Y2{M`2TdnkfPB*b2cWME*HorbxD!5=|^z^!q>Lm?0Xy!lK@ z%0lNypm{y;j9scz=3$VXxl+Ri3GqRx2Eb(qn^=iWEOQaUjOse*YG*%i$a?Rbd& zl>ePxV?(}e3B25AXO*2_lb6NIqm6r6HB_{yxW#w%PA(9<{w64amt@jud^=iS(Y5dy;xfhG>3()FHj9x@N+m~ zd)@EHpm5Clr#WoeU;2z44v(i_M<_GLd=`=x{`t$-zB8)zG3facGjwmuz5NXkjb&9qG`n7@!TlTGeOFL|K|RH7h(jXlBP3tCk@5WbMPX zuYs$^JHvI?GCi{hCqSIXbfYZ8EOpI~|5NgLnp?sy;Bn;a!{2p4kjc!jNgDxcl9K&5 zRblG)#WzY!tV-ZDLp1@|XbJ2F4Ujh(Ny$)q)skj#-|-tm&!8pU*z2FP77s6cQyoQp z*mlk+WjFTA@X0s2P|3ab%`~gd3~dv_1n{cwADbuO*#u*f;$-f+Gu0o-dmUifdcYuG zWW;m*G@G-uA3d**9$r%sXpv3I#@%E?zG{?Ch>+6SZnMo0EfBYqD5bD1pNaJi{4g@c z9W3jp4PkWPt9HYdrv`|PdSU- z&e|dhMsc(s6;{2Z6->@I!;?%D^n1DWfnPKg*s_@F@5CM}6fx^QnZ#a-$LM5f1N_KbpaA{@+ zbpZ%VD@#kn2E3>+)ZZ+-uIE)3QSO$=h#;m%wP6i?q`HGq1w#5zqoygM74>17 z9WY<5c#OvC0zT~!vTI@0=1^VvM?O(i27|XaxN{-(2qywSDRaBNs>pVB93;I_ThFwWlW*Bst(gdJKAk7fq)Vlg^ zo1DN?xXzBp7X>g)mR0I&alTS!9q8GX(t4q@N2*M>b48R`=HvOTm=Kiw9~)eL>Io2g ztGB?vCsHs+aUSTEm?hjq-aBH|GUzSdQ!Y+3N*dZR4#yiU0bN zZZ|Q#y!6ABzEZKQJ%|l_?g}eDh-T9 z&cbja6zf#em2!g8A{w4okqUSqcQ~hyAXB@JA$(X$q4kdyx4EK z?ESvY#Kk4>-&&fsA4E2%c$P`&Xz3?j>{Cg_>UVNbNy1!n{x3Xk;b5d`>$qoJfs{-L z%8a(uA>NVf*UU3{%YlSG>#wQWxO{Ti)ZR{OdNbf05B%~g>6Eb;6f{GLBGC^&*lRo< zFa-rEL~y>jC{|(c@SPZAvOvT2IH_aRiW!}vKnp`Ynq5e#Al~97v|>4@Fka6U!{r#Y z{oawh>i7EZr3w3#;@M45K8P2z znZRwN1Dr}2*SgLH{yo16^mHfPi<1}))*TB!+1xd~bD`+MpxdtCX9GN-7nsx?ZB8!Qhr!M?LTR80l-`d}EPVz6N6waPwon>NzrHq>D-r#-GgS^}eocf@tt+@$Z z76OziAWAEJ6&T7h*D1oM@z>||pGTP0kJR9sY#Ie)Qtve%Se!7@g?LUo7-^WA>$rz8 zV~>z|KjwaEr?2;?o^V98Zmf%w_xd+F&o0jY)ES_>d`K?nv2Y2C0W3KpLZnF71nWSo z$AX8EeuYN+wr!ebwaq2pmwK?EF7>I+!1r$JH~&C~_r5lrBs@J9fchZ}LLRq$nvMh` z$QJj9QL0!@B*rJ)+-CSDMNCSw0YW~UL(7YZn?R>#^)cAxKwqb6qk|8{hE|X+3t@2~ zr|jj~HG~FfKFkt~^}M_{aLb+~W!a^&(p*TO&aJ(HOyB=mU5^#frxXu(P#=qI+NcJN z2ma8nl9#b%UT#j#w0MB+ogZd!DCTA&>+C(nao@6J(Ed2e0IsP z(ywU5YZO;+ZaLkOWbs1)M4h~|n|V|1Plp5xM&2YC^ZPS)>j5|t?=X31tLvmktytY| zXMA_BHDZA@+U=WonfTOv64}3!?`I{7y{S%|W|*0`RYKg0um$!$qr(>!*f?SU$o8Gf zz?^D(hjnhDE1bnN4*LrygPh_p8u@h_G`DAjy?IeXIUFKZ>6#!Rqh|Evlm=Acva*q$ zm=(!z`YDFw-fkTkUGx%GJY!0ieRSPxPA;xlO6I~$-Bh5;w`X^0_#WL2doleGxLCUr z`lVcvW7Sr6T$(3g&%I)j^VMNtk1V<#Eab#Yd8ug_ zK*DFYKwhBKaAkB&-1rfSejtV2Dl_W@I;A?K3(zj*wd@`;nt~05QgPE?5z*pX-f*y7FPU`IvEI^`^t_KUdcHyY}@i?c>chbMzOVc*8Le zl}5J}N#LY-G3_`X*AVe{OO@nt{P(M!XkWXNy#5QFjito&6Z`apb@oB3X2F)K^sD!z ziwZWdlwXO6zVC|IJ<0Y&=YsI6nUw{-yj6#ugt^HAlcK8M7HM$kC)F<1V-e7aF+ixS zlzr0_zNP+bp?@R65(tFS(!dJLbu9XDBOmYvtWx;_3Sx~==V%R$hXYGk#T>SJ&l)*! zu^M_Je4IFgb!VHAj%|jM$YXSD61%;)gS<0F+`zshE0-5OExHJz6V{OYw`EdsR zAo9Ay-Q)ZSDt~}UXI6k(2T{;dNu%7lle)XFk&%~{22*W)JQ=->@yqm-!x{7SSPTy>F6(z~j0 zI(yg>(ST_iv~*bha2#-VaOj6i4%?gE{5If;@2afXM?cajeZtE^QssE2%(Tozqo%3F z`m;0G{THE9QJdXD_{yH$_vZe;csiM5-40?MiiR>}|230eBN ziCVcf@zGESUm1BsoSc3LN4-wH>_efNKSS~67Af*$*=t@$1Ij?7naXD*wRW!&v~{5FJBmn6(IEH5$uR(fs_Ol7zPh8HeS%`b9B;PI=m31E*h|w_h(Y z{5sy8+@P%#Kid1TMIFCca-re8tRcnQ0O*#nK?$O3no=8reXW)W$Hnq+0vuAXT?eyy zi_`7IcbetGo11NfSy4O$rk>|&sB_@1W3+n`rXVr3*pCm^T!jO^;gapKg)T8i|kBiLX^h@MW?>;8uKo!U;W+dXJtpz_Ky40$&^Pg^3}xO z+qw@x^Z{dRB7$|}rd8IvW2RL`x_rv7Y%O^VkL(3MEZ=n>=#PZJn1Rl`%|8;^^Y@a? zX^aui#!fnSTX}(*=*gvDOr(z_n*!il8_9UbTVGd-K~ z1N876$=xGcxYPZAPZY&C6HenbNC_d1ybQLZ;eM`(6((~<0jbnidz{gKT6E`9L>)~% zwyZ?_WeZc#&UBTT_AN=hrk^Sgt1REnLPZMNLH~NA2hZ|tkm;aJJK>__yZwh6I`5Vi zlIht*f~*z`spHzi{P;Z8!cP!yKo{^LJ<`7}&Gu*A zyTq+J+IpnBZr4k-Gn1z*yVScq5qZa|LF>%kgWBg}^G;Bg2b+HTE0m3y`(hOeX%sCRnZ7op^uMk3yaY&9b;a-6cr-$k6S?wx*Ky*yFd zD}p*0kxhYQfGOQelU{salWtX*F$^{q?=(45zO>g%>3JTCCg9+zDf>r|Je(RT9*j*U zEHoIZY(S~9CY@ChCD|2_Jj5L89Bb8_CBztb%s1BrG`w0R#KH1THg}7q`|98I8^z24 z2zzrVGsff5f!ca|0R!k|&nU4*(}C!-KEeFxZ6q1keCarWxJZNGmYZ|@O6H`$5WE_%w@8YwrW6#dnyyMo3S1_`Ga!3dez4+$ASo=ds zCQX2Ov_I&SqfH4Bp>t++>5jh*9yfT;DAs^a(!%HSL5|0p?miH`O~#JCLlhbPRJ?Xi z=~K(-#-jBG!~M(RD9&2}<-F}EqCEJDCU~VvPu=4Cx{vsblkLrtuWb( z0CN54_tCQJa$)6SxrAi*c8fG_{!k8F!yO68xfx9mI$E;z+0SQOd&l$BooUv5xB*h{ z+pac;sS^yi7yn=li}mIY^K z`aGmfMgV=(Lj`{Ie09i~5IU6RMD?$l% zb{@BYU>E|WUSB7s)Nzglz}<~bT=2d6>eCl8^4|VVh8Bht@L0o)@pEWt@m#`6YL9=R zJ9kIuzp6d0y4U{lLR5#Y6&GwEagiM_whh4ReArYabA}ss2wO)GkV?+Su!_U3jl|{S;gV3$u^X>Ik$0gN!UbH63}bPfKH8%PJV=8$qLuMyQzl@ zCt^j&N*WNelqcgNMVwO#S;~3WVr1Z;pdpj7)(4MeKZ@7im|e68=S{_+RHD3R8!G5r zTXRK+&I{APf4wL9c_#1GS08el_}b4*;~$Yz_;I}lM?Ty^T;t}lc?j;cV%00CZ24R5 zNW#iz#l%Gs_`is?qtSFcWKM9lAG64{ub>@6Zhe7UV>GnCgNZElJ_ta zxXxiahD_$z8z{H$F)48r#XinNbiqXD(SG9LDkEJ1Kwok_+50|4x{nAr7)_CR1i_-v zePFifVbeDAGYZQrkh#^e?m&jA$C&4fvf#*QTcaNf0l$W!uN&omOlpfMC^_ ztvB~yuZZ-Wz6i^aBP^b@{yfmsnVc3qzbNRG*^6(9!2!)~tcFxp+HMqlBFHLpGLT$I z=y5JYd>F=znC$m16i$)d;*1ZKd|>x|!^Qcyu=9|N#p93+k$D`$@M*DXJ*9gd;uJ!r z25}RpN9c};Oo=WEZnz^6$_MKeT@yrzs|P|M8AO$7C|Wfw;CxD0M!zH4oxBzeHl$E- zWzXy2x|=Kvh{H|WprG958_w@J2TcjWXMJUR^W!BpMt%4;X2=&Rz;+IN!fNLn_#(=T zAN_j-!5A5kJ!n%#riO)S3I5mbBtgjY&-E}?@>Do{?*^H2#IKOU(BhQZIig)nJ_HWY zvE7bRc%aWlZI~xMIM{!!`3n~da-sPUa)w@ZJzue6gmcfGL0v)B$bIHU1fuCgvn%Co z?JPR{2$;D{KkhR!9X>-(&%%kAZP3MdcoIN;Tp=Z+;lc!omR+zwNSyx%ONE&1#87l&+=8p5p7#_O>o#)sQA z3V8_pE&DC}a(xdx>_VY^Csm0U{E>NBW|IDM_+e$e|Od4(^{GMErVGj=m1ZsTOW$)ts;O=VKyj)p}AYm4rJpl7jg z*>x(GW?wl%{eA|m-Zic9AdPQ%-1Z{BU`0VRZD87cPYKVCGf#hneb{ylGgH_3_EPb4 z@Z~P`%?fV<3H%cfQEf2a2FcCsWd`s-{aezg=;=_aNn(CbhMI+6)JKQbxWVdb;bHcbI4kx?xSvVA#@qU@E>nTHGkzX45ey*JGY+i= z8#G?s$2FIRDkg(mY;_Zhe6KQWCS`?$|D|?+N$w0qRWX`gkubi3YL1|OS%d%Vdp{}j z^lQbI%tQBpUiu$e{)VcjH?PB{TVH)0ajN~dI`Yy<;LeSAxh6~0sDq@Kx!1Y2`+9!C z#zkIiZLdNuWCnsgi$FFEUYFa_xj)F0bjm5j{L()}V7OM(y~bWBmMdaNA$*!5yC(}@ zbv^zLm^wDN8{%+Y&`@Pi@co%*7i_D6~h$E(9{7>+-?0aBW%Fv@ertGGd*B${j5pe&uDNS zZg72{?gALQ!aC`v9p2s&vBBslV2D04S`FLh5#9E;$@yH$^m+MG{0XV`7kSk`<3HPc z+&K|yf!(f`$2cEz7|)C|oj;LmBI0R4uRWwU?|_;nBfe)%D)6&5kVN-rMpx+HuLWQq zye>Ds)DGp@wrQV->P!gFqs~PiIzcMBIPcpJ2b<@lz9T)a^p%y`;`yiwEnt*@I4J@0 zzxRDV&+Ek>z-Q-uu5+F1RQUctwM%mXy5f}$ zP~woa*r_L=vhj0%2mO`qYxANLH+@+JJvpXNo$$y6J=^}MXt6Ele7tYHS$7y2Nii|q z<0d+)_qY>%UXA%%$Bu#s@teOo`ap_RrO2?yZEI0rkzIunWGsj%!nN8sv~Bb(_6`jL ze8MvMvV?^il98Fjet?J|!;hMJbKKb2wME(8XEAqdsY*qj|1+-E{P>Cb@JsiAKvWg^ z0?b3qdav-CzS+2>6vHZ8=?9bq4+t!vn5=p+h*qW&>QABv$)>~Wl8_#1p%hSYhKqcS z_#`&06p2_Hrl?n6!=&upCPyVHs->d_mRQl#a0O}PkHFaLSi+SwqmQk%rFdUdk!+fD zIh`B5h3@B(OgEyp-9k3kCSV?!1ka}C0gsU12kHndkxc2B z&Xk?vl7}`l=7hI;Y`_{NVY$Q_lNz0vG@KcKraNqL%M2E) z4ZbXEdwt^~Q1XzU9^<|iqMbD{L66J|oqHX%oX>!+T zuCFGwKbf_#$c|W~i)A zhr;f;OI<(ktNza$(>F|90p8GIpT-h!Ilet}iFtDM+6(-1SU|Cm#pO17kgJf%vUiG& z_+_spIx1K$v#5SbVQj7}8%f!3K~A5!o{YCxXKGGEU*w|y_xSvS-6Vga&L`v(%5q^% zyNHU>J1H5A!k1D14tVBMW&XHFRhUlI`z77}6o*sD1Y0D+hJ)<%9^0W; zjR0Dr_b^v&%(dFTNGtd(%ZiB^>kFqANB<5uKTMSjpx_0oHvfZh^aP*+2fC-Yv8j1> zA8AH@R5`rgJRrRAV|`r9)^zS79-XAgJ8`zifW2O5d|7_?EB-44*Eo}OlUZA zDwx7KUyB-_Y5oW0szk|~M->>)JjC)bJP7^9uu=}Ln4uM~7nH(Nr>BL*@2WQ?9ow)@oP^Fo~N z&OaCnwIytMj6Ms2#^G~m|JnC2nG~1*og=0td-UAdOe{(h(5!BNw3(Qk z3jl6%ZCw-;u#}&>R+I73a&V=9CB)Md{`R#{>}qAC#O)0Bk3xZF(;Y9(KXi5q zHi4hf;h>|+mHN7rnT*-iJ|QW3w2lFN8yg)^3T(lbl8^k!I=dfv9JqTAaz9 zNu2+KQHL3wl0bUrfHP3ov{)tPCz~@umJO+9H7-9(bPim{>_Fo>{hp7OE?|jh*hT6* z@r?7CxKVgr1nj_?B?OkhM#VpV<^mbghMcO6`-d3h$JasK%j+biaJDck_y( z_^F%dQHlNUG)Z^ejzdvNYln$f@7H%x;+ut^<50xZDGL5T8p04Q@qFTJaKh@L-amhq zxaL0c+e2#ZLB7AL9*l6=LU(>`CcP24o%GBFx4o+U-za!REE(YR^*iF&aU0=Y6rfFw z59-^n^iIVdA18+wv<|6Yg_cFddwUbBzi<(qW*h}E&nRUB@|%p34SxX*Mx#12Jn|6v zkw8yZY@qu+mR_=S2Ks=Fz1+}Imh0gANEYb(uvW?!UtzEQ#%~(Q5ii=f(Ve)_(;jM)z|?j}qKD{v~qg zKOqv-qic+&-hxB5;miG0G#L&b8UIlDaV6yhpX=FloOzIil=P1kw&8llaz6t=)}7H_ zvOm7^Bj}E|MCI9JGDT6 zh;^7Ubm%E<$+S>R+!kLVANyse0}LxORXXgb#_RSXm4cvH(c@m?%n*!k7bloawy5M4 zG@#xRRDOoaq7RB5cwIl2-^W*-?{_{LznA=SG5vqhVR0eYu{5Ri(MykUBdQfw5>N(3 zmUUT~_3ttX8L9sI2;>y)ba-m?OB&{j+rO8$diZ#J{8_t9xrTk-2D^>s+HZ?Q;PZ>c zSMu}gyDN#jdd5r=TT)in5#&qg6{+{X$ny#p_B;@^_%CKntPkb-s`Z3$LPKVFiZdsG z3fs+194c&@$QN$&fM3#?OBtqTu}LYLEO@Ef1I(=u(36_HWBsqRt@@9EUu}Wu>+{lI zT=~_}WdY0Ot>g2I!%u6>dJSZywF&@y^}CB21>1MtPZb77LEzZuM)+`jlVz8+5gpXAHG zKbP?7kB^f5~;^Km9x(&oofC{niVTQ*^y8-OL;~*t;dqofjTXDxY>f_i$_gX;za9jqw{j{;P zg)QqP38i;n@9xO^pTkuY%@iD}HTFX_#TJ9_YV7sr;qBm>itej+e~{(k{C@pQ3U2)d z=7jjNPWJfW49^rJ$F*LJPp@4hL~N~E)}%{IiwX;^)qi2We00@YH1Sd6BYY&yyR`LC zcveHOt)9`yC9j1^A{)Wjvdr4q8rVT{MAO`GOLjW_H!9X|kBw^>+C9=vzN zb2$Ndyk;KL$Qm4L4}Q?P_J=?eS?!4X>B7q>q6$S_L;D|ga6XBED9XF1-I&S3hoRN z^ch@m75S@Z6JU-L08s-nv>{HA9)M?#>>x!=v{qdl_>93b!&DJ|g#$%00j?a(b3o1<|B=k+wlF$*4Mf_V9s4l zFkf(G^Y(nmJzG${I>qVx*5@ZppiIG>H1V%Lau2Vy7Taj5cMS`bEJ7@(6{T)zG7#6$ z34N}zsDEGf?*l^vX*)+dZN+!90na13d%r9LgkjUeCIb;K06_)ORC81yUNH9vRg!$n zW9L+2oWH0kZ3hG`pp45$+P|6o3V}2RL*}Y=yhY2bvXz8YLDBy0Cl~Eu9G6VgBN3Ow z>U*TRduI+qV`>3ZygThFf?DaJx#gO4)ss-HCjdy zXsDSLMjQE!3Cw*?&LFJ3GHAm=^98;gQ;=Na=iTQSUSwmmgm&{idf&3Er6oe8*{NI)m4t}R+?Auaa`J!n%15uRl@O7`djC`4L4H$8Qk9Zqj9JbvkS)n z3<5q&-kr~{X|-^;JvN2=Bi4J&?#|?c^IO1COaEw?6v#b8>7j)sf_>%=1y!i>Iqb0=E z91pH~3N2ttpT`HKs?sq}cyOKvZ@jJ{_^F3$-6(8Z%eHY@d%85ABig}3bvz<FUK$KL4E*2kGyS@#>`0rwa1Y)M}sk)s1rPSbhu zfSnGLZQ1#&}5mA8Wtt<|6W;ERFm@ zf|N$+uePI1V9OY{JoK57f@eaX#QqkT-6V25t7 zADM`S{57LidvO`Tx#Q6;bpK5SL8GZuK9F`H5aLs%lR|Kaa+#F)4K|S31+%5+gK$zko-gE%-4qCqAFVxN6wa8MaC5PR()}m_Mu1{GD_HF`EHTnLP zkV8qFt9!^xf1wH^Iw8p4JAL0k$56=mFH+q*b^GEJra7m~0DO%)w-Tkd#J!h?f$3dT zhTKVC7apWs&1v+3!2)lb)g>{lO>oivY}eV33CUAz9)LvH%Y#!>AP@KOjar1BO>1{>y&N{e?Rt0 z{xCp(5N;T8SJ!EcI*vbSvIrU|CGj}Q{KhG(9iqLOf#fvT%nZ)u=53kY<4kuHmaegH zSxr>*NDYtFrrt3A6fn|J>HlS-K>ktsHwTY0{}HL&Ebl8*B%_S)B=C6yo_^_CwT1Yz z7uW;Z0J=HkPE`fHJpE^BnOwe=mNq9?lFYkWo8{p-t`LW0rs6OMnQDpG$YVr-b9U;S za5GHmj>rJZe`5&=E|8=jvzK-eI==c-RVjLA{qU;yGLDwF}`tt^=ncrB|)2rNp>?E&I<&htbdoF2$=06GUkS^R>xdxFp3%v9-s|vD4 z%8s&Oq+k4*n9r~|85-+1I!9Ig@#}sntcKc)x!)W2+moe7baGX;Y0qP3{Z0RE_&Q5^ za3&M>cHpWlGg9vJ{mtX7+oP~krEF#qzb!EpItn|MZfmxcwxMqfAn{C z|HiP=7<}bPxOB-G2AI2AVo(+OA;-vNIRVF<#ar-8X*Tox5%*6236vICC4g;6zl(C{ zn3frj7)ToE-C}(?`L_3xo7XLqRBx5G#CgjG;#nR*xg#s>zBr+m;?~bXBggYh=D7n? zIZZXl0!MAtOzt|IW+Z`7c`^9AtwWnL@3YTryci=()g3V~TT~m*>3Y^{_cq3K4G7|j z4s-=N`;IW#nK;=KlzDobJF!Rb(_d;O^fqrhGDqGp1(uXt3QO|Kopk^`ZqpMjjLPnU zEop!|g8iQ(%DLbN(q8UE5iyw0ru#k8BRj}@TYF4QdkrTSc`^i}*y_vyujI{|>S97# z=g+a=ZS9^bZAXr37`aBFjF&r*TVOQBKDE(TV>(wg+L!{Nw0=C(+?xNnHslHMW{KrLlkm83|<}Q zdfR?z3|rDF(Yc2c`=17RW=RK__*6=J)mh#5n0`rb_^@0<#V`loVVvjD|MNGO_<;;+ za;M-NSuOQa%sKdIj~RVqJ69r$57K1AY40>D&%G=KSu)8az(*6XocEP3%bK75&tnM@ z{yAcg4NtzrNcw4M-&j5vZS^QSslL+Q^$u8uB~H{by0Fynm?3nz3g?&ZsS!D_Y+9*< zyOhuLjd*_U%AQ6w@3yr!`z|=^YZt?E%&cqY3rEC&=Dt7aw#-gi4NHc9Vw83k7m3pn z2)u?YBfL%4dqH^1JaEB1y^b|AF_g)Qwhr*JKV+Fv*CmV|Kf2<`NfxO+NF}~1L?PLI zeVCa{W^KN7W7{mXgRC45L-oQGc^>Brz3%JmxvVzcWj-OO11p{M7-fi@^f+^AgkU)F z#I~aFgMrqb{X9PHZ4O%Ja?lDPE|MC6twA61;40|b!|jfxZ|&}NTzIqQpZM@uAy2DS z{|z2PX^BU#eeMqlQZ^c72QHsnNouKe)KFipFOK=$)Y3uUN{e>5+)m(tvM+`Q#~<#- zJ7Bfhs3U0vV!lIa^-I0QDdI4Ack|Eq8_+z{fC}xT`%sMBT&RNUeKWv$T_Yg8togZa zC4qsRI-T_BhnV(0NhCzc{OEc42)N<6q-z&N^i-GkQ$>y=m&=DLjrpiybz0mrUX@K6li?X zLS=yXL4T)fk`KRDtZE;l5P2Zont-talIi`cO*;82uG=kKxt=^1Qqy$JL_(~g3Cdm6 zHbGXd$dU%h)nO*d3Bjgn_?G;Yd_$^`)j8SBJk_nORtG5-NY#M!ob~g-A4Brr zt;=RDtv67!@){~Hwk%&m;OUjTn`y5{nIzTt>URtOR?W9OB$2J!?40o8W#_@Q*Y54s zi(4S10}9s51@#u62C`b6@&&B*VA_v`LayH`IsC#LTPVNKkPczAic1AAS3Kq=$xHR$ z|Ic=65BYl6<3VHDE4PzbnFxe27_^rg#@b-Ncz!(&I&qc0J0AutFVCndx}IP#+VQtM z1U^4u;deHug?e9i+<_>^UK0G_!2?L$zL@{$WQtzLY*mxc>nW6Ka#(s^PEL-0L>s*M zJ>WYovBCd^LDB!5iYOf>pm%ona$_f??y2#j>R9OTvWGD=b|(XX9~H-ybVV|KsH^5_ zYT`$KeEL2DEC_lBs~k&a zRPSD^m>L4#ULDqA#7R;Nch}T%v;9<3OJNIve67^k=He0MUsjAjga>H5Y?A5*w|U2! zAr|PKcYr^w^x|)IIUFCkaV*LBLiD$@_Dq+0O7_|> z5xzz)+1bm&xB*-JjVWY07zXL-z3z;U`vUa>Yv)ojvk_fZ?D@m5Mur_f1HDdX$$BqU z$8&JTJ**H#1Sc#JW8p(w$S&`&A4J9JPGD~f$URCLnbuE-9GfoE&}%aXYFkCOb?#Ld zmZ%*QqSFw;uiMidgW>(sUl$8`1z$WRl5kC2?0$CQz3wq4K%9mzeB-(N3buS#lLP8! z{$Bg864XL$@PF{ffen&gH!CFYP4a|a@Mw5t!wwu$#>Q#ZM2ipasxw^WbNO5fYUs>b z($h}5+T3stu);ePQ+EEWHB_ozm;bc)I@)d;YMQhzbQF@Fvv_JVl74I{qmQzkTFazu z@Y(sYhc5pZSNdr+15&irtf`$UiopZB?4=j-^3srTg+Si@CGP&Y@d|<`lX(;kt~(Q8 zomCfYiWy<`^N#LQB;lc7K-cn@)~6Sy4^=4>61NRkq|@-U-{KoDHD0FF&_ax`-E-Fu zmyp*+a_}BFk?HDk_V+D!7GFYO#qpO~Qte8((}x>TyvbEoC+NY7^-(?d5Es|8F}kqb z@7{9uok}^_MpgT5(BI%6`pk|kiH};*USs)Y?{6(zA@T;i;}pVH3_lmWoscDVct3p^ zCiT!f-frvYc%lu_aL;k?+g$vuwt9uDU0~|YTw_)@*5q}XF7Y7#0B0e9O%ap}7R6*+ zpG~mO!ytn)`^;$pkMVmRKVajC$zylC-0j}-N8M`BGQS z@03hBdY`z_4T97PV;e)&1GX}RC1h=!au>O1*5X$Jfs^`ofGeBIFJvJasPZah9JX*? zSbQDEb~!rV>#qz82mS4ZWV@f(pICJ^dVBi?E`SY%(^^Q2JJoTPB-4iP5seUQ%1{u$g7L#_hyh4-whv)=0jr$Sdj@waR z=q@&dRJVKcHlbL+(rerpcjLZJ$-;e4H;C$?U)u6|VR$#c^}5+n~6ey$e3@dSQ__SaX-|}D8?hV zd>)5Hn^_7$u_%*K)x5GDnJdpx2K#uzQg=NJuPx7)Dy%O$eRJ}Wr~}RjJRO#A@>xn5 zk$@2>n5ukR#^xxD5#?LO+r;X6BSeU|Hu@*MfX8T$>Y?v%DBV|KiV6@9czH{cIW!Cd zTN{-ag}N81K5wkFNZv}D0df?NlHaZv zamw?d@U16;tbNU|_0x&RBfai-BKJcYBz>>#ztkH9Ja7SThZ?LdrXUX2GS<|t{Y1Rp z%jwF8=Kp-h-feDsd;UJSJNu6NQY>>@Z+K-zV%-1uBV98TmBAw!RcI+zcRX9+3iaxG zH$P{01Vw>bqG{;zn-)gV;UZ3nGzd&zte%>>e~T(_AM#wezz+W|@eT|T&8tFEyGuf^L11WF0o*1UA^ugajOyvF<L7(&j3ne2M=&n-umsARFr*&nYgiUG$5~To>UKj7)w#)_Iq9nof@k z27>Vg9Q1wOgrM30`KnxnKzcg2dO1GS6dJ$YIFF>KssC-}MV}N&$JoBSblYF^g@IO& zj*cL{o8fGQZRQToYx*z;(s9wkNOgw{H_FhGqfps?3_v& z)Q#hKuQ^^^$o;+Tg26(JJN^SP0N-j%+6nT{MR(pd(x%DXA9^R$-$*ryCfWr|M^F0l zpUf&hUo_47VKX9QhhFrlP31B2vGJD<_DfuW${imwtyYtM++oz7jjw30TbFPxVb?WQ z(YFdeEoxZzQ3}kOi9{sQp66M39(a^W6Ro-d$PA3Z|7()Dtgi7Uy+sflOdKpkdy_Uy zuq<_i(}gcX@k9PU;{=B9Zy`V5g*J$&zWQeFgnyT|OItf58Mi!3wRWlE%IexrmS^}H zrn2@_G566b01N3rOWH ztGbbLj-}2H5KQ|(jA==8eN~tFNw3Gni9K@Z+2uD&Z=baUp2k#@9_@g)pMaMPmz-1^ z0afki!`xxWu)W)dA$+y^gmFzGTUGdqmsFdkbU9h@)%Z zwt>{H7N~Fd9$c+O*q_i4AGZ6MP%TOLdiNN8f@&-;?#pL23z2aZ3x9LHHhU4V>u=)K zfVR>Gq0gy(@8!6m#+A?GCr}yKh}qQcX!>xB6k_i;5HXeFf45(heLY@lr@&cKkSO!x zFW%3b=9?t~doWBqPWb?p7N-;-@T*osvM*5j7QSaMsxilt&HSEZ>LxFdEc0n6M6m5{ z>TwNIf*KH55SL*$k9Ti zkgs)H8?bK&Z;ZU*$cdoU??0Y)V&=1#p4*{)^qUrZa9eP(oZ$~v>4+GZ4OJV-%m3ZV zP%bm~Erh@-6ww*Vsrmu4@7ve)SG<_7eXep9DcftS-UE`CDddu^R9a&<@OLT6HnC-YkCpN^FS;{Kmu`;*}n&C2blDzNQ`Fx}8 z?=gNO>E#9j!N&t1)fzS`Z_IOV0 zso?a$4yGvp0fh>kIa#$zC!q}?v>oB|&MUjfBItj%+KKS{&!x!zRL>NSG8QE9 zrAiWwF1piPP-#^Y#7BRkUAI}t!D)%<4;9Y#Z_N?Dlu#H`pf%;b?ITzU-Z5#|(PY-4 zT)gwMxj5!h26rAfMV`y=Xy$OM$X8NNBMMI65OqjP!-^&XB2JIHlI7o>hqy}cP0c1@ z^Ay6uO465v^O^_(yezyv{ zLUP3wzC^$AeDQ)Rcjv)G;(2gprWEnWV<;xWD%=!8*L%s8fhKCl#Qea^vA_+{nnOSR z%K2ep>AO?IEWh)?4ws{a>cCY19tVFxBHAu25zO!7lvT7#r;OYVk1H~76T+xF&itq1 z_Wyw$vzVRBUUx^&pp*ZXoZ6`nof!p1_K#$~Pi>KTi7u~dXX@uNB)tP`A*E+0ifi3x zeXchAr(zO$B9Qv}v}m5KCEqAV@?d{bDq+eJ$EG1F_ z-nvTJxAEYLZ@7*`!>EqB@=a;7XV)~bC3DdQvrg==!?zG&M~*MGiRF4(--)GPBO9Cz zEezE&JB}@B-0*wX(9&v1b~BKuBjvQ!We^^Tz6o0cNR51J?`D{ial>BzSyYn`^hH{2 z#lqxclh>ZxTAjyY*EU4pbHnY=>nbU=im?;6WTw1U4VR$8tN^>pnIh2mmJcQ#;)pHZ zn^288hb&d}i&-)Ja%z^LEPz#LWq49b>Ns+L`J3^^UtLv-X@F!9oy2n5KCp(4vuyO1 zI7^!2tqy0>)IACbL0wL3JPee4C^A9{G8K&ECu*~jl`zY&;Ofh;3aZqT>g3ssjEA?2Zwh!75D$vy8X-JFiDLQCQ%yckY&d>MPjLT0_IzFyua2qfvGsW-CFggn8!x=(~A6BhiE-U zOI>a6h0t}121C#(=i1YE{Zgfh&nX`S+i9Ne1FQ~Kb=(S0y=Y#Cz=X@tBmz4BQO|j$ z0u*7wRizhddU!Z81ldP~kEWN4fEV!(bHC9QW>K{d2u58{ONXzAJ%7v$UvV9$G4b9> z>Tuf~NejG<*U={6$XB7j2%p0nz^~B>s{6@4Pu+Zitx_L|DjdAk%i6q2@uvsjWe@%| z^4`-;ppw2J5U?H(`)J2l9>v>+QedA&bMUuMOH_*G^0Y(Vz9N4^p*8q<7v6T+#dUWM zc@QBcM3LA8j@kblACdS~cAN=P1VfUqZQlCcwzWM8aX?EsN@xL8@#Ep%@~|a~15@1W zI?(#=P|L=(cP}CCN+z{expCzwat(8S73a$KA`!u2Ms@n?G*&lLexqSPSBGjBH8Z@%C7LUM)~*qt2O?<*Om00s zKpU^|9#3H@ZQpY#RR`1bT!DNS3z#oxZe?COI4V%|cEDI2lqFM51%MS)pzctz%h(#U z5RdG-vJUR1?OJ^3$ly+Dhm&cmP}-_ z8HTg=sFJ0k@$ARyhLSn-c5UfKONW_t^>O<9VI&R2Sc8m)0MgnN?u;u#3$9;yFPD5+ zgv~|N?g_X38}bmT6+bEbtv5W4>fCP&{P-@-k8k1Y)l^;qfttbXk58R&?`R%(93AYJ z5yOuWww-GtO=)|y98H4*A39pN7(xQ9C!yN`QdkaM=9CSd?$=29=lcfiwd+ScPptyU zs-^Uj8MtDd>b>Ek!|U_5@G-_X5-9yf+2u+=gX1dVG*>nZ>=Y~0qNADxxg=HFcUcgQ!B$WhJl5%6$U?n#+Pr5~J201U6(@lm(+)aT zLa~3LN{+Pm7xim5DN)KlVzIv_7d4hrQ)hqbkh@CtIr6}~MNE57xZRJ9VioTiFTw83 zr?wBtReZw*;z=P>MRwK>v@&14mM)eM7**o_?1Y{#heLjxePDkLwB@)HPf-$WmzrKr zH9khcX084t@HSBOU8hAJiN#`UbxM8a$Ay!zJ{T)9e#&<4YDVX!Z=5mmQ8wC=cx>1K;_Fo7>j`Iir-Ru0VGWXshks! zGKfeV(ePzIcH%@3m%D*))(jhO6Qd0+f$U#$YHV0j z;_pg^xTds?j|sOn$aD>;FWl#N-~HM86vTvejcI5PW;gleTNJ1C14e%v!>1gd-|BJf z)4$Oj1_{{c3USWh9;lHI^HyG(rF&eJE z`>mr#l3W>fzBse0nlO^_V-NlBEqW%pdWP!h=vE2;*G0rUMemvUm9RHlgG3aVr^1%% z!n45-AYOmT;;ELHu7ap+e>P{k>_K<1&&F~@yhhyUq-6@)2Iee9xDVG2#YPscmJbaJ z1)3R0mc&@&{1pFFq1XZ+>(X*x=rviVnhQya=E zztf{)rCP$>yzm7DB1&gSm9ca%RQSC64LM>Q@QFJ(>&8;iZCgy)_uRFe@3wyx2?oUd zi{N#XR^6q7TFW&tOLOfuBVV>;SYs1o3&cvr6!-;{(WbCimmidM1S&V%{E&XKxOk-o%mEIN?nv` z0pS7JZ6vrTLlIq_Z#lk8@#T8az_H|6&`{;i!a*S!89cFrpD%A)fdOWhnXnpc`8d?n!0`&LeTBLko z=p_vvDOd`aWon)7#HorMbEe^TrXdsM*LwRZ6w^$@a>4%E<+@zR>tkP}>$oJm8}nzJ zqiidClv0S=uuP$)MYDo7t-`E=vSOjyi!8aPQNK%N2ehBXQ!qS}VGoXHuIKY;-|AnA z-CUQOq`Ru4kudf_Nn5*km&z-*urtQpH(T=%mq zI(DYKSW4g>zW~vWn6hPtnx1m}%xkq$Iq=*4S5L0e(x~s30e+!Nx2v?Z)2{E@ZLEAM zc>#`xRz<#+9fJ}2SJCKJlHMmMZjX+EXR>Z{1K2W3N_JLO2zPjT(adzNJJn48H^XnR zM?xXyZEwl<3chK6zBn`jDLEP#suX0cKml2DR z+LLy@ZkB~RegPZsqoG_NVy9{qv60yq5xhk7PC{Z7s{!Lf|JSaWLy>ti&buQ5?UZ*5 zFupo{-vz=}#NB1NRTBCX%BVVh{dYv+ci`{tMv8Eee0W=A+hIj3o!8Z@9z>Xz!FWiG zMFpQhu!cF7gOP(tRd5PXoE9g=|Ne`tG4s_|9dF#UWK#ZjDj~5`%ulp&8;+Jnlb5ld zoybpTw02%}pki!BGl{vF=1DI4fxCMt_s&(3(MzX11!v_-xg(p@UAPBI;feU%NycwJ z<9?)PqRtW^NF<74;_OZgWgYFxFCeq!kY{D}Xdy9s#Q-$%xqk$FxDsWZadiIPA}tF_ z`|cA~bwY43M!74wjDUE_GsbZF}qi#$vsewRJOA+{RxZ zl)yj2I>3sEseBsjF3+zZjlVoN;rw(8T9Y=9)i`S0I5eyb{-&>UV(EIV`T96XrdqI& zOZ*C90y5mgtfoA?QjD+?#_V{=q86>&%_wy zhVl0?IO>&#Wb!TJRWkF%)Wjr|#ahCr7AVP=EG@`wK^Pxt$3om#ShR8TW0g2G$;hy3 zFWwizyc&-Of;R5{7KtK{sIa;66)Mo0u!P3L(nH^7$h7I~uVS_1&u$O0N+oa8lG;NE zb#Ib6ihJ${1cFPW(uxEWgcG9G82&INDi)G{Nv$)=)!~RsR3mhMl*Hci0`YzBR}hZL zPWZ!XYKJ2%?xot9W7^4@Cs)peE#x!p;w2J?jfZ0%(~bP-m`i3Rjh0a2o+Zqg`T>pt z0BT3|lUQ>xEt#4AVO00C8o6#-iR@J&SCaY=Y1nzq)NoEa?TM27m8qy&`$44rALZQQ z7ZHVg#+fB44Bm+4o3sa#Ogzw{uM1Y;)N?p_9ljs_>T0)tvv3;<8O1C5 z$nDRdYQSk_sl}cr8#A%F`-Y~5O^Y9m0 z39GJ(_S=svAgJE zP0jvfhqc)-4^QEO_O@XUi#GJCabe)0uO}tCheGyU$A1mJ0Tvic;-CA|M>q3(WxC#a z2R)ndq9D|1lI#v=k&@UxhF5N+&+2eu9xhHCJUIo^&c<>A5m! zCD@%hi~lT_D>v5BDo>R`Qzk*_eICDdT3iI>hi;a_A=ef7HO->?^3#pO%3r+~Y@&DJ zKo&c}uF`>z5p%zK-&CHR)1$;|c0YH(CsD-wZBU{*9i_DA)hpq9GM~O0?|9dK%pn{3 zh2bIjm_}BzB${zZRzXv5r$SzN{>3@VFhBTazw*t);Id{p=Mvt*nwncz+WwjovG*F) zjI2y6m+y6z^8fUN|EnRPb=7VE1)pqh1Idz*a_k{>aaj-`meK|zFK2}-gksU9!h^5< zN77pBwH=Hgu6^mMlo%exQMi-8gHYeIZa;5Ve`(i0=5gZfgKr-)+BI!x`g<+7)hNz{7>>v=&*EKhU5UMFU)=XUx}<|~x^UO}!cW@K6*j#!BwDoz`-o0P z<4VxaHiYwI!RwD&v*;w}dBFyUih26`Pbrh5%(7d>L%ex9@&*j6xO=J0g5lrfEYyC^ zq`ja#S`_Tg^vv8m5f*H^^%yjSJgmR9+QHZ>>kW7E%ZSA32tl_d%2nv1OLpto_r8>X zj02s}c_mvn@^sh(Pw;C7OS9}6XPFj$Q(!*c#b&S@)wMh>jiO|E4kuGFLS%o>O6B)1 zPVxBwbE!nA%Adqi79CDy6+9Ut)=-4g{jO8Z%`7Uh_XlY&a#Wkxs>~DbpdzY%$6aVS zvfzLTE#J93C6~h5S!9ZfQnP$n=oDy7+&$o-RB9R-$oJ$3#{|0nxN90KnQRKL!8B7t z5&8G$P=$o958})*fnZwuIN1y&-$9zdii^x{2>8uQy~q z-j=$_s=)L)#GH~rzrR-r-J}B7J2%-Ck22z7FHn*B0TcH=-&Xq6h+jvN$B|F*R{U!NNY1oh+O&=dJhe zOJ(0rX@}~3Z}&7FmxcNA`T_nF&VE{7M6YHLu*Rkl7q2;+5HsIRa&oz&$$oC{MfLe^ zt}(BaiIuV?5iQdY7<1;k)J~34?muy-QZ-Hm8YF$s4}Lv++?D?!pD96;S|KqkcAs7Q zqml{-r)`)Yb#Tso8nI+A=)B+cu_VRp>S`RoYWsUj0NYMOZqA8y_jPYC`q#w^M*+}7 z0CQpI&+Wkk9v!n1)!^tOY&wk6cTH5lUiO+>d`0Q{-vi(=h7Dn%HSY6YmA_Sw>A|`S zQe|9UremBtQY)hBGGJ?PQlAXmxujFIXIb^h%qtu!1wq#GKqa^ySz%iyZ)BXKFG;9p z+43{R1zv#oH|@(V*68Oop<~)Ol0gn{TFkI!atQ#Tg8G=X(||gzwO)X2%9_Q zE+;BalXgw~osE>dd}Ph3C`1>PHZ6fPe8AB+mnt(LpB?p0YeJc7mgqm98B-H}Gvy#c zmG+#}n7Tu;N&nEpL+tri;}`FY^FK~Iec58w(RQF1a+l-(smU7JqC=LJN-$)Ab!AmM z2)L(zh?~kq<>yVYl)^I#PMqF*)==BQ&xcLZMj7JZe6gx#K(F{QEY`Mn3@lik zUl1#l=B%{E5M>IBMCe^k%-zpWWqw_Rgka+QVi(1u( z&Zf*vI;nCxR*3q$cBZ31Q_+b1!yc6ghgpDS7wYa^Mm#uKixhfF)a7 zX&D7WuE3K7;a_z`R2oNEZUa)AAAwtj(Q*+JGCz{lD72G;)rPeT(TX2S31NEL9@B?J zg~ETL(2N2)Ip*hB4pAsC-jgwIl2PqSC{Ot&ID+;C0J+s&1(K^|8ax$Ci=0M3 z)p--iKIr`+*Uy@A*|)^j1<0M357EO8sKxzv?s~}0yxa-2aESdKQ1EXm$YS;R>Qlp$ z&|K~u71QIl#h7qR!=Ml)B;Miu#~gP0WbuYWCOe}=!t;h%D$dBM9Q|=~MaC2&-(UFS zZhXcF0g~XfG%3&@(z)Ixff$p-z~k%5imPTh#R~mkinLfOm2$NY;W`7_Y57Kq=!ERc zZ*QBFe4*gi^Y(sjG~!ErN{XC`B+ZZ53lzdB3&ODNjfJ zHuvEI^QY5`5t%0j)*0T{su@0azxT?hbrmZ<*X%NeNg=Xr#!L@9x;m(Iza%F^lZy}wEfF!oqx;v!1 zyWgAV_kCv=nBfm*xc9oxbUq+5*wKdJIH#@@TUq*QC&5sr{YBSk|0kAa zQBF}Vx$v*@JmJ_laY{)#qkDVxy|bo+1!u0*BC{ol8p`*Ix5e`?!QooH~6QWv}>*ilPM z_hqlJzf;wF_{aE@9lN85o!R4@0Jq5&&|>D$r+_TXvOtVo;V8;+po7NIqwwuN)|cMF zO-y91Qs<(Qu`ghqq_am~us5DCEx{Ru>Kk-`^W;0N1k0qi3TDPr z;U8M3LX3X@cMM-nptX>(rD>l05>n@aT0YI^H&nmqKCxCw7BM3 zzs1~LQ&LljC@%{wP8nyCIS8rT&*n=)_$WGg=nsSTrJzBKm81%T`izx+jw9_BDG5)B zN$lmqE)mD?0>hvgYUq-dYhuls^&S#9sd1VvD%6d8bQDSs<26`edH(q zWE6es1kOoK-o~K8+~2QTzE><1mPn)&iC`=NN}lG|P9Ptbtdy+yrNNZ+NrUmgS)f28 zNL0hfWd~6e-yqyN-d$MuZfE*sc!{;uYb#uv=G~i!3(zgC+yM=c8Fm7{ll+~U*o(C@ zg(NB)tWFL2{c9nTs6sAw-*tYYR~Co=?WMwJeZ`R0?V}uDb-Uh$2{)xTZ;9_)q=sW>Ji&Jw7^qhJQ@&<3f9 z@wquXRYE+q`Rdo2YW$lRVa>_A(ujKOrcOaZjx{8 z5B|H$+qriF7k2HxCF*=kPA59&_UfX96c}4h8QHKa7F~f`!Q`f@|0_c=wC^8+H%pWG zhEyJ(Va>O{1T!Y|wJ9j~O$$AWI6i^S;_g@aYS+Mn>mgmn7cbN8n9!0TU`2UFI6{y-UEWC1?+A|9vcp2n`DI!y1=u-xP_>`6YO&4!nNY(vL zJvVnT2fclqv_(+Y^FwkxsSCV1JaO8x^hSUE#tH*`KE;AI|J|yHFSEG89Y-wj3Ag%u zML7`4E&%Z?-$1a@y;PK0(dhEp1{!izaG>TlXK!MeWn;g{D@JK(pNR;<*iR{1nmjRT zQWZ&(k5xM0!Vj^N;*!BVl9oo~wTdc@mK{wJbPtl4SCFRCbdOZfDh4c$dcpf?5%=6_ zsxHRXEVCJJx1UH@3Xx}Xu`n>VT*7oDA!3;N?F8>HkK+~h?p=U6d<|e)P+NUI=)roSxo|GJlF^QcCFc# zbo{|0a?!T)57$^rW|pl{!9b1a+sl_1Gy=v0(IOTN=TV|85ZUx^0;SgA<43|1KOgIF z`(CailsYN`K_VV)5?pQ`e)}VGs72w(x-P)WInJ6SZS^v6^I0mJI_kP$O#UNNG2$Q5)2x;j+<@cOvEEWN`uc5DwVo(V^DA zX*vZkMW&k_xJqDm=nT{5mxeAkv#t8=xzMWmQqL!EKD70 zvV3ET(a`;4S5D{}2#C>kH_-{%3gP&ywvVnYh_w6lxEAD9 zIyG@hNHl$~plUFHPjXDJF~!EGN0A5Mz}QJKiGCNApIfY!c^~iNK4QnCbdv>%@w{FN zc4O{nGBxx@o=Y-tkBh2cfD@w9Nh>_d>jhS~Pmxx2JB(L4EuIBa-rK2%!Vt+#E5!-O zwp#rj`6J|_g8gQSMm2jH6N$EGxBXDlYdiM(;6*sGxh_uivul|MfC*!%{&0=g?~I>Z zDkpGbd4?SgM0G|S9b+oejG{y-C9<_8WeS>hYgY@QDb zM1X-atKT3TILoB*aA86qdR1T$%aQs>Kn0Xa_cUkVC~`y;A(O`UuP4`=<$&HM1&QQE zhBF8m)QQQAC_q@5c>=8oSBGb;q&CGEV05G!It6DB)&6$A?gyWTU4A%n z8~J8;6s~{FxHX+v?3tTc@|ch#x^qGe_M0ynOWr!ke1wk-H#2NVM2Qk}ItV9TyO_{N z02*X1Igf2reu$RTm+uO2gLEmm)OBmqbx@2nv)@19Jpy`pPHRJ7H6@H+Cy$oR3 z6fUgG4y5{0E-E&YfnJ5tq*CnT^SGfHk||jj)k%z2Ix!amnRk>EAuD3^gf`(@?{YjD z(l8Nr3<$J!*sTPF$T3cL^O8i!2%>gMpv8eO>kPGWyWkq^=`utMv%KSd@GssDM~Mdg zWsV=aFA)WepJD7tv+s?(vU##DF~QJyviM2LhlWXV6HG8aeQrPd&;E+!TVRZx5{GV* z28;LL5)ztJc|t2Kdv0c#)^k;R#ET*#qsd-bm=%Hu^gX?u19wjiep&j{Pi!}?24nKw zP~zfejEMG>sICR!^m`wI*yS>2#gyX;BJu_qr84~VPJ$SJd0#32DEF!B0Le!>9EteH z&|_9>A)uWsw_l|nG#bg@P?cc}JGbW)R3d)u+{*P9<=YknRHrh(N^FLk80A`vw6+Gm@>E5`qt$>yd(~w_%?Zp zID(6!N$EOc)Ff$*NTjLh3V2C$nF;y;B#r)$7>(RL#Xr4bx6lU#gY?z@yybK@z$Lci&-7onI#NDd2 zNf1y7`T;%`qeE^du`>$ab(yI#_8akbA$8%$Ul{g`Olz(6?9478nH793Fghv$yn4LB z)8{lnT#i}XIPtIBsicL$?9j`#Sxoz_piv%oSX?q1q+i6+m{vpy5?=(nR2CEV_TS6t;X4O#pmX+~-e{+RjOv5MroPD=IAu(bb+XPzlkEAy zvTKGeui0#?S(Gj>tC%>BqGWIkQmJ%{E3Biwjd?IAXecf1uY_gpjmHNE+0Y~!Kt=EJem>A{J7XK!%*`9*cgKosIs{`*$FBV`JzGHAU7#BCIL zwOPa>d$V51w<9mL?Ntq&sotrIkXe~Iz;DTQ4niwTN%-EitjT_%mcp8SAn5K$?VKWkkAh+#1tL%r4Aml}_ylMk zl7){yP}!W_fv+DhmI#^RJ~op|sAAEF$|PBbJDDI$o2Z~5gRKj-sC0Z2SKHuy4p5y< zx|yZr_rHHBg)b@NrDEBJ6#7GhaTt(K5ACR0E*?zf^k+rr@YW{hG+CgI4$MZT*?+rl zv2k#;1{v6r)AfyAebIs36b2v~Axd@vj+7NlHb2mJa)U-d@bx4Pxn<@ZmzX%tb z?$K3fT>T>hr&F9pyra|w9x}&D#WY$ijg{7}uAfx5`mfLTpbj61mb<=prn+xV(dhBA z%SuPG)Q^&5(&CJj8Xh9<1uH1HnOw8IJAy9|R^aS;p!Ov)2y|Fr5Nt|C%+zLKRc?>Z z76C>6nzG)6+*x)xe@kXPUu?amAB^BnZD&l>5la$$e=zOywv9f2W@VQ}Pus7a;bkUK zX8@$dI~Wr_ua`=F7QyHn=K}lN|4CIxUZkpyv}Dj) zFxDVZ$izqpyA|Zs$A5_bM6*;$5<+NT<@7)m?YqO&^L?mlg}Lbb{|{2-Z&$j_aO&Ky zXF#bN?*B}Qq7oEPshrwT78=Cl1OVp{@@zLQAQGy~V zK`30jyo27-6{FS_qk~Dw#ZD*Yk?Uq|_B%r90gQ=U?y#;uovL~s7NP2TcIX5!*2wUXi#;KZfbr^Z>lsTCwD7`i!CZkvP6t#x0>hrp`zE2cq`y)!) zc17cQM+=R9jXe;SvZ+1ORkwR{Z__j4_Ef3c&B0Gc2Bk~=vVyA8V{o3Hfu_l{K6AOv zbnDul>Gpr}{~Tndx`jE(yN&vHw{XOSq2=S{WEh&fEJ1Uz_E!{r_{GhFbV9Fa zPHNJVkA59oN?%apV2F$ScRL;++Xc|OC4Y&M>717^u8^Q$|AwX{t=jRKOAA~W9W&V@ z5kjR1^gOi=tYBRV*D(>CnYk{zX{qFfF|x{426F141jPK2AxBF+hbrd5zjKIkI%)ql zI?#spD62{k^WMp21SF!;rToQ`g^rWwQDA7nYG64O7%WOGh33#v3>sMst#NB8`>=jr zNz5$K?qsml!>HiH7peH4&t~QLOO_66r_rqU^I!8LMAYP`Egg5j&(OJC#@xqOOIGBC zAF8iM9zQp+$w((ykkiO2W>ZKRSIJOHXDQXhm>2fNAY@0xMD60FhePLEbgflp3p0IX zE~2_6mvUgszK2GQk1a;pCPD~^v|kb|3xKGS7xt7ZZXZwv2&pOL#lhmTFfgBeYELI> zr@gmkP?cfjw=uGbArNS;V%u&fs2plO!^n&XE8E@2(q!}0qiiH zRdN#mPabu7gDS%Co#w0ZeLk!$jA#>*lSK3aR1L@}vHIUl1C0sMv=~`{uvFpe?6`4! zKyi}O`fmq8(r2(sx;%nJiX99afYF~w2B9I*t1=*v!9L;)l{kv{WB31xOOP3ia7uRE zI}nu{q>W0?T$@wpIK7}tBxP6aMAu4Wi_+i5}(z~t&TapU4NsC5Y(v}yzbr98=7rrE zu_l9RAZ>8*_+MHreQ~8NjaaoGLCEcMkRK|`@I&@53%Fa#tSjJRuf zM#)f%ZHjFl49ml0A*UK194)e5jenDR+p{g@z3Bupo(~Pk(@H*m& z#;ogqs`y5r$voE~n(-8$naAw)e^k;8tHU<0jeB-rg3Ksx`=AKqS7brDBv{W4VdpA@ zc(qRLMlT`Dwth?FYB##2y|6AO<62Pt>YDTM9StcBX}_96d2|-7aEuyyQLqvXt?U_- zd@+TUiTApEw7v4C+vv<-1D-k?R3b*Tn030mDl-=u6cILq<~#9@AxV zcr(cvR158!hxT{5B+vqzIzSlp|8}VVkAP!g3oe>eRFiO9r5Qwa1}A_Bd^dCllgL%Ys+#pTp%OCMA7UsRUsQQfpogBP&lwYudk6V@zZ}_^i!naJg_H?Ij|n*K*xPM%$m(;@lTh78~{Q zKGW{*P}WF{jz4I`AzG|ofdYSSSs)%*J4bw5%7EGe*)>!J+a@^u-9d^NUkY&ag^uT4 zk@gTKt^;XF>4ZJ{5?`PPf_Iu!^!Wu{EeR^csMmlQg<0U~Sl?9paq9~CT!GxJ13>Va zo4mD|cw6@u4q4uQRwV``6g}y~);~lNg8XcWnc9edJP3~bllFu5eU!53D?ulj_yz$k>fqfv0~=p77d_e6oL5x6|vYZJ9>ZLA)w%VLQ!t`y`x0KAcWs|fN<_C z2L4T78v^h-u+`NkLWE(a?F z_+hh-XZ8ds^IdBT3eIZoLYRD3yyhP6+P`A2bl#To(===BeD$6^*x)tv#WeC>5O^Y$ zDQmSiUtnCy$yv_mVMtp-L~zw#C^?+B)vtCjJ&%pGFu%*GArlv~a(InmJOmG6`(g$5 zH8aRM+jQF6;4WKeO5fT+)JnD;k+Acqo&fbH(>Is8k{ar0o1vb&rkX4llEeD2HCcIB zLAjeNk}~@lTIco;h}G0fS%Cj)tNEa?n6Q-gSpIf8L(h4@_VMY{)g1E4ir1(<2+)ux zl{K(Ay&Y~v#?eFJw{;=^h&zugtR3)9!pHB@drJQ3?7;4vkHfB>`v`wOnFoPx5w$n@ z5q++iBPer-Lee+$!guoMju%XToh&pRn5!SKRq`nCUKo=L&U@~DZXmDZw^*k4`>|Rw z=q1&G*=pVZg}SSM=7p&`^Ym48X`mEX`muy%Hgm zG?8``gvk(9ai|4ia$Ll#G9}o@k)XIx@4BW)%){^lI4}=VP{Md$Xh(!rpvsm?#z@ws z++&BtH>Iz6zk!9RXjcMq2sQz&#?(vXd6FqZPS5^-uAB!#k1X*IiS6p0Ty~e9x(ZyO$muAyaf%rYQICQbBQ)~1!W*Z( zrNl@P&xi**DzETMT^0me8z|;8{YzP$ZSA7%WtZbzrdjTH1|MXf)Cg)d%{Y$t4g|DP zpA|f^nqs8Er@Mf?k78r1xHFv3VoHS*mVE=vERFc zW(QPGKlQK~1_3MIkP5?)!z04mGWsQthqB|jvz#SAhNJ}f%iqH z1FPTv>r4E1;bd^Qhu2PI`%HT8RsUGJAQsEwAzxrU+&MUQ)D}L2+Swv6F8ExHv)J4Cqn zb?G~E`jqzeDJDS<)1mJ_vIcseB5B!KQ%#VH-dZe)SsmPlh;m@y$p7Z_dm|?Z0tKY9 zvY>i@x}j3jKvf=Cn9mgJoU%s}bt7B?1h{@3zFUb)c|+}KqRjk`Ho2>V1NJ-B_9x1t zNhkz5TK{Ff)FjzzW^&+2^>Qg6l1{v z15+qb9wu)|k?5Es@&b8l65#=ouDS}^D!DYj zRXV;)x@XYP96;;rq5Bga-_dZiuio>$URri^&$S~>lQ_Dn7S-oF#+WSq+GhD>Y2N1x zztvnR&3=hV^o)Ork4`B&#B8S|%yu|-D8uCRfH?(6zH`xIYlP?xzjSq_kWtx}Vhi6| zmxXwez<)z_e*E&Sca0BDG*}GQZTY2HpVYoDsdo(dy%uu|jBj=QQ4*i4ACf3Y1e}GS z;jgQo1~US?UuT^4Tz4E2pNL30-P(fUG9)~nNcf(`U3(S2Ip6rqk(i$GNZB3NkTS0*Ht zxxpbF8fvY`x1Vd($bEjA&&7Lo9PLR4wq06bp~Tt7{D7}taZk~<)f1}6$atLQt1ho? zSao3+%hxhz8BXWwWqjxp+@9KwcK+m6i$F8?G)??+U-w&&uwHEeU)Rzf_m$lcm)Z7w!$2L z)ZFLU$Cw#ad;x1JHW#>lOs(sb8wAPW6hmn>mAXed-k4S+bp&7 zp(B3W5$`N=`9kf!KJsUB$Ut_c5X?fNcZa}tTAa=9m^ViHE2J8T89m!jK8g3kBq9Y~ zv6uH+Zq~aV{hO1ZY=oUuF&b9buAGRQ_F!JCutVR#vf9@kZ4gd`dz=08Lz2sB0s17) zFoA=Q1AK~8q6PdN5_&)1A65MC{Yi+atlor^^+_YOJg+57*Aw_0@iZG=g$TTPFNpFI z{yEcS_RSAIt%`N3GkMp*(Z2}@&^F6&W&re>fKn(po6Q&-oZd9I_yFKCkXI6cN)S-c zXVsW^Kn)cL;{fDlVw5Iy?#&I`rp9Zg@%JDyvOx54n?^!Vy0=)<7+Gn|vXNMm2ce%c zW`uP~;XP&h!0)gCmk+HrUuvq9f+YawPBd~sbzwh)!y>wf8ZZMK?U+eVs z8Wx;*avy0kQK=g04OP0I6mJuPh4>BH7caLw6x5p1q^xdMEwNFx{=j-YarH|uBRa%6 zxkP7HD=@rw^(OY@Amrbvez4sm&bjc~Sb1t~1OpLk^~8I3x~j6B1oUUKsNa9>I={;& zg=xt@6@9cuohOD*v&L^Mk$5*HsSsabIuv&>|BYkIRQ+ss%BzD#Q6~DoXHQ=G=ZZ5a zd6i7y2aYBtoC;Z>6o6vAaFWP#-C`kV7VnbD5umutLrB|VX;$H$jaeBX&K4jq(~9-5 zJvF9_ZhrM6PrFg>Cbz~48uvqX4N_(Ep`9&I8rQOjs#unHiY})_V4qB@hf~Xw530j} zu&A=8y10{VaN_fc{#Y9EKh_)Q2VlnVIpqEzc(r29ck+kX_pyB9)DvlN zSwI>Pv7?qEFv#*&JDY3c9%D_)3OYTONl3VX-nw0h0#~k4YMVYV8A%p_`})!1in4+w zq)mQKUY)bsUk&2fwqA~xw=ASW`4xOZHB%wp*ni7DtS;GK!U`+ z>U7l(Y{n=l-~_I!7XpL;BN>;}XAS;bLXW)4Gce36BTiwH^k+YUqzjg2X|9xN^=tuE zU#%#wMUeAmw~!kogK8deOj&}HkvQ&je&ce>r*8keB!n4>b5+OuZOUIL%e|dU|lP8%08m9#NSs;>)5u`##Os3o74$T#h zuCkgbtJoW#@TI1}2-C1sW~y4^4Z6**dJuF%qHBYHK~%L^9a=-`lap3-Z`$U3X!MBc zmO4DR9)YW%*R^tGd+6YzrvyE{T&hNs+66$@dB0*u`|N`4&n&9tgg4GeF<4po@g4>* zoZqod>>7X%eCXPhU)1yx8yF<8FegqAu*?DHn&*hLHu*RzX^f=*3%!nC!~=-k_F)pcc|#9x)!29>_`qMNF$P!O;?R5&W4juC*xpk_#)0$CiJ^KJp94_lbxXDLGT&Hsl4^;nxQy+FyP+v*qcc6 z+bjf1h-BXI^6{frA6qR$L8KrikA6Pb^*)c?U0_jJ0d?T8UrP^b5+_OOEkZFW$bcA3|6LL8rRKzGM@|N=uA_H^lf@(t)z~RMx1AVstC~wrn zH<-x<*kbNSMoWoS4r!BT{REA8Z6Ssk)=YxeJByh?m!bhfHyzICdfkq1U7R!)%mN(- z6_Af_R%vmTO8NCiXK=0zl&b{+a!YmnV3AtL6K^zZtZS| z!+C5!_0$VmiH8tItFHK>_nqyMWtc&uwFq|%a!5``o2ALR&+!PM z$C)k7+6fOC-Z~m88HztQjIvr#HFzf$OG(v>OQ4vw+E;AS_K=LN^*$VVgVAEy%%q@W zDs8fB?9_P;IC0Y5HPnL2bL5TtSQmO$mqTxgnd?xjL{SyUCI%=lG;U9l4LQKKr&rcV+K|&x^)1!{7Lw z9a{{hMXl;hhl)9EEkrv!>=WYw`^8D$qWV0`v$AkUV$jF+DUb>OBoz&w#J32rxtE9F zs_$Lo+g>C2EOhRJ2>p3n<1)inoCnE|(Z-$rv?v<`KfQvz9Bc+pYo*XE=DOs|BXek7 z089hmyp8`N>`LqEpDu$5ZpKs!`?C9 zmq%8J?2WEufJ1zk=NHmS@fl})|LcDMm^H4HFq3O5;;j-MsudXegg^t$YeGC!D$D+f zG(IeK9mG?yO5q>Fc)PQ(nJ$zF@*hASUrKfGP@gH&I$M@a;y&d7X_1I@6u(=tRd``Q-0LR9+fZQQp9Vj8OZq>x8Ci9eoiCP?7zJF)?JR} z`|pI-Wt?+-dQ^Fm5Kvw!^%7(h@&h@K9ipwcbiYY?@yqtQ3V#22$=B{qWLZ4023TN_ zfsiqxcZ@ZD{&-NwwJ1F{T?;j>{F+QM@dNQug-|TsGA3>;4k|_3ipE%sKB@0}YjV^E z?8g9;>D@elHC1dGPi<)#J8~KH<%`X>696Fk~>+e~H0=v5UJkd7%BZB!3 z$KMZlTu&}Zf;QM|5j7Tr9oRg56~i-ovrlYpO%GxvGf>MNTw zFN&(u*`TI#;SW8&fDGQ@i-h5Z&Bm-FD4oP$*T{=4Ef9G#6ALR~$ZiWAJW%zV3zpcGsSBtqCi&4ZP zqC`MZ7@ZBcc&7|ldHH1(!gh~eDV2KnU5NW#h%b5_w`P0TCzYG-((Fo4iIb@_193Bs z<>(Vu6C7$yt=`}kgeC?}uV*K1au$uBEdS9pe`bjoyMm63TYnlQ3pCrmmJ@gr*;qjd zS7A>S#s4~-)j)PbsqzEsL>|ERq;G<}6co8@HcK9cnO<5e=)gAxQjQdto<2_q_(BAf=|^Mus~{0^vTJ0TyDhI~{RN%`$!7ap4U76=w3z-K1} za6+>!@c2%P=c90THy{3V7#b$VU7#B1_t~`Iv^~n!J3PBBCMM2EO>6ucrSgp|sYFu~ zO%Spg8l;nVJTYpQn#Nx|?}i{OU(c)z9BI3O1GBVrjaLrwEcVH?DT5_7Nlc(3Y%y#H z)-Jrtx|W#mzrYXS=#%LM%e%eV?QVCe)%8B(m%P=PzeBeViOY3XSZ!nlm2drFx{ou} z$!*g2;!F!-NZ$dzcbmeLZ}h*Zys{iMyL#cjfv)O@5CX7`p_2HQ?HMILATuU` zLE^0negd%_D&o{Q;Evk!bPhkY5>BJ(PmQ^{Tsf!Ru2!deeCHTZ2P1De8j-UjeH?2B zCodd|*oSZgYx_6_8b|fH&)@5~8ebh{x^u?g{maPbd+t|mxjWU5s-92}wPokJS$z(* z{U9gtzTqiq-(%xVG>P?rAL(1|I&<6R?N7Y*tsTGaxa;IpBreHlP%y9+*(6}-Q+Z6R z6BNmpqTm86y9CeEf31hlg#Jw{c3H)!Jna|vIgBaw_30ddYCR&;wtoIn-JqitXa`LT z)PogX`WPxOJEV!^c~PzN;NbI=B|95xlz?t)czjKyNEsaMI#bKkpj@J@Tn=yEO+K}o z)J{tvql-n92s}iI8FF{x$~ufLcXs|b(P#wC)N=H@vbps$ooGM^-_EM#Itf`R!`A{a zdBI^HY-2TEgudOF-(ta9^%VbdyjvAyvXU_Kzo|hT%c%M59S5tI5g|hjv>1)_V~#O4 zA^WOsAfa=TjkY-`sBsv*E_rvaLuuBt1wDeZX%}rgKv8~-qyX*N-Bqk<(v+?*371&d zRJ`#%3O>*I12i(g+9mWj2;uq(x!G>6yV>tRx4S;7SjdcC@4n-h)o(4nf_D5(Iy?7O zWVD9R(CROl9pQljjzci4DN{3J3#m)@s$pHT=(9!IpZyuT(AoS0oNpx zezss{PA4^)_@oP>tSdh_nizuf9f=m~fAYExnJN~x!p9kTnZ(SD0c|P8m^t^ztxEAHKEDC30@gNd8LVAsO-A1 zOf)KVhf=C0rYQ`obn$&;KEY|bwgTgsU%S4$ukAn&@uR>NXrJM2gfxS%r`yWqy;DQ` zekbIc5Sj50nS+CiJ%l2q`f#Y4?13|dqEsoZEzj@uXu;tCQ~}(S_u^Su;$Qe3f$6kj z*LBwUeT21LrtR4%!ECQng?wW1*hI-5(IEa(P7W>n)r&~> z9%;_3j=M?UGosBO#_Gen55!gv$K2~QPGDAFr-)@<*%4GtX z3F@y&lb3ZCNh1nyKP|MHy)A;>I0;_rz5!k5RAZaz-|$eiorRe5Yka@41Z$^l{|kA3 z1KN%PlAsJHhAn(IG9Q>|UF40po*C>#_Ln<_omwt=@mrp+_l|F@Pey(H#a?7_e|h$j>i{wAK`i}uI4IE zg`QjsNr3{0N+?0j?iVg_L`hdcV-d{@LqB{SUvkh(`wfJ{pin+jr~*GxpCJ5FzRB_o zz!~yO@XGZ5MdGj$umxdJtip;lb`Rl_h2cG~;E>PHVef1!c(E0~ z$45d@RIE)SQ^-gcHj-}shjaak4uMTm}J-XUi2=%{Oro)BeppJqf2^%zbZ{cFJ zz(MIBO9(y>>-Vn9Td!JW5`LlX?sNCUE2Y<-wNY?iVK_|q}lZu$G7fz5C)Fa*t{|R?_7+uGrcg${CdcR=UaQ|g+>VD0$-JUW1 zQ9DUDh%Fq0io&=tswgtarVy^mUj~b|a#ioED(hsX`x@fa;Q~&|j7&&x7v3J!3M)C~ z??=r0uXnCsg%39DtUl;Ar;8VEUY>{}V!+NK;|hf4tBDgACWinZ$f52%tx-DbI1pui z`k3ywCGhE{XkiAc$%niAC$q?wqb47Y@R|<8nReTN{7P|0k9+uk4R*;Z14@jlO(G{S z&%XvsXfXAnvAoLd*a5>~G$Ja+3HEn9Ts@eqh;BgS?2X`a;%tpo?2IQ05S5yo+j6q<#5`x{ zUDgn4?T`SZ3Nso<{t51!bC~!*ERKHoyyd{!~U$bW}UY)EbT3`EP zm;IjW{Lb>_D!pCz>m4i}2?ENCxp!#$>GP8dt*{CB3y780Z9y-P%whWHU`G0Of;Lj{ygWyZ+xqaQ}lv&!)zI>fL{@98wZ;kgsO&_U9=c`AYo~`ujcpj<-2s?d#cyoMSpz@mVG>;54kBC{;^7NH5 zCfwl>w^R84Gf)ByZvB3cOj*4{l+)2;l#5wzj)0A|>Z;!64|7t{)`I=LE017g<)f2a_nj!_J)q&EHOF5;X4j`kn;qsl7a+&Ii92?lSH6sl9agK)h}MLK*-azuzXcF z+G3jH>w6fZBBOIc#~m;32^(83WSN!&Ai53Nic1&!rN@d}TPI=-eCFy&AM{ou_@-u9 zvy;+2)|h~}2atZIHI|HS3}B-U{gXoqslhNyLkPIE_*TGz(Ztp^q<93_4^SJp>D|s` zw_cl=lhpP(1r&pFmHnqrwP){_IxrZ;E7*ta_ubdq0GsI=6^-q~XX7W4lo1VUOUo>D_?K)joRPXZt^IE5ZeA?`13{&z;k1q5wu9Ig+I{;cf*jCaNYLQU zc}0H|DK}v&?dHyS1hkBeu_5n0$MF~VhBFqfPN<%5FyL zv**uE)%qKL0oPa|v5AkfhaHFJnI}w1#JLeebuJwN!&y@#R)ev%TBFuEwave0)&Htd z8d;Slr=}V?I6%9*YcJ_Y4SG}OsWM5SkV=n9 zN_qD-okAX>*`C&odIyUf{(yQO+lfF;%zTbroBRkS?mB{=GR{nK7dRLM%FngqR;wEv;ei8P@{Ro1-ceA*Q# zXUqyon)5JVf;0&!Gv+T=Y`?`rl=oJyo?Yzfc=*J*yqKe+m65bebK$mN*{MoB_|VK+<{rjL_-! z=rQX|%qZZM5&d*_%<8tq#<|kIa%b(;u4m|}rAj?@C|`EDW8Sg4&8R@Q+|fPff!6O{ zz?tJFFYnwcVhgP3SjkA0KDPeO7`)b0dW_Y3$R*)*rK7@`ZLtW~2wAxP#cnL?49FYc zA!f#rnrJB{$=R%}MZOMO0I$@zi5*46kFQpWfF8QrAiEucZn^->-jA~ghIf@!8?&f>JJnTRwOrRh}WMdeiNjo`2K5+jH}=(e@DUg3Yvq(bngYhr5;B z7w3{Lt2ywJYku%OPzP*bpuD8EeZqtL?|%IWoW6qbe+gli4n?WgRhyA3BTvLniF~IW z*TRSJKNt*dhnZgKeUe|NzlwUg7;LGmtgTW`*5P6bUT-Uapy|0 zTKKz7vI?ca!kewIC}1|V%0m4h#_=JWiD-Oaxx4=u?j`pHW9}=t32Ur{W4lKL3&w7b ze%h#n*;A*0&FiHaX6BSubTiM!e5t#WS&{~WPKgm%U z@xGXvn9swu+o$E_GFkK~@dwtIl{|tcPAl?Sa-EdLko|~8%=g@vUA! zitY?D#O-I~WC<%=ca}L{g|A(Y`r2g_k<42PFPj}EM7f}~JRN0_S6T+`E^N&{G1u73 z$5SiNu#{#Mb&|&$r~u(~WnfjrWLlLRG)Re*f}raGE+!^swg(edgUa{6z*e##5C@+^tfLiZ$BYYE{Q~1>?NkMuO1>3Zc`n9&FB7V`?cQV3EYO&* zD`$Jjed5iPMYr$h9}W!7H=1v@MgVgNsnt6H3kF@&eeY4dBOQVIT1H*&vV#TQEBY)p z<7qr#CBrmxC{}Lu_vK%r91O)z3F^M@|Br)!7nZ;bHo4=#ZC^&7B!hnXPF2;2UPI8J z;V?v8sL@Q2eu4ez5h|;gN|q`}r6VD91C(+m#k!u@s=YvBf2KbSj zH;$~6*UPPmZqKvLci!-Hxj-aNH|irgV=eav7B!*@*#1U2ehvYGHb!}b zGrYea7qs>(lZlu;m^}zea*F zRZpCEOZ<(wowQg;9F-t&Tf&`xr1BH|Wdu+Ar8yIyd2!yUyQEd3a4u0t(dydc9v`3` zdFyYPVIt%v#(xK8)Hivw@`Si?#$_ks{etu5(sR^`gSKi7a%P?9$kcHa=2ZxAJ}AKE5hrXwbpg>{ON~XQ9>t zRk$x}yLMi4k6bTq(%G%w8!|p$csJ(yxS_vNW!XowZh9l;mJ$>RUfN0U_(`(=7^7#L zu8}{ov=r0itua%sV;=s0y6G}}N;?)%H%!>|)yFWQ?VYZ$?OXGOFteI>oOU9H@LcI& zTyRzpIL-c>GF#y34nB&@gkINJYaOC+cF=~EJZ(z+5M@Jf0@tmhqcjcQV2a1hBWm?w z@IK^xZ!~4Pw0AJ3P|2{-1{K+i3k0Y$)-6ymy;IL|6}Sc!=n7Yuu%)? zl9UvX5RmQ~X(biuM!LI8S{kHVTBK`+?vNb1yL*74W9B^m{_i>Oxh}rU2fjSl+H0?M z?>kgUqOj^yDX52}U1+pF4%e~q>xiyGM^&NsAHNvv?OA6l8lpJaCpQvo*m|T~;hOuk zQ8I_dRB=@J$6vEMJKWFj!T)^y?IO6!s(0_9 zeXOD2of8VJu1Cs;57)hiIGqawx!qd}6}+yk$=6=D-Zi%muFpGLH$6lVI3)|uyx69M z*ISeaLtIE?x|3Vwy%6&oIWg)p<#h3;>ukm=wm>!{o3y9?jaV9W&!RcK$FZ8#OwfWC z_0$GIYslVkPl`ciILWxY;wCN63_I;sN83n}TPL6}aQesSYaKGzcXLG5T}dj`W1X@k ziu2F`6^g2q$oiq(pc^({ugvr)u43~08(2h3&5)F@U%(yqxE)S8xd}|l|Hl*kt-EN= zps$ks;OcRvEO~fPV%L^kj*EPwQuw1F_;dI`bB*f9q|`ASH$oV@QiOw!vlSm^@*SNM z%h5cyr;aXM>6$YC>a=Do1B|wB;!2mH924zyGW_Z7>u|fDRUgAqRuEv6zCMjMjLNGV zQ-G~GY0>rocr&gdvyfwUwG1!*sO}_FKcdK7gDi+WTL%I2AD}c=o%X&WU4MaSRl`bc z{NV;BLv$eQ506Xo4=1aSIH7-z4Sz?DNc(LVJUnGjx_;_#@wI*UzO8mR3wJdhqV=xa zY>+^ir_o_Yh@nDw0NWcS=WdBACa3WOW{AvdWg@$I-S8PRM-{kK;G4+`>ITw7hMfDn z$mWW2MeDJ&c?0XZ(Koex%RttU2}A76-tdA83-quIMGLcBPmH^NJk2(v{?HYZ46|-$ zbX>qaD&%XJrM`$HpL@*Ah9DUxc8z+ZIyaql`9pYI7?sx#b{`{G<#%W(l}KdA*2op> zrjoSh^L9tbJAf4UZlf@^gP@&EoBe$=6(44t#Az04N+ugfv-`T`Nbmkucl^E<24Wvl z^6uYG`tZWtlQFTmg)#H~lJY+ImP+RZh5xg*8|bk&ke2vSg)DQh9B#z zK}`FthXn=z*J^tzPF=HDwIu!$2uAMtdV1b(xbqu7md-X50z4l5RwDHAi+2@=tX*K5 zosIXVRk=-5yb#0jK@)h%6A-!#KAPEH?kZq|5z}HrZuM*c-7@IE($fLAPyoZN2{vnH z*jH!=1Sve6{e9-!+&9yISwgj9-|kT3K1F<1S5PiXtxyS8`IrpvP zv*c1y-e#@JC)vMO9Gl$x+_r1ZP+Up)fJb51(1K5YG74C$TwD6cSDhMQUGa|=k*QgH zboyQG$i?=a6wpJG+csHAl>Pc>&MmJT-6TrNU}JA#FWEgQ3RrspwsrN42@ zjj#2%xFce}9qzt5;80JA=9=5s5sTcQcKGG={0R_`$GZZj{Mo$fr?Fy2Z}B1w_br8o zW5lMp`D^mD-Dq4)s{1Lkm>m1L&r%bfCCg++qLVX0Asib*dB+a7d4+B4Le)!2BR1}I z6~Z)2XuB0QQm%AA^0{4xcDR*QXVpJm!<$gjz~5SkW-=m8B5Qe|Ifm=Q_+%tXKS#3j z1>Jw{Y&ydXnA)5j@EkQzO3lk63O`T49QehYBuJcAL1YfgD_mz zuSH%%W4`&pH7W8Zd)c+Tl8u2K^V92RbSvIE1YaQ?7v;IUz<%_zCLC43n_>ql?i?K( zo+LY*ANPs3EWC`QKl?j3d+^M30!}n{%{^PNLX-nr^k+7;XDYNI1fxk>KA$m!C6`A( zKrl%$=BctWM0OHebU9n~s%e9XIN%y%JMFp^gn*80YMNpeX3*Nb>o3{AXt(IL+7#Ij zx_wc*tAQjFD-Y3{SitM{KB+Sju29m3bBkQ&Ac!%GV{u$uydICeZ?fATmqjiMNlK3W zNdtb>a}2%D7_Bj$#KDtE^h2D&A7U%B3$!>R^|O7?l^bCri>Y%pP0}1XBd=B;tP&D- zUuZKiTPBIlLg9mvfp=pZa5x-oeW%FW%t$2w{VAP-0f*R8%$`q~Eb>$u2#|f~?Vrw| z_SOC9HaSckmEtD{wo$)z{A5O?M;n3tO6h)dDbljbp=R91rKn`Q8LeI41wL_W=KEa)?Ofd#tFIASu9p4S}rz=1#-vlS3kV1 zd0B^#)_>J8mJEj8`&s8F)hAqjS@oBGlh<4hUyNzdxQg`D|Deqc1CU1M>gqqoyh81) zl}G1p)4#a6-<5I_0Co^0v-J9Rf@{)iuMHXS1|+L>NfIBa;&v-n;^qHIwJNmax~t&j zW@E3z8{$8D8;)}(R$U&uQEt)M`oG;cHzPk$`CCIqG#SIW+!jQjy>;zw=2t0`H0pK) zA&Yq7+J6yax$@v^k11S zwl_cQ!6GrZWq2~b$LEI#D!#e(zXyy?$a8i{{BHeEx!cd*IvaaG)f52ya*S6EcNK*L z>DY35L#1ld01ANAZ!#6W#?2MaidE;}5ju38J{FrlS?1Q4SUNHUua>3u86p@|Ab7Nr z3u$|HeqI?Hy&o5qgFLDyvc9byHIl7gL6qYS34e&VdHD^4zZsqHT-H||17@-5sryMn ze{?02n12@ps-ml;Q$y9s_$k*e_9wA$Avtd}i5_3X0RH|guV^AkPF!wdQn%a|@mZEf zee^63v^DFPb{gN4v}H$MX16o0nhhC=tq!`~KRn)iGZyc%Rph@?rd!szZ%mJ>Z}xdx zgR_-Vb5&S630pFKKZn~CEwAs@b(JL@bj)r%+r1*YK1$8IxWAa&*8Ahw6A&_0C`fR& ze0*zwLwRfr0Wz%P|Eh&CcmCx|ox_#X>0bED8_t1AxPwW8L6_NB19BPY1y>k_8Q>gx z%_nm&XrXkW#Q~4xGGpJYtY3k($**i9ea6*2ww}Wbk%w1d?==*y9b+VOZg^|@40Cpu z&@2Gk#Ybj#zf+Qdbn7U7B8OQWn8|E;GoH%n6}1OTF$g)tvpf1cE*iGMJ^%ipwcqOD ztk-u~amnIn1SRHSo*ljnx@9UHJRtrvjTS>O!;>KNKAsfz)wCdZAl%apW>Muki@tIZ zs^NLx%ytfTA8~?5%g%Ep$Blj1Cyr3p`Al+L9reN6xA4PfcL92dRG+zGxbLHbg1Fc! zl&b#*;!D}g8}>Bp+M*K zgBcmczjuRCK)-8f?l6fL}f!c5T!1C)Z zY*@ge-;)!BW5aG`*D(l<-;e*u6Yzk0qOc6;Bo#>&v<@zx0W5Jtd;#mtf-n#FuOU~o zJmcGR@$wRYLZGHqb%)Q$f6IwaxSbYS`X)*~Dvc`q0-#JgoN_zdIPZLEoyIf%7s5@& z?K`9oZatP2BB4%tNBhYJ%hmE*@z4}28#BEG!>?C#Zx`d+2=>lJT!xcfi_foq^;1`e zr35C8zvdT}JRqJVpi|w!aX8Gvq!8rkN3^~p_-bt+`iDg~#BPx%od8w&G`1a=K*6>HvW%5_}TF7rwDwMZ$_=?MD{_VP$!XK7&J9j`*LkQ3R5JCiq;xSVZZ*=h-#9BFyx)tTJM} z62-`Xfk8|tpf|3;Z0G(QP6!)cz6VF9>s6|@qZ&OzGU0KunwLCgifA#tuM>3J)(4%( z()rJ3GT?l$q}slN{%`Sr$poJI5Z(B$X{~j=I-7V*-4{Z8zG{e=Gs{T)HD+`>ka>MxaGg<;mO?-Y+N zJ}acyU2Jqo8xEZi+FIaFErM76be*5}x)gF3Sme4Syq8p5IUTc<2}7l`5f*xJsSD*v zQ?KoXAvR!V>ju@#-P-tpb$ne}{)ZaB?H2SL=3CCkv?6Pve%bcOK_tL9I(n6=Azz}q z5r#ZN^;m8;NWt8fKrbqcwtE_-xd_P=Y+RPNMs=Xha79eFoGYXlCMG@A{Sg~i{OLlPpf(d% z?%%q+q}3}6f{VhGUsOP?ys&Q~#y!THa7~WfwNU;D)xMP|WPlNK*zSh#Z8X{O4(ym) z=!uMM%mXF!$n16UOly-OIz%fSQ&D?_SZm1Je`qUSmTKLY`d-uGL_RE4339VnL+PIK z=%o&g_+c#hV;>eU;_e#R*B~EtEqc|mby34E4&8ho(r&O9hPb~Tl)l9oAFISff$MKH z`DX_D+%&N*#t&eJNK58&I?;1^Pbdrm$lL36kIzTmgy5w~KNZQ3_jTa}W0BcSXb)am z-@Mi!Ar)E{x`IMMy^&Q8!~o>;pp^>3b~d-Ujly5jiCmkx0Uw6$n%eqd#!9^$NePI3 zLJiLI%>SUkE|>d*3gcjbeEWZ>sB65cp$mzPub%FQ3+*DxuFh!k1v)%XOVGSWKGCT} zTV1T#QFe(1&&0gp@>t;)eb2%Ws?+pyO74^(kTkxB0>J{b>#`ZI_?&vrxt`&sE&z{(;IzN28Bv zldBH`_P*CwrkMNX>RpY_YT3TpXYPl7Bl_^j&Y#SlEYG-QOaH;-p}*r--EDJ1y^wJ zo!OidyDFo2kx}H|`XEa2-F#yI4>eKo;fyD)2R=h{?oV!pc&v=JWuF!+W6pOgd_v|PRVFc72)Sgp*qU$@~jD;J?S*P6yqzB{XD z?<5h+yV*(kL*Z|WS?)s8&(0(0cbA!^n4MalY$6ed9zNO^NauEq`E&`{6m?G(yia2) zq8)^1`=vFb(71RP^kd!&JrIB;7ylVEPekmG|N7%PxGwW+GK&}Osb5(_^`WmjBIcfR;~I>g;&sKLC^Tx zaP53SOJ|Y}_o!=qumDk5@Ns3BqI+t{m&1%V@q~F;~R=K+y104^gWAS zL~}vH?DNa36<5*gmdEUt7QokiW31n=cXX%CNf0@~FK}UwG+hH>_{=J|#b)utq%h#3 zfa@2UYTiv-jvs$9)jfS(D{R&x=3#*S6wwZ6+SV2n$TKp^9VS8Wtdr-E?=+ehH3~E* zB>(Txtjjx6a$-CDMMHsrv4)&QY04#1n19k=cx~k3I>eh?r^Aq@0UD0bQ^DSbXl*Z0?bd+t_!uyQpPTQO0Ez@p29k zr*-23U*>SdjDm%%AItn^k4-O*?;T`ok1x%5dCGMv;!p>mkvraw|hyB8oCt=y@ZA@p&WEL+%r`hX)N2eLRUxJT>GX5pv*BQ3#ig8no_19G+uI& zhb$;33rAhE;E@qiI76c_;`*WfnuCXLYTR$yVr1Bw-RU$I!K(!yB%G@46A1$$O6y)e z1a(}x>p}sz#ato@?LO-T8&mKvF_qm`kO#l4*jcGb`Af#Oi+hpNoe`Ur`jWMNnr;oG zP4;9hdOvi;dE)}>{i{&$up_KB@a#;Bfziz4<~?T1S*K)UTsF-}luNUNh5TC{9TY?{ zeYyHzmroKV3A4zfLLgo`N@oqq|C?15WQhd_r&KUR<&c;jOd{N$(=-vDbg&-eIBB zX;3NIfERJr7YOntjf4oxy9vQs&ddU4?D%@YZW&OdI#fMzX}<$1i4?iIuvEsU1XHy8 z1_-{=!bH%Q4HY+GWg|lg=P(sCUPzFMxA0+a&XULb?q(=N-RdA{mu`(6V5{GS{a@H2 zFsrV=d~M&RN^N)=TEU&?rOlt`tHP;F{I~9r2TF9mE~PH_GPAyV0)*YtfHf{s_kQ3U zcJc3p@l~Tld`TlG`6_0;qLD4&Jxfj691kJ?;7vys3q%_qc;Q&E(Y$suYr>P6l5#p< zdX|ISS~D(o$A5U#xwct46hBa&@t0RN zf!sqj%gLMZcJ|)jO|a^+4!P3(E+$eP2=?OSoY&|FqDSW%oy{%uiS;VX!h&<>iw*Ql zHffja#R3eEF*l?GUBeuxrpk3NP`r_@kL{f#qoVOXTJP}2^&oDpl%7W=JtXY5^QO)Z zS13ClP1b_*n&661Sz)Fcy=^q3KIdsic+c66u+gs0TIh9`t^aHNYyP#)cI%DW)mu7; zP4|qn6P=TQ>Q+8B?{^|rTg=99a9{2C5c$zLat&qc$ zKw)_cyNq@g?O8xw5D{=RGm}naCQ)L(m>kNArKc$ZGMjz|N&j zj^xNmBVdDh-Y+j*&NO$amlo9vKs#}fugXKxs;r*pr-A&w2T|WAb)kIFh{Owo_^f6$ zUS2{{PuZ?&VS;hQ4B)#Q0`>}=aX(Ru`VfRPF&1;?Ow5>;I?KW+*4OEi^ zY=dJ+#P6@R+6OB_x@Ybcex!=phxx)d zBXd{IN!E&BA+0bj8WZr6@dBxR^+AFUyVfC2p)>~0=a;M zx_uFBX^3*2_ANVVOuH|_Kedhie~4%*3Sb@`Eu|fzPB7YrHBWo1FzA;ktFYA8BmMSA znehL`LzTIl9uM(UXc7TKxI!++m_njCU9BJB_qfxl z2hwO?lTFa#t2y{3;bn%qZ445GE7#@e`WwGKyh$|lx+l!JT{HJyva84psRcBtM4{J9 z)9`x!S6Zb5EdDp_jShSJ+gX~)1FqhX^8o*wAk|Q2H1h66Tl_1ydrs^%r`jQrU7I~M zK!g`BQ4tZ!6g1cvtL^^hphueXE7|0z?Tq5y&Wd*1Go9PijQmwOQCge~4+QesjKNbU zjjSSPcS^9gc9mjdE98CM)<5Hn+aKJ;D%$&R8KJswC|hIZdlfT9gu{q;Jkr$q zhmC?@!mQpmylnR11q#K*@J8M8`zyr(J9$}HzI9qL4lC(&zzcca&eV&Ufi!msLn z$-}~bPtx;tZAc$5gecBAquHdfrE0ajR!3)Ll)ch;a5Y2TXdZ$BTZU|#wu=#t2RR|G zQB5_5&#vEbT$>EMjAuy-fdj8>7T6q4i(7sKKi^&-iuv*%k&hxDZTA*ER~D~a#s?bC>Yg5UZ#WeMX2R zCFw2DrDP`nw4+Tv^}9Um`-vKz6qh)6Q;>2e|H;AT@c-zW!ik|qE-B&NDKmg{O)a`3 zBl<*!Ae;PJ;iZr{{(=&oe++pTD~z3p@0%_GlH-@!US$$jPNA5(@Ld=?FIO991$%^cHjk z4#svlg)sL}cr7=NRQOB!n5?YbJ%z4nZf>4W|4` zTnzpi2;C(}zu$P|!)ttrm**V{q24H5#d09w7Em_wr2IN-ef`lR&nRVC-cxvSMsEhr zHM4V7-}{hg1fdk=`HeXus#PQYRz=~Yw2_9XGD(~o#{7YaY1+u5)KkTC@wvmJup-t~ zvp>bjy$-|j8E_w5cVxSF%y=95MYY+-@cz`!?r`%^e<-;Vemd% z)_(JeT>n@o-aqjey3y=+(A==TLcU--^S3K4U*tLi#6MQ`?ofOtb$3nH-*ipl?mh1E zuq4d4N)%Ic>29M&HhzS0@@H{QrfePf3E6z+dH`gUTTCz(Z^s_MuhF83`)Vn6#)??a zKkNo3n2!SDI!~o6QDp{|blTjIPk@)-tHHz&T7pkh_R9~XCNVT)jsENzYp9&pL23A- zaG6{4FcH<~36+0i0| zo#(n})`9)Q{Z-&yCV+KE2RN%K^FUFID@Vgc{N|f{%zYc6LWLEx$t#D~UOD0i0y6hg zljAcGnuU3{qSoWREO9-HlYyVuwDG2E_v2i?gV)!EZd!lDCS>He=dCqXL-qvl*N$1yFrRZ&)2Vn&l5tB>u0n zT*bSef5J=oU2C;C#hh#nrNCD+KTPd{^*E;f$}*G3(sq8qbT(*!_s!#+IqMC8rqikog^3Sef4>*96#cMA=4<&R`4v?>v0 z(N2XfU}cL^pVkhYF7|!vIx%o>`IN>9kVU|A($+1eslUQJNW*I}XB_N}D zC^q6egW3)$$a4XyhXtg$jg-tXsep;hFR=gj9GEPE-|ewnNezDBLqDpq)P-238T8H* za$)^wh4Wr~F65)U8Zb8`! z@I)%+Eonyq#YgFdBGd30?b7;Lefx_AL<{T?2zaV|zgSwoU8Pgui}BG_z2P}y%N}GTI+-{1seIP*nL~$mkF=j^Af-XiQPuf{ zy-JqO*G85uZ^9@o z(wmU*y7N#}p3N6P)vq9m__}mEPLWNbIz>*%E|S0qTKd43*~=(}-;_%^lAI;my6pRj$!&w)MVjTHzfuj`GFxtu^seJn-#hzl)=LX=hF0n$ z7antI5q&pLghyI->^b>qP4rD8LyOIGeFoH}AyBG^u#Q`I@Y3jKP37zVu6;q?qx2d=~${R>Vj+u0g)s>y`4)Z2h-~4kR`|OYO0Oojq0-v|D=e z?63(V6eL3p?)v?c+8#^cwYbJS&XOq&HzWQ*=q%E!mkh(o&g+NB^eWY~=~fk?JE5CB zsAy=)*@2ivN^LF6CZ^G6g{b6Hk=PhtXA`ICMOCAQTd>TD7f%ONzn8IxpN5L24gH7* zU4#w=E0W~;o4rV`rNS#Gmxe6!Nbjhy_nSAo2h=n=J+F+%$?+%-mG9}4M=81MPm zlt+=CfsyEuFyNgcWgdI@owuURtSor(*Oz&$t*m=-%Y-%+)%lhrybAF7HIOiGp_75^=xYJS-df|8Zk2E_ieOsRLY;}R0jgFUl{Gb#Vx(TOER{d%*%suuQJ$s zYMnaA+1AZ)9^e0hnay24(M5i0*mrj5XYUMaGm*Xq4i9RAgm>{n!~*9_k;9s?_GdoN zJ+MhppS?M!dP^TO%lsu{tBM#7*1FTneuEbH#s(#d05<>R3G(8Tl(;Hk-AOg5*?Qj8 z-X-|GQaR(r1%bSX-r=Vr8CFpwZ5sw>FK>3v%mG01+oee2;jim~4)Q#ZI~>cq6Y z?&;>~*QZ>z-eu9+k|KSQrA_Z2nOrxrBhN*6_KwrXKTXq)C~K?%WFj(3MT??X^g=wY5uSL(YTmhg@JpL)qHx)169tn@<>^FW=n!fafkN!Wxu!&iH;)-n0Uhi408$%*91LXF2{^lUwB z^n4xn+IiPjnv5%e*B0=q5L}kao%&m9|9t@5183AIFN)Jo(YDnae$Rtw-u+6l1ZIJh zsGl8yi*!*Pi}TOilzl?Qb7@OS*n?7B)ApW2s>+B%S4u_Ftd+ zM3ui!S^}4!o4C=kzMg2KzO$>L%%r*%Sh^wL^M35h2|ffF9~)gQJ@=)qqB^p@|799R zH0yi}hEKiU=%fnYH_wXmdnT}Zr2A5@$V;2a;CIyzBdON^?}jfb>34fIIn`XadV*R1 zgZkUjS2v$stwS6hBAw#qse*eK)iTU_nf-MaxOHTn#N4u@A!^RU24nKutI@D=8gs-0 zgh{btb=5M;Xk)52svU`8mZsHH|5@&A7IDU2ZEUc*Aw(JdQho_6KE8Y4&CSEhuD^D? zKjhs1+?j{}HIT*;3iB@xg87z47q?Fb%LXia-+7+gD~gBnoEC-r({G+(KyvsbJznU?E6urep~4)NtZuUR(UfM*TO6^7g(P9@KQUiP&nsNa zcQ$V_^V8OWFL|cy#48guT#jnFQD<+TMoUxOoKirR5_b_{<^k^{Oo@1{4^_-KwN4}R zok}ht;@FWX7D6jv^mUPyxosn9884BjNDv_{dM@mqu5^W zVA;K}WSR~CYyCkbc6=`;X<|6nBySt~S;XeiLaSHWL}a1dTh;AUiSe1qK7+e3gWs)M zDFNd&`HVTHcMs%4t=D>d3|I{p(f-{_W4&ti=>xo59uMsPT?@@`dseo-P1efz_-uWdkSeN2QMrKg&-%pdliyRUyM|1RS6#N*D+yG-bDNJA zNb;5pN>yHKre+iKF_v`KGV6;KYf*svY04?1-)oku=7Ld4n5wyoYl?y<@5gq5EjcNneVtTFt8_D)K8 z_Ix`Dop7!Hw!e>&>>kGWuaI@nQI=(M54|jo6hsR!biViCD59IW#i>%i8sWn;)k(3? z-NfI>JsZ0?N$Y@X@auS0tD+x-r%E{P?F5M+P*{j7Uy2(gLlBkipDfLMa_^Vax=9r| zcn7CaicxyY zo%b-8vp${eV?Wnl(dOC5bQVCa#oP;-cTt~;+SnvMS2|)%n zy&yQ2MxvuO5ctAl9&=Q&8iO(SB)4EXrL>n&()+w;@L}<(?-O&V^SU zH(Z>`t{3G5;yyfEINgI9!GA~ z=_q;LQZZ3Ohk%aEoIoe_6!BA-N-?jV0gd?9iM8I-_=|7bh?qfEm0*bg+fdjaIfdfG zd`+iw?Ube|>qPwzO>J%#e#Dx-j}5@Ef+_r@00p!u}{R$QMVgP_qVe zGXAaW+-F_^%~{*>Zlb)$uJ?w(ek4Bkndwk?)|;U2WI;9Csf+7fq{Y66P)*z0-j9V? zgBFYXzb7tSU4L3r{3@}G?^+~NVF}U}6pqer6@3^pK-wsd`wFIVY<0Q&rOcPY%I%6g zu%pJKGH>{}HI$1>)uk#p`-_nW#iu@%nE~0armS-}hWG0kvA8om%7ZQUx?j+DO%V2j zI67BEYq6s19L}@ELi-pvZ?5=X4F*Z6d);0WMi%U>seUq833C0u;hOuppnIt2SI{eS#8%EP z`A8DV6iK5aj9tWrfzidp@t2*=tJtN{Gw&FUh`l*ml27%say*qGoMQIv_*~r8k)K)Y z+MLs6L7crYS}#dx4g(53vX2=+0CT+{ek1;Dlf;$ zZSjdN`Y)9>)%U$Ky%U~Oe7Bz2yDu)V^cli-&27(oKC`k&isnEk$H%Kr5ta3x32FNb zG{1@$i;6=O#d~Suh00iPE?q>v=sBv=2hHZOUOSU?(q^CopAbC}b)F$Zb;cRXZ510p zR!~7$fGdTlyX30k7#P>-n0#Xhj6a7dvL$tyb(m{w0LLZ#cZQ=CB%513EtXB~*@BM) zTe)?S_uX=X-wM>a312FQ+*sT-37^V8zqqo+qG`o|aONMmK(B9x+5OWiDE0P}hq_4_ zpsfRY;fx$!w%`CZB7tl3c5x2=tO{*>Vcg>_bL1{`)4av0$W!IB`{GDU;;znTT|H@x zLM-F%W>Sg_$uOGoRv=)?IY=3t4o{Crx zcIH=jc=hX>2r<-lX#@}RNcD(hHzVdBFHaH5w_#dik@-0Es&#@ciW3VL*VyWHu57~} zlLQN&w)x-@`MbXro;R|`c};r`ic|dof7Zwde0R7&{DR))HE)wef`Bu8_2C^$g}VW6 z*ng{b!>#$+SXeo|6?lH3m&sqRU7kGi7lPEGm|!ly{!@ioId2(>yn%{UeWcb3<^Pts zFDbP_W}i+ZDYq_p?)F z5!KhaPlcGy5!8=#=iMY4qSG^msY2Ie`SwUdwc3eVY%RYV4KaCR>--T{i@8 zf$oWx*%9;c81W*+efi)DRg=noNq&ExoRm&@?e8c+SHx}cwVE+yIG#?Hcxjh5-ClAc zrToI>=N_J7|HN_roOX)z&urW9T8#w#u?S)YU`c8{6|qLCh50qy!X0K;zmxm*Xy==y z&pZmdqB>BYTK*!^-4&Z&z1z1(0xUViGyF*upy|;BoR=ARt&YrqMu&=Y&@xhPVMzxV zuMVZQ1hR(ZG?dyd(9Z%LuTC(DZ%QjfFJE*p2|v~v++oSu3ID9n=L2r$Qe`BSkS>s7 zDQW2x3_(63KWJvkYgGK8gHWwM$MyeZ#^)s^Xf4F)8{Od27OQC-P?MJRlb1 z{qKi%6{hWg9LKCUZO-Mdf-QeH3j6-B_5hFG4eO!g6YC4CYN`fS-bS18Vnu^tmLmG& ztoV^7L^_OlYFd}mT9+soz^2cgcpO((jk$0w4s*1Abh^oRSY|ZZMa?boUiO(L|Nhva z*AYfybo;Z7`5($D)q2xHP5a+mo_rNF!(U;G>yhSCUUmE1o4szmT7}-DFJce4T}6T9 zn6FgI7J z`eL;R%z&5x-LPz>r*kr3j%w(y|80Wmzw7n4cu{A>J}PxRKX%s+eR+LSt@5sM?p=Mq+#VQJ+>}So za`Egp`l%V}9HcTe+thf2&s60z$OA5Zax<5ebgceCbJ!VSjZ8PR$K>y<^hq>tB#|zm_CCe2h(>iDG3{GY(_=l_9G4KS?y`$QR`+Z$^JU>@nkd;- z?189@n|aknUcPcim)fu)0Ga3^0YKMix#ZSZ#4#lbC>z^V(b zPrJ?a#w}_7=QdOf5vUtqGvO7?;MZmhS=g>b@#VAWE{5EhTtZ6lbSK&7bOLz>S#jw< zr0A&wABUc7+3^r+J6f1n6Ps`ByEXMS$q&?VpL7NDN4Pg__UzwZ28%(z5%)i4eE`NVS!mn>WH@aNGt2 zJCg6-|1Rf?(0Q%TG5OQ>GYI1Q5KO;suRdYsPjGin0k9e__d${NAlV8>S0RQmqmB@J z1kNOhGTXg$0Q&P#0|axz?y9zClJ2uKn;2oSOX;0D)IrA2ud!NN?i7+CD|;p$GMpTI z-D7n-j}RS!GoO#uaiuGv);&F%F$s+6Os0!ySwHNsLqu3ISylxvg=1YdpPSM=F5DJC zWxM!ABiKL32CDqw`)n$4t%y%+%z`ytrvnM!b#oc`<>RK@^QDapvMXTz{Vc{0s2MM{z}E`6YcjkE|Rg9#*H) zH{VPulD~gw1JD_3Tnj6!2%R=c_-__+^o{!a5jtKc4}{oy-lyc+f5C2(ZZ~dMeixM! z9*ZP5Sx6WGmM-Z>_HSyRA~W{qfKkwSkq)9Z#ZGQKCLS)odV8H(rRq*T-EEjkE;6*w zj(lmRCd?fo3v4+3RC9_N+%9ge971BfrwV^hbz{~`;;ypAnwpyTj!sN%@;>-^@mKm5 ze+f3*78p>!ZHLx4!=!&UYiQ|&yLC@sz zm63^?;y-mbzUziG?MYq@GTgLdW#r~Tet&_agj07Gy_XKeiMc0~sYFUfy z<{)dz6=s@%n)NwFsc_M_EVNMSGogw4PSSQ4s-4Y7)j-WDw8R!D2I( z9@P%HzeC`14x*XI<@ja!z!u{kS3=#(O^*=EM3p+KmZYK#zaOBxa{D5Z>Vqi)Jfa92 zV?dT%Po10V2^24fkjYJt`)j}LQquCtY52FU??bDP%E7&jF4GZno)(PMw@X1w9<@6G zvAd1;0biOH&GrrsBDkAmWf{>TpQkp`2sJlx$mKq~lq+0VwBzMmFgEEk_pq5jAjEIy zX8FMurrcxoa2d$!J$2RClxpH#*{n^5JYBs?J(VLj?zb5X(8Gcc**@8SEWVm&B@WqK z6MDQ>We7@flxTu&-ipbU(3=-NCp9J|CzlViCP3e|Yxp&mZDk*ittZ*r zP5hE>ziuL+B#kEHt;5=M0IW#IsI`%O`P+!aOPr^%f=0`3cC`%>(Pt*C6$G4m|7sV2 z{i9b~7zxAW9BHQ=v<7>v@Cvh%=@oDlziLo{zUsWiiFj)7gQRrgN2Fd_&(K&syaG9Y zP4>U7orPzBT62W8Wlnecp6)fQQ;lX}?tvC_^r!w1U>=OWdBy(asLhTa1a}8PSgWgv zWx{lC`jFBbwIA^(IPVr9q(0l^k)LT&`ik3bK6zbVuD!$Een&0$of@zm_>vdi%N0-Dyy}g(=_C9`*P8B9a}97T<5deQlCYft@nA`E7a+~ zcFxymeCUDwgF62(6z+dv^EpJypcVq9d9xN~zu5*|A=e3)>Q*35#L0Z#D1#61np3z% zZXA2{a6Ncl*lpbh*x*pWpNU8;6VnyVLW**FV2+#Y|x9%PBn&QYk@7himz38nVD360k z+jbCHo@))um6s&4tw2AS;dv!Qu1yB)hQ5E!iQVW)yOYcjses8-7wa2JGD@c_W#qeB zNfLG5dWg3MKj@C%?**ayA4Rl-K~kN|D#rk6N|A(%xii)Faq76iF2`<5dyAw1> zf_rdx2o8h02X_lFSn%NP1b250&fxAax5@Y4`*z=$wPqIGr_ZU{wfC-Sku+%O_wue~ zP;h-4`_RA%_NOO*)4xyeXzoDA+8U-!nG;Oai?NGvgj)QWA?oPSubG-#(oJ+nx#Z&% zC=!RHT)GN#7+Tb9xVJrMgkGm24_=&k0`Abep*8WYt}bJ?R8WIwVbeMtanpadTN2_Q zj5_Z{t$o9D*n~;IH>VwY?YrdnpyTXr3jTem88q$s*0Op3zb_Mp{k#z+MD^G;P1kFx zbv=`+uHh)qN;>05TVu~EEokaw;j&=VA+MQ0j!Zg|m%)n}(McorE4FJU$C$Qlx%n!1 zeL<2z9q(!pm9ddpvhE2p` zw4v@bUhykLXc4(ZfBiyo-*S_+93v9*?FaQ=O9 zo^*OtWaUSL6)0c`p$>GqYDLc&7LA)feL%0;zL|^a`EPPm9qGe|w)G``ZS{m<4*dPzcoDo*9p>*r|WG zr=I7D8j9RHD01&d7(I{sTK5y70Pka%BMO$OwCCv`eiwm_SWcK$B5Tkk4V!oCl|qfn z4$ref>=MaM8*1EWdxTr){~X>bS#$QFHD^QK|^Ri2=toBr>>h(sj&B@qFF zfZdioeOY;S)-hjmviM4cJ%WgPlNik`DDkE21z-ueG*)#PrDQuOq1NRrBD=miQnZg_ zLE8)Mv^VMN@!cMZOzYFfSGr}P^;b6D$0W~W&`Tko5a?BX`*8W=&~ECnAnIrPOT_gK z!sW9GJ|$^QzMR8DO&YAo(n!xkT*0I=O)g#39@Y*%=(-O%!)R$S zd8&o^)*15?<fem3+S@SsH7*cH9zYdi9sPjCpTWNPU?ao-Tm&1hB$4o zlv!aP9P3xwwAkb3D2c>c@6fuu-2x#W19uM(i|KV`N*r|IQb z_U+F{;t{bu_TJzLoLNUq07U$#&vt!E)2&<+Bd4jYy92v>~!ybY&{>->?9dfj}D>4uR^X5oupO3BXT#^)V~J9!3#-!04oqA z66vKU&QpFajr(7C$>KQiZFT92l~+f*;v`2}-tWGA=dz2N=o;3`wz z%^hZDF(a(G&PBtcoafW^ zp7}dbEG(>|5=k-0ns?@AYOu3iLg#0CYQ<4gmzS^~d(PB3)SDv@gA;+-`yQ<{ z?aT$d?^}8jF{88qkq|)4S zV1UKON<`~(B;q=ckUPTY6aJ0Q_3_n}RJkaFOin+S>D`sjg=Gz>=2sdcnh~D&CT(Y@ zRg-BC2M6c*pJ?xNE2_;cv!1=}EOL4;L9!L|Ol4}=Rga=rt1i@p6Jhln%M%`P+ky2v z;bmvaH+c-@ZTn}B>;lNc&MYikqMwt{Gttp>ViU_|h3EwazGucu`n57~E*278d^=Pg z6EwWTKlMy7t1sGRJo+Fvxw;BQWsEYvnVFBo&L+45!bm3phR)ZW<~InPT;x;89>+mt zx#JbXOW-edM0RP_UT3+@O>T%q2A;i4(6Sd;IM0$`x;_}r;!J=z1$C!Zq=J?P!e?~-J>=-Ij_Igv54P#YoktP)OK&&h95s-Mch?wM`Q}5Fg6(VqGeUYB zk0vleqCIF-nJJ!vPMjRBWe5W>ztjw3q#%>EjY#yt<&B4$1?7EkoC`#J?_qJE%1+-R zq7Yp*OTVPzZM=VxdlyIZ7A&%^LAFvoAjc`>6N`+D{7W?H+gEoKHR^xqHV`FR>F-^| zu4u)>D5vz34XiV4pKlVS@vj1#S99O5fY1_X8HTEF^Coz;%D>4t6+whZmDF5^9{HGS zM4ik)3JNL@IP=nYpoF?~_)+GP3o+Tv6bWphet5yJDr2Dz5-{+dt-+vMN9* z`dHpm*&JnmVs^4|dc}DA=R<48QQ_npxbmBgh)WvLR-C*~nXyw}{Plm-=@@zL#cN!X zuo^p-*nYt*eg_M9;oca-3s@du{FEjA#VoOX4|McXXU2b5Q0D1dK%Ys4+rD&N6MRn> z%`#ol`2qU;{0x%#FC$22W7Qnhu0mG0eb-`aDh)leh#Fwbow@yx5`TnQ{Nvo~5DC7@ z{W(ojNO2&FL-en(khoVaQCFn!kI7yhZ4 zHaWtD8mgt5XC)pj;NfxG(+<5DP$dkLf0~hxv+SQ}of`MB3ub`Pc{mTRGo?*L<`$S7 z%^|qfEH;^YdPGoy-*aWgfJrkLbtygP_C8Ms4>`r!>2liohZT1R zVooGhE$qeG-b+niW@l%E3d2CE?(Ui|`}FU0!`841K1N`vL>)daniljj_?lA^#`d)h ztmcYF!Ono3d=h-nKYmRsyzzZns^BBnn;=jrDLjscP)#g}0&*RuM1UDzz$GC*iO#C^ zlBm!#DIekLreE}-@mi%9WIs~;dpiwQJwFKP20HF_5uSF?K_PSn&%Ne?IjDTwwll7n zDbQ!yaGbAg{RihJj`YlhqdthE7U%3yUxiVpSTQ0(Uj4m}n>l~PISbXk-E`ShKF;KU z(t~Z-wc?Q%cF!`)bC9r`mWoLc^%qxpKL_V@8{O@h`}Cl@5TcF{U%5G2h^GkemEn*F-HYnZMfEPftRwG4)O&id9p1kq z-;FJFn3Vi!NRymiq}*?+0Li=>RDzp_CG^n#$Z!Mge@!SC5ml(k%$*t`^sFW*?C9ax zIKo>Eo%i-Ww|(Lnq+e=qZ8P14i9FF#4nsh_QGZOL6B&`Ihqs3nVyXMAMnDPpNh6?V0mpg>Qx94B;-l#29s-VrD-7 z3Tp*o<23y~#_`GIG96ZpEI6LS;E6~(0Y!mG5w;gesE)YD0*}uKnDS`!5{in8oHA>` z>TBCoN8x?_w>-ja;gBNjrn8*A#RZ^?(%A^}L5naVCe-oML?fmeh*$d!A`eg!p8pyNzm( z^tJ2UKjsv4gU0mkH|MstjCqYUaz3|p@B9m@N>2C~Z^(MbG)^v)bdE#3OG4l{Ucvdb zxrtr6zx~J#P&Nh!1|l?ae-d#GHgb#$kVJ;v5mTi<;_zi;*+lqj^I;lUTD-1${uVl7 z!-g>}^wcA7zuDSHzx4Zc-^nN7thDD!Nkm(Va{Y`!-RmHhUJTuz;7QYz(Cc-lz7dsT zDW~!_E&ecTPHZc>{V5!my0CdIjmGvaT1Qz~8KU4N#`=;2D+0g3pJz!QCx1E5V1(y9 zV;i@})4cgyMyb`0hF|3HVXfHxXQ?-Lho)3g-$}$S;ZfY*_e9q{BRQFj#BD#?Bm+hN(A&%zT zxse{i%IkP-sc6MLwtHd27w#9I-t)hgh@e(DyZDAZDApH*J*!6ktNI(O7a7+@8Bj0I zZ^`IZw3C8~s-Cp0uRM5#)wvMaH1>GlGsGtoOGK1p^sGW-UJ8Lg#?Z=CGz#0Uzl09C zRPbpiqQHc=-?|B~Iyrd@C7EK)K`HVI?ZOe$Jaa;)~+}0oy~f|>}!G2W1SrcctUX1U0fbI;I%;O=qf|^xrzOy za_k)6jL+p43NG9>*qv@wA9s}{OaT_EbJp}c4tv_{omCz1i7@R~LlK4$l=IaeWX2== zt0Zbh8SyD#ne`smeEh%y0->{W!KaWyG1?FzN}QYz74O=c&O!A1iAy-6Y6e;}OY zni#na;dQw%bjWU-vf-Xw+l{!4-|X!TJ#*(@1U#=f)0#2lg}W|8_agraCyRZ*Yp?Nf zlTtlZgts*?E1#+VHmf&%TvC$>PhkQ=R1mG)pKdoiS0bsY^H+@UX?_y(9LIGdSsgSr zsT9d8i(rVwBy6n`*8^YL(0OC~#njf%q&cz!2XiZnt#W8@vN^)!yx^5t(M_FI;)$@Hfgzn1G=aHsRI%ha^^Ho!A#T_YlD_ADVie%i~T6#E^a&8 zi4XSbvnbEqgWdj+-HsNM65cqV=mA2#5f*@&G~ayV=G&4?(W$qGH zYE;vTK;-@D7R%R!P@U>sgOBK!z+A7g;xs4p@ z(I**ZQ*kDh*b%)^8&3C}z?e}PYgVr*vp(S{$6>S0d&$QZth1weJk~yb{Pr+kEkBZxKCM@i_H_UB;3$x5Qv`5iC%dFIh6` zsoL?Wgulzm`)cZb-peTPWzhBF;dPGMKFjgr zUnGcRQB`O^&oTau(D}9ZUX$;S@_RE3!fjT5t^q>kpe3dL5^AOTs~X_d@=x;lT_qwO z@_d>18`Shd&DY;M_zxNcY2KB6H?P6Jy0+9a_;v?dF=KL7>c2Zckp>*g+K)n}d~a7A zo@DXI4em||T}MpI+aF9^H(l2ApqSpLJ{{6fjMZED)78wbpaO%xZz3|QFCcOJ(ui|7 zc^yNahfvMUrRU0iFpTrazpQ(ki2j;{%cFmVie#o41e47zu6R21&>bPX@2PtnjxE%n z%J?8bJL63CZ?dmfsFT+FKA#UZ+Jx4kg@3jvU3W-Cy!myMCF}6rqq<}>t8sH>jGBT- ze+yB2y5TH}v<;n?Gtdo1X-b;RauiiMxR#>6zvH6u=L> zWv4=Ab*?mPI+Sh4$@W8e<21;EWP&jG${)?b4k7*Lr{d*V^S@}7OT-q%?}eV8pu_dg zoAvaD^xM?WJJA;l?boUM^lm6zNinE+nRB`b_-Q;6P<3$J_bjob7zTqcX1~%Rep=Xb zsg|+XbS6Y&CYzc^l!W(j_L`3q7>Pv4MTevm;zc4@yMrePa$nD>8iC+71DLYI9pA(U zY=w*||HKm;i&9P}{)ikFm=~jzja7bU*uU+7oe@Jva{Pz^BB|Ar$L{eWqTOz5iqli9 z6WZKA+p2J=k<)*$-yuA`Z)47$1nKMT(ZpSY4bLX$ zg@{*UFi`lExBg-Xm|cZ?<}@Moq`w6q7Yv^=8s0_~e38LT8aC_!`6gx9ohr_|v|~?~ zL@5ZXn~BL#kK$dA({Qu_A&#!Hxg=Cv$dmX>3fOun7He9(EaEiU`;3I$&L%5o#Nm^B zpW<^L^ik-q2@Xy=cY4h6)^_Lwm99@wMu~E84zS2kF~|fYrD8IA2`M%rGJAm_qEY62 zLZhC`PAi6dxOmY(b|ZR>DJ?B6K$Us9s`l$2DQ!=9uGruwaR^{l91O6c=co}iDj?zl zeUwVWo_$Kko_S(${lpELqO0E0GBQZZecf;w;WhBdlTD}DD&H5^uN`hUuluqlix>&w zyBg>+{sK*g1#- zoEMzmosT_f&#NJB<`+doap_#&vm-3kLnUH(QH6uI39cshYiC$4@R6-l|M~OhB-u+1 zt&STJyzx;+$3L6fdN;qI{T;Orn(ouw>7!84F7#8&xoxTZ1H`r?kECNn;}K_( z@2BGiFcjqGGSjSuN?~X|$BI!aP7Eu?1D<=BE)JKY2U7+TUaN+Imn`u3EiCBMM%Lc8N;#Vo z6Px{=ot^(mXReREpIMNqU)Qyll`#KlJn1MBs%$%Ceon$()_Y`pu$)%*LEHuVmN0ki zHM6YPT019sj9}GKA)XTccDbjElXT4&|JZYJ8R^acAC%zgdP2;|uGc^Gfa3lq96`FynY zfGE$u)R~rh<7jwG+;$cSOkDKPTbK8~7>c-#&NtIiA#iY8^yq~g@BfG{{?hUqUG)d{ zSgqID_M5A1@_*82Me2CAS1*HH=kkxM%*+;eBQqd3;dypBd%It~VA_UTFCOTxr>o1< z@~#IxznkaIu+wC4(6ic+C+6-^c}ckPwVQLQ&@BcRZR$Hq?3ysKq=AoOm&THPMyk&V zKwc!ZlA;>bV)e>jd)Af*{G&l5c&aqiegym+f}+a7H=`Ve5t-mGublPj)8Kp#|A1T- zjR~tBJJ%k73tuc@8^=uxC1&O0?8}5+&$;g0A-4)WMnjsRW_vu>uQK{b4Esd&^mn5l zF;|INLw#=ApUr}q(F)A;I1~IS#2s7%3vY|6t**#_!z`+kI4z&7v(EYujSrow9ULCY zykK`gZZ{O68RR7n{;8wGt2%Zp4qATfb}!;D7qvxAhHEv;0_R+qCb3U+}6&ezLiqTc?(^UhokH*v+E6Eykci zx2sU@Pc!YAtANZ@1Py@?I=RG)U#<%Gd?J`Pq=9V z-s>J*n_iC`!>C${UO~zF2CpmMr9$3cm}FBM+4KEJ3$a#}#hcH&vS^O`ps2I#vu+Gk+)^FtI@SRr zX?1~!YNtw~C`~f2ZPo8_sX%o>Y9$^~hoH|}vEi;BSfS5o?5~j)D(HsrRSqa#RAqdi zCBPus&QKq;@<)2tJH5_O=&OQf`gCa7$oEXbw=RTKRyfl?UGu3W*YFCyTp^16Lt4FW z+#aeMN|=|@!V(2fk^C!~#8jCHf>^oObvCtxy+Cn(v?KG~!r&)42?gy&_?AQ-&=A@2 z^RxiOPL|*&!EGLNv%G4vBMLNA<@$U87=uo2s*VI+)u3knb@6^ue7@1U=YU@5-M@hX zmfO)Xi1Mpj6vi6j#&9#}hEpf045P(1;BCg$L!B@N?p&(vVCwhIHH)fJ^joKnnA?my zHo=3V`Zc-#cJ5N{>oj!LlnO~hJz&24K$=v4NR#J$qo1a9_ptaT8{u$r-im7+&2cB3bCnWSiQG$GGpj**}tkT zqsK5fh_@DO9}Mr}NaIINQ}v!X21{Iow0E*IU1OGn&Vl2)pzZ0ClE3;idPXeh;mGXa zelz};JLbaiaBulfxu7@ctcqhsbA!9Lm4^4?g(4m2DbPB?GSLB|&zFy`1k{C= z{36@$3z5k*VA+tP?q{s7HpMux?V_h4k6ajJzS14}sxvI56;rkU*7mD!m#(N9GhMv>sW| z9AOU3=8QK_*oS*z>z4>7-1mmtW+mvQ3}JI=zG{~ ztszqEPijpY!#k>(UcBU+a@kJqR;#2LND#}e)E9wv?d{5R;VUf8{>^$QSQiT^^2>WA2@vcwC8zHml8Sil84 zlp2qM)gvT86@PWtjVq{Yax*zO(TV%Kj=Q(mc%Q+y`f$rAqsQZC4|}h*PW-%ZBJc$& zAtbsf`lzRO2eZ~>$UcV>40OHNFFl2vvD3G6W`b=tQmNDMQ!D`_95;x*!PgEdC;wx5 zpwTjI@JZy_aHlA>)`n%#B(J#&gN#Uj418XWhtoyZ8vh=Ms!8Fn+oF!lH76laugC4t zc~OOT4b-AO&pDN8qv?oeKhS{I6qp41v_FCAxRa!9o0h*d*Bl4SD7$}oTQPUB!6BpT z3-BpDCrfOn1jDG|*!wutscztwfUpe+Y{!27I=sI^_$7sGD<+44PKlWOpHIib`2`lXWmLk}|5-ek&xT3AwLVM=V;eeRQOs$YRtSP=;t^-z6J}u#W*Ro| z=hwt#)ikR4v)2=Tuwa$Mz3Q4P5~D_Z*ogGgV^B{R68HE$tUV{EJo3`jLH(e=5YbAg zS58aOL}1}g*uzKFWsT~Fe%sZd%D>n*#yFpZNiaSNv6EaO#=>_tW89+}yN80c^+I1m z=7bkkCj@9YCIac5bYC6-e_^?kD+*xD+WM|a=(~`6*rHUna%z@5G>1n2ej_r--Yxq|OV`kxU2{bs^|H^vw!C_Pps3i;g zD+4kedic(-S)HOpX&GgTfv$mr)Zb9Fo6vItY9Yto>>GE)dbbbl{bgOvKtJ+=-W@Xc zTD`Nar(@(NzXzem@a$-VQvJzo@+_fZ8%N;nA@i~^r_Jt4#^``2^w00FYpyJ{l* z9e#rr$8y53L$k>o#o!0R>xc6^ z!%ciW`_pneIfJTC>b{cSM8UJX;Q7?e)MT5d2X3yHt~;5reopvvC9TMAEOC<_qnP;M zEcRrw3!9qr2Te142s0wL4w$>jRWgT_s>b_n5j9ey=?C%pgCN+&der0vCqrB{fPTBw zo!B7hCE|j*Jm&Wov26^DCaZ2gaB?@Gfq86B1Dak}?cZBxWEU3IL`f z0(IO#|46sOunE<2gii?Y{SA+(v`1)gX&s@zl(q5+wN4Oz*bpH^kK?)|Cdr5g<|a?E z6|3&#s4z>JZP0lf<`^y<-EMh9C&QBi1w+Tym!;@VkkA{$kfs^Q@I4h5dGh=hyCf$* zFG7GV57B3v{=m}DvhS@f;;<%Q6l@l0Y6j!R%AblJhBF1meD3CK$FGWfI!DEQLa%dg zCY%A2jnFNvGjx27g6H{*H()yr;%Gux5ie6E(dJUw+eo@4q580hd>9P==VV&=epSV@_H5?Ff|AM+(KdP-9#@UB&)6^ zMt6XJ*MadWTlKeppxosu>>JaiBC{pp{Op3_Yr7~S6cdZeN5g>2N!zy$-3 zRNOkO@J87x?z#V-^%ea2EJ+y@dl#iXA&o~Ey^QwEF<#M}x^QgtJ4@nCP@W-buG%VV z(dspi`gLGin({BIeOA{Nd9a%Q&5Xf*_F`l zZ?D&~H@!@TcWlu`xg+R?Wo`{DW28mEJAB^B4kKKb*5SnQy?U}#zDe<{^_dG}a+kts zIWM~Fk|QBnh5NUSqLE-OtHF;6F8Y=GypTP+JNf16>S`HT*}N|7Vc-JQUfSXrU`(DS z9FNAA&G_&}Y8TD&Q(-KjtW#)HY6i~zy|R1Vc1q+fP2ZxDB;Und6dde_bo4w$9KBId z7v!yYaI+D+$5}f5$NZ8`o0!5g2_RKd%u4?Q;L`|2N)w_fRbYseVoEh*Tm(vB%jFfm z|Ky-jJX5SuV`|0afTVLfbpbwAU-WRq$;PxxW=(A?%#qQl6Oi(H@OxEUJYr30l zQfPMQbX*-=s#S3GQ>W2z%eBX)&jmL?@&Vno8)`I04G5_@X{dl=#nyAfh9qZ%go?7hFXDqG)p= zs&dr!;H72jrVK0yqG52>@!o3(Re7<mcE!>D{9^&Ij?CVy0&+JS3DnQc0kIP^d7%1498XwhprDme*I|M zlm2Sh=E@tCTiKa{+o4I?y%C+|{IA9qI2H)&;KC44t=j(z*d z-%w$~wAudYXwGpcp#E1^c&~XTw=Od}2Z)bs1sEmU`z&W59ljT?ioKKD5+Q-i9sBdW zNxGV+T*g>LC)N2cZoE>R-CRl_BM2iTP$4JTUa*y?v<11;0ywi(< zB1bfZ$Bd66V-@@ahp2^0ouwjREjC>`Uy-sG#k~Im3r*H2vEt`YkU3G#*~A@@OoR&J z-|#$3Gu)tw^Dz}U9egvx{K?Mk<(X={^b{Kosj*ngxP-z)7FKXBOLIterDQXjPDt)M z?1x`kl3qwkPM!G$MA+X&*|eiH-g_B*A-6cd@ba#mKi-GQ6$Rln{JuoT%wqzYzxH>@ zFR~IgPS?92c9fyYEp&ul6L%^vA@QfdZ=d_WX)KSZGTOci!Zag`4A)@{SDJNM;p?@<4KcvRQU}Ok*nYa7Z>!t^p7#E!I)nzW+WRf#1W|l;7lKi!WrWLq8 z97^7cKe$1Tl5elpya;Dz;XbRU$tSueMZoTQ$7LNmYE{2 zv(FSkY@C&#lS^RGli)>9-=5FTjWv#qD52T>NI7&u#d}+*wGVo_8^5)Lmc@p$SJC~~ z1&VUxeeO)4H8{)CIhlfI-OX`iml2WFIx*D#bv{P}!a3H})2oz1VBv%PT}-pqZquTN ze5F@R#N8Jm%p@&&{28NrPqQc($#Ko=CQtP0y|6ZLr$$DflYg&WFXL%@69=yacLp{m zG)RAW1lRRa(iUs|_$ixE>t?aWOa!RjQvZQjb*w+>S9i_#7+3}SD|rb1cBPfD#Z|fx zCgo4SS@rZU!R0IQoVYm}Gl(z*+;NH4o1H|!nu^a zwy?0MN^A35E9M%+@(fjyi!?Vm`)fY;!KCFe!FQhj@76dRbM4MFQt&H?4gezKSqy*h zdO_0Ql*QHDGuZ5JcbbMw4#i~M^()LR)HstRr+t0dO!89)P26M#GtH)7+Md4Tds-Yn}jH#(@uM+*cFrd$f2IO~q4-zpI zo7<)npxQ};&T)+vEI{ry|Ke1yU3wMwI0;%kb#;q$> zy8CAPGew0;gv&LRP|Bby_YF6!uqA>3RzM|{QSVMbtTbz4BX}K{eIcs{3x`H*Y;I0N zRAwkB?A6xf&R~S|@&p_4Xym&3m$(#*IJ8D3qM3zk_%pJJL-z-U5}VU!zTCxF`w`WD zJ}3j)_|bKH+kTiY!O4>6+gko3s?n1ISy`MAdgYeV+M0d_ky@G8&H8EKD3&7pP$VV@ zQWfkn!hEyfyy~8tQ8|J0s%inl%Oivp@$1*V6nrac_#_vt`H8uKKJP8~F6PHM9#fWx zmQy&-ny)5&Tk+_+C=Cf$EHWZ zviXEv{Kd_K-pC3FsA7C$AbDB^0wM-r-+wPY-=6mT^~Evq5;n|m!snuJ`{LURF=#24 z5;8DU$38iLguaEDOr^t^Q^544RgQrQfDpwYdrfo{& z5Lj7>ki%`%JesbeVbjP2B1>e{q?U}HE2eKY?lbU`8NkyCOz0k||Hykun@G^$N!y18 zR^-2`Rc(7H72vZ;{>mj#E8PezS2J=#4Ihv+(T;!`| zGdeMs)Wc1H7Rk0qP#_L_%70;Nv7a$4>9;J_o+;n0bX3esB3mE1A30*o{gqEExu1Du zv1Knyz0S3$`ujztj5AIDUmu>jTExS)EmZn?uDx1xR)C?&ScOYYyJ;VV z;`>PSh@7p^tBg6}q0zTxBrp9$`AqXr-w`?7I?mA5Lf|9-nM+2mR$zP#Icz1oVxW+^ z$=ZQV?3+me3h`GrCLfXYJHCG0!=ua-?7NOu{mxIXnA+k+4`kf%rL#&)5~F>dneta3 z5!sXFa^#YWqI3hycFY?dL9{kyoMyBJ?Zg8JcaWXmR669G_{9Yb45spvjRS0oFupB)W(#2F8 z$+f^MYY(!ilrro(!v6r-5IIAKjF7e)%=sn&z2{xOIdR|(7(-6;skt(LggbBW>VBfv zr2XPy7Mpa;+SJ^HpMl8ZMy{T8pU>Yj!B@7sLny%HeFp{3kgbrY-+kJkRWv&dMfseKmxdCo!PDYV)QYi0} zqdTrGn8iuY>ef3n&1P@|oB9l1QBFa8AxiQnwu~;yx3tFr3a*ONKhj)w5pl4$pLKKi zi3q)vD!~n4CEI(2*)V*`(y{kS-r|z2UE6c5Ap6g=zp*02S%S_#AJ)32{%5#r{2`sl zIHBO;7Cl)V-6Y3Gi#`9IEf|ze^i{vAB~W2rcGLn^ z!QbgZM6INV zCR0K7k4@bhk_XNxf4Cw%MvR5{oZARO527m%PHli`Mk^JW2n&vdp%|Z}j1l@5?Gtl< zRn@uL>;+ywPvGAdaHvsZtM%=qpMrD6qWmiHzlz_SKQ~V&3h?oU8#{_#I@PUfxp-3l zT%sVw7^nCoU`QW&5RQ!+x3H4PJWbbE!bjpn`BR8^adyx=q0$?|OJmUKKP1Jhf#yVH zC?bj%c;47ZUJrq&4*3%$?pG8RJZcymr1XFhE#XGY%7}S1|cbd z)NcZXR)&VcIvP$Rujm-;9zv)ZZkU2jlIa$?Ig|J1IpGjRnEOJ_ID{?SGJ>5?_IE@{ z+T(-sw@2CqdG6d&`#KJ_F$?5tF^UuDHZgi;sxkA>8Me`%7iCUSpYjYyVWm0?TAE;kNb zwwY_G^k7u~+LhIh_!CGLNC_(XLHkKqCs}n%cxi5~@5QXG9V&IVoG-|%QLq8U0EW&q zyr?`j!^rbd5(P|4QIad$Ejb^VH9j(#Z2PADZZTGof9;L>^WkqWNfkaYq>J)^_p1g{ zx)<8K^^_yS%IEpfev6lhHNR8*)C{%~ju^zzxjtf}p%+m{F@_2IDMmy_W8r%!*D zL-z(n2}vU5e?)UR;}y#^#*lHynNy4Ykk4X!bBi1;n_XRstX<^e=?og)zzqf(uzDRe zCTB$j1{LZT_67=0&7lR+0kX1*ai2Bpe^6sW-17P5zwEfTe8824KQ!^c<(uyHoxnTd zC1k`N&#rbukPciw7nrhbKH{RHrk+|)tmc%rcv0*FSh@HF?q_U0Rf@@S3R26mM@j=yf!ZY8nBe|Jd{j!~C*E;02Y^ zS;^1g&cY3*48@}DAEm9^{S@X8K>>ZI^B>vSA3j~_ipnw{C(ZIxrFY@=oc4d*e614^ z$zer%RjOeAHxE|;>{c8-w`OIgUlvfZ38U6$3dFF!8O1q`J?*IH1=V}ArAD^Nq2^t8 z*M}!2U5}E0f=tV8tu^cI1NoXWYQ3Wk=-t%H zENa^z=eW~)3E%0iu$iTO=+`t)orvPk?o6BJK@-$#W@i|6f$MxRT7+znm}RrKtW{y1 zD4t@m-7QTil?Q4b2@z)Ho$N+yi{CyBV!Ef6;^c*|ou&IiuUzK6lqeDHR2d*g+=6#}sL0n+W4FLf58u#Pw;u^RdF-+Tt ziiY^ru2WR-?wb}NmbN*~%~L%;qRpyf8TE=s$1X2BzdhuMPuZB~{H!5Yl!M{0!K-CI zbM6g=d;!IX^8xej60G>|7F2wsy%rZ2an@E5R-KYMR~%OJ$yWDLLuPeK3%IpS&)b}{%_Sw zI;Tw<&dIT;tiJ*vm}hxJZDG(LblU6tf-8^YOlYlK1!dQ`SnQD6%~@x77-`|*U%NHG zbjw{sR}2!zfH<7Z#Set-!MnU*h*ZOy4EL4JMhlFeGp{IM*>< z^SV6ma^)_YCKBG9le?#~wkufoI4|?7YS%9biM`LE!SZCe@@P75eTA(Zda;7N9mU$* z%)1BK7lV+Cqh(O?ahuQeX>=q+$L+lxerL!zT5FCEF;VF*If!5_lXS`uC`#`yMIC=1L!_7-fuWU8k3dil#fXEWc4 z-wQPTnkg&Cr5yCQ|&h6uv)2?9M6Sx#siSDIQ0GVvL< zfAnN@EE9B?+uv7}UYmUG6aF_g2QTUge)*2F;i>!&iV$*ZAK4r^ZeQdNgxL{QE?$&P zc5zfRVRetmT@8mtLHlH*!Pc!XLtVqg*N^{yW9;Jq=$kq{74siVD`$W@fuOhaEw=r8om&?&v`sph{-Ay1=yr5`co zk~t5w2VuQCjmR#q_TxLw$f|W>xEAJzkpk;0;P z2}axdgAwOdBjHg&_9grcGWNNwUjt_GFnJaEYdRY)gt#^NviS+nte4D}u|dA0^2$Fy zWbwEMZFIkKcTafSB9%&nM}!fkRj=w9GKv=Hb!ofE05!mFcdfLWR>Q5R#T~IQojGCo zFy^)8(6xalD?f4uEG4tA`OZOgc-^fVuaNBiW(VCkmU?{v&MG!~92V98;pwb{qWs=A zPDx022?$6@cY}1NN;fPZ9ZQFFhe&rxNjEIr-Q5jKORj+E`}p-Y@5~PT!|X8UJkL3I zT-WC|+1~(vz-zkUnAtg%Q=si?aSUC=^09Jr zk){*XK_8}`hLmM7#Rl(UYO@+CQq<8+oerR9pYdPtT z2g!*M2S`1S;C1WB}>)dWEXHIhSJsJ_JaeI z3!l^1XQq1N^!trfbtr9Vi$9|s9DN@EPoanhUmL8ik(qf*@6X3_{(RfdO-+j6``%2> zgE@U00sHftH+!jYp1W(hvh=Ha;jg!>z4aw2{e6*(Qc_IYHkH-*uXbVNXfA#jF%vl7 zG2lrXu4mYo*I$k_hF;2(#fPqe@y$JKLH@AW(Bry12Vva14-t+CbxF$$IeUoB1|V2f z`mG&jDm(8@$I%+O$SPeZPA53TL-ttvX5569D|h2$9Kh( zO)ZDxw8h$}$Ih>360B)N+3}_eotdNB@*|~PnJb3U4~6F7 zOmT)qJe=zUM6a{FSe#-vR)ZC08M$OHA2jfo~xXm%YU@i@d&{VRZBa?0u zAXR$L-QxGR!WE*IhQlU`0;pAYnr9owXo==70}ivd>7=*ca*AHj@CssS@kRhiIGJ_fB{}t*jzIs(Aks zD|zTg#gJ_^i^^*w#~_Zea&{t;j4Ocn*(3>x3IXfWaEh9K(bOn7|JY=rklgZKH=WDkU`WPueR1JLXCw2Ty{nD3j6RNJmGAUx?Q)LGiX=Hm8qQ+uC1@q$FHB5 zB9M~y+uHVLS{i8I|Lq8)9_U}Sl`$CBOBS46SfqHwjwvp*9qof54rOoHV}oioN!Iu? zn;yh%Wlk(>#r}6uMa?wP&h8{0lS$~vX*NsWU3@ti;HL#?G_(A&0SUKaT%jcoZTIs$ zTe%zI8j}{^@cgwD!qDZ78eG6NCBj21&wD{199N-ht47VJs-TV)Q2jPNRtPo=L72RZ7tRZfxIk3Ok|)7Y`$TH z7dy(1$d{96Waan$1Ckt<(uM#X4Z!+*th1&Zc>8NMam;w`XV__?XDdj{2D*sN38@07%S%fosZLyX>tOl2<8uqB&s zU2mE^3%^xy*llMI=*Jp!(PEwMGrt61PMoTAElGomf9~2{J`@vaK0-X-UV|SJ*RW{dWK5 zNhF@-<`Lt*nLmRT)Jos`b;4w8I0nm#GuCgiU?2)wOQ9qwZ;XlS%UkO+ymFm(U5&~^ z`Z#1sLMl8yx23(09!q$G8Gm{mjj;E-bNLdndwOlAf3jG_&mPkqA}VKGJ`~3%W2|q! zz#JG$`;8sfBQAB|Y&eIGmnV|1R{dfy);1ky`CKHDTftUY=QYcCezceE6<(6MKy<2; zR}f@T>9m62tw;0UjpgN-`OGBI5ml;E35ft30-kI>cx0eu6z8a&0LLh#k=?(d(TP?e zW{&airLY|UiyQb)x<|cTIqsGH#*$+1N0YzkE~Lw*$21MUV&^5y!%OhVjw0g4M|@C; zm0o&Il|64=f`F^g)DLLO#KmBz0An=tpv$jN!-(B##jGNY@(cBAr9VGeTn`zyde2}Q^4=zvdtZ;E~SWeYs6mR6B z6|Dx*%XN9tgV#)7GZhos4IHDBC+x@d+FKxGV}RkWPzqHEs=2w^o^%b>gr^{oV3oq~ zcqQl(l8}%9_8jT&^{%TI{QDTp0RX*O06QX`+UOZ3H2=Mv5I-a~DsXrIJHttGfFOTo z8aLBF_^7E0;6YTU@}9eIXGJ}gdlNC?>X=koj(7fbyg3F_nWlsYFK1^}XN)-8>G#cZ zfH^&4i{(IWVQtzhcI_L--W`sa=<7x-b=q9QS}l3uF2D>un1| zU-vK%;$IcmAbgHbYr^YsJWK4tkMtKT3*XCL;u8tF^Xy+>0~xmi8y1DR$#?RA{E>j2 z5d=hTigvG6hQuyu4{c)MOnRt&efG5Msp~|Uz!1^nFKIuPuO+9WD^QKhWe6Qpo*bPn zu}WJ$A95k$+Ke?*Jlmvc5RDL{85ozsrnmdIo=&(D{-UsuP>bi4nUFy)0AL99(KwjG z_+Ikw#WDX1LCS!3-4?N{JX~wb#HvrEy|&|t2}_q?R4%gBl13X|60ju_Vf|MFUqmX* z=fTuA4jNJVn$2d1gV(D=qhr;+2<~7=ja6fbd3!W=Zl|u?6rFD>Ofj?YvHJ!EdT}vG zGVKXu^Ix#Bt`8Ne9jwyG;rCu>eTkEi3XN)*$IM8kG|kfXvgpEhbN@bqQ;Ly4idTw( zSjgS(S`}aI4`W2!;|8P?p!&70jl5s4N~V|~!Y@6&=c6hok!5ApBzuI9Jh(WPUcT%t zmI_JN8XO#)EqAxqIcrU}PHlS6Q|_E$u78qt9k!LCb~T7OMf4s=;1mhniK zi-{TL2$^Z{<`l9(Bc>bNivJO9O(&-5{uAHGyF+R=TYU20?o^u9Veyi&It*e);3vk` z<7q_oTzyi_J~Oi}6?8c8p^Mu}lX~IBA1_zx8zx&qO1eHK3`{4oyN~S;+!Na{G{iw0 z8~ik!86vM9Z}b^p(RvnO+`R*3-6@6jMB-5=u=~#98*z$osTvs%mEFX?63mceG8blW z%QY46>9pfu1lkWIloaN6b|Ta##(kKnKi)LUXe(}G5(@x< zflH`LaPXNJv+#<}(3EJ!GhqVB)R2QZ>F~95fvHa*)t*npMdxck|8DZK+=lj6Nir)FG4xa7NK;hzh|4|w%3 z+n$=$&(zwRu`XMdgpVGLKN%(kL2;Vadg4|=?(S|ga|^1*O0E8tWdswLqsuWDj9=eG z$sqX17@kO1UU<&OC97=>?+)bb6K2OibUv6x6Yr&1VgN}akr}mN>NT{+g4HO9<9Ak( zWodI$)2^42NUF`*cc6n}AtOEUAM9s`(RdPXsb=84^O`>I*E}s{96l1$8Tvy)E3N0H ziv%n0Yh`_C1^0h`bYL|A|B4iYse|1Ddq7YPk|s>%iuL_t&Zo|&l8M;lS;M#G3Z5>^ zx%o^3`;6bfqrFi4`_H#jkAIDgTL*qUM%73U|Jt|-y$3kBTXS}0|*PiyVZ;Qy7PLW z73pQK7X5JFJmK^Jcp@qtk)C>TQ9j4?BCLjw{PbAv?_={d$`#s$hs0TRP6H`ZsceOeZI zo_Ap8ZnsF=SNY;~AMGM+t^ZGQ=t*o8&8JGUAsQH%gYn>cK9TTmi-KN=FD+0-R&2I3M5OFjPQlZ$VT@X01HsH9&UpsMJJniz)5=#Q$QO5L5LAA zj9O?qxx7{$Xe89vb5j@*5Yjw~lx&OqCkv5ffHZvzSFjlXY~|`%fsw8_1hc%%mUtvF zjy$Z54lHw=|M^QoYy$#YO+UwamQq+>k6&2m zegH}%BRx?VBhEB8nv{(%QK1nQCE9sU#6I&&Lmy@a2uX@R)KJ6|S5e8ir}Q zPx-tZb*Nsq(ejNC)99dB1xd?E>(0ZHShY+%Zia&Vc;+M18r6=^Px6|}xhGMzLvbme zr+t1Z&TVXH_?O`CwwKnO$vt}vu$WJ0K8+DX{dH|B?gueZi6kRC^(|3OaQw$L1vi!iFtj{RMhvt8q!@3MXQ*^ASt- zZM9`M^Mx302m07T_)B3&uWXd%6wa>5Q}oIbo(l%z*D}`94(X ztb1(UZ6~R$=HJ^s_b-%R!YDL7!HelcNlcw>45}FS_0dy8o9HEGy^b#67SXd1%{jX0^yyWpBHA*}Wlmtq<&7C*@_ZGQ!~S{51R za#={OB0p65KJ-gmy@j)+chd95(!%&;%9q9QC*SR`8xf~JB=No$8Q7n{br;63Tn~p^ zwH{qiuV$*&*UQw`w}p0IEDHFDDka3!(%C9n6e_#pwlZMmqI+-9-^}0WD(9T`500rZXU$#9D!4{o9nVc!AG8O$AN$zJ_eAf__aBBz6 zJP`;`;{~4hl5*}^hI645w_Cj<)83N-fn2vj&Wp>p9+G-&$cU?pYcZa-R|QId?jOnm z`5=w*f&-p0c&1Uz$3IE)Y@>~z!bn76M_3TZR0$I!Bfr<@zx}Hus}R28oiwb{T!^+@ z;eOfs$mK>lI8`;mDRRa&S4hwWmEh3*diBo|hI68E(_2e}f#iB`r6=VW#I`Uaj%1n~ z$zo(yo+?1=RyLn*r8~AN|0YHxD;|<8DjGIq1=L}pWIXmnh7)zq^gyU1nl|erN>ibC zO|z@!2mleglB+Z;0wN(J$$Ym~ts8p!A<1Q^pkssL%qDAR2Rrt9+0V-JtQMZqucrIA zXktUN>dZWc99wD$wSFG8u$;M6PE{P~MO%4)xVX?LEiCtF=V|h$HoU}hTPo4O!zpCr zoc7Ft_w4MG+scWI6|On=qInz9(Nt9pg3pTOpk=F-N@NAo*MXF53f-zL@%|2~SLSk= zxi$W^LG8VkDKK~UniAWHa7Xb0TG&*6FP;fWM%a$VnsB4Wy*LFK8^)`FpRqhCn+Kbj zo4wq0N$zVb-VX;UjzihAIFWnON0yQt9<^XuhyvHAKB(Z|EtzNN{5}t9|7NDtio}{<_PT;>Ammum1*3ow80x5Vs`!?9aQ@*o~@YXB9hrMnKAVZk&qjt z1AzWXgV`!F5nF$Ir|Jsr#(=Hs?$^c>{)94AT|*JAS}rFQ+&$uI$_o=H3|Y^h4u#G2 z*}y(VjeAao+`2c;EG-Piu~~7?ZH!-BSi1A5xcs5O_dV-7YWY*88)wKr(&?wYGE=;~ z@WI4t4nx$?zSeDgvI_Xm5^#mqid(_F(UXnvqn$AIgMJ&tn7DXu9=-wSGKtXe)nQxb z9hb(oOs}W!=Bj;GlV>E-^@A{_o9;==y|ez>6{BeY+acObV#oti?=K8R6lhJr3`n1t zLQli5ma*tRvU;jCYc%oSO9Gu^igf@8Q))od)XIjT>F|uIK+zJ|A2_Ki6;r{SS87ew z5s`nfB(LYqd!KJVEzAUVaOC(P99DH)(Amjh)J_v^p?vgwvy^A#i!L@uV#UAf^3C=@ zr7dkji`}YDct-T(S`&o&jBNC|F`!57^LWPGT4LnDv3&MN+lDq9G^l&|JR5E;^!)H6 z2{Tq3>*~TnWGdCpq&{LNOcLMtX%Rlh^N?|>bG^sl%6rqhKH1T~BivEUEy+>TnPTfv zmP$=L5#*E?dfZC%_>@UXYM)QSV`6hSLE^H45RN_hW7+(L*zaZCi?$n)@cS$}Z4s3w z9!X;#L}0v&X9zHql~$jOPP;{s?{muiAgtvWDnse}10mkeB}^*ZQp2bfKL&eUpl^># zcx*2o=K73Tf7KVJ!I2tXJEGco^?{*;&1mXJzg;_Bp*FfR=O`$*uiJp!^*yOj<|cB5 zVYEHy52dg?_!Sx2p#rXGMw2meRh8;c;o##?CP$6#@qlh`FNUcp5e30a5duy@qeS@F zsqbx7+l85n3m1iv5CG>?eV|!TKUV`b8%EUt)QQLYDsy= z-1*P9Tf_DOG@rNxv&TJ)72n0#8CS5zoTts3TiZo(oLO3~KBgKg6_-?&9+R&B<}0r% zULu;VOl;@UB7yCyN+;^iP-<)G#1Edob%%lHmKNoW=P*oC16U+do+l>jl{`Zm&m2f<gJdryI=oBEKVi0VRn3Dx3@e4W}JqNp6d=t75}l-6d&>MjbG#EgEM*17tni=-wdzyx9ucy z2xkF|KCkVU9NW@&{g~!5`I9{VQb!K##7Q~3)#pvWk7($Nf9!s~QHG68}T!HrRjf?JhkE-gQuC{h;qZ$rKxgZDV;_H$ zik%mQzwSE4NZ%f$C8h_eEW*;2tV4Pme2&aB)(s^jDu}XTpf~=T3Ti>Yf0>JCORJW3s;If`^7V-daD}^DsHs8t9GVHoSqCJdmy*| zAq+L6Wl-YIO(@YF9fYFx zcAcMYML+1VS66Ml4SF=I397@FjJ?r|=bBduD^FD-$yS(ZDsE`f%@@9=l>7Lyjv05p z&}&cmR^U{mA={N~NuuO!0w+AFq%Z#V`(9dUrc(*ZN_`eo1y5tFM{JgVoWW-F}1b0vJ93SE0o1Y4@H49 zVpdZ;*SGlD2JOCIH0S)0hv>6UA;N4iD1)vgc~%{pAK!f2YjV0fMJ}&gGq8?0ER(XJ5RdZn#zFp?2J+*-@l(bS#Eoy z5P8B|M*R15v{-tOU_`TFk6<{1Mpw}S zbvO-fE5u>LZV=2e$&AXyNwoi7=3i}q>8Y!p zkm!Sxuk6EX0>^aNEj`pn?{Gp2MSfic7&P?{TQjSP%nZL57wBJ}zXRZ&7_q9{TzosT zS;-SU{3h)f>|N7?^I*Y3Q7_7lTbr=CBP^n zK(!umkMz!xPfd#>8%pH-7-%mgsJ~`!`JQNDq)CItU` z(O05bQP7X%2_ay54BaC{Z+T&(w`x+>y%DsskYZ}pHdVzpFsU^V=N_MJPwEX3Qm-A5 zZ~q`WG)PKH(MN(^NwDfka=s6BD1x-JaYl(6h0f9~;lt*|?%X%3PPp zXe&B4{gWUAV;^JdL5q9q=RI}K=VzSMA#W0rY)jzg+o@%0xZWeC+1N0=ZSZ{6<{#8{ z(egJomse5>d_C^+TasJNUw8cV(bV=bk5u9N5Q`a$^}4LQi}o4&NTXh9 zDPgTRxu+4?YV#kVm@iWyF;;$ zcEb(CZ6b!R87G1HnPJ@&YGZ|kg~5MujnyR0k#9?ERe@Lx_}Fp85KhT$)pzM(AFiLT zpKxIrAXEum-d@LAxS4kT!xM*ilfa6b_Jxi~Tz4P8b8lb=JFfE2^qkmY1Z}fW;PsNu zSU>z8KC#m{c&S@?VE1x#*P6#6rq?qzX>t7Zcd^P1^Tja{E>ht^dT z>4^mP+FVjADJqNjnwH}PXeA(av3QYFd{6rM$uwZy?L~*7<`m&kvKin2a|TtU{$5c< zEw)^Wv zA5o0h33W|f$z-}1-<#O*IHRgGYul9i`9gV~Y~R)|{nn|R7ku+SZewHO;sTK=9NVEq zOCq|*Z;(Ve&{dC* zV@T9QrOy5YNdaDH-tyU-|1OlAfvpih7W*!Ik=YLlPzZCY40+iQF9lVk80u!{R*t`^ z)?2*#k8UfG77j%y+{j#`2Bxh(k_^Z9tT?Xaw7oFpb$%#zSbwHMx9O)baEYs%CW>@Q zhJB2l9W@Vh^f3{wIrsF?=BM9MQ#x(@^W@mhBxkIxFR9M&IjYww{p45+Xb{}T@M?%3 z3e34@U3*ZUV20a);Z~l|o-c?`R-YU*i#YkiFHvf1BQ-NTrb1$3#{p<@gxD>+J%VUN*y#zOln;-`=HDb;k9!mJIFB~;D zEJKF}fhd$Fo}Tt>g}i0;UgkvK|GPbqN5;(V=rnQo_>o^GIvtX8_z$|N)$ zwB0*t$o%W^h!vnKZT}j0%=UPk{TT8B_0Z&&f<>oB3gXUh*Xz@!e&ZbPbF zSWgCs&025l5okE)r6E~k(z3)Y$5=AvdyQ%;jy7zPJ1;xYexTYNi`*35?=#jeuU2MOV&YHV%(uiTWE*6y8-uQzM6zS#>gvM>`KfgY z>k23Ka>6Y?*=9?z?r!WZ>u_6Sj0Q>*iAPQ;$Cs2G;eRVD^{^ie+k*qUc>w()1xM!F zMr(+Vch;1j1@<12(;g>}*w{3*gpeS=K+6=*U9K(K`8 zWYT11zZqB4css7~7Ad3%j=~yjosyMYm9)EDYcBF<-Szl;@{W78V$9!jLqFt$zucn> z6RLio3D)3LZ!)pT<4J~YC-UUxfo1_!%fQQH4F#I?W8hCE4Zli4kR?rK4I?b)Vzr}t z@U_&jU-C*5N$6my>L^9oCq(3oE5`3G?6&I5^5kNESX_z~Z0hN;bL!mk1Ud(tVt%4( z;-|P_>EJoulFCBqsvR2Pw$+g|oT;QAA0n!IL*yL}_TGS~MP2BYJO{T)W7XsbkpTBe z?PWI(D{J%=G;g1q_CcQLAJ2ab#$K)ow)t+RpoG9MDe8hQ`;RkIAP{ns4BL~c^AI%Fj2;g}Q%Qu7G05HqRt2Fb{ zzdo?lcaQfY%(tr_MSM9Rm&!!WLs%CS>NFLySQR=A1a&O$3SvN^r*`uK)D%aF4hY_D z`XiH=PCs5V5-mMg;Oq~p-RUOi$`G+pwoJ;>!hdd*XP=_|)^R0z(WO*h?ua~XKyk9& zHg%g{&*~6o{YS?5m#VtW^Ti_Lq*}r>{s1G5YxiQte&5IrYyP#UWhqqdH?bE=Ps%#RAcjYPgds zz$AH&A`wUu3O=Obb~Keex~QW=RGbTf{2Ro}=NkLvZ+rr*cW(&L?uy$JCIalD#LrHj2ng0JPonDI6o%IwsZ`~0+rpQ69Y#jDm8yFzb+jtrvz03wQ z?d52)BmL$Qdm%Tf@gaBCos7u5b((W?xOcnysXAZzCJ6?9T62Za_ifuTi+k3kC*;%L z^8V7WaJ9`LcVz#{6gRW9666TP^gm+j{WKO44M}5j8Alh&hH2>8=v<2Br#6`~$cb}7 zA|go=KA0dX=K@v1C8A(AFCg0A9Z${{x!ZLUxlu$XeiZh)S};Pks*8zp4SqN>fCsP2S#?BM>B4ps%rrR>-J<&{d za`aKZ%M_AlaYTud!xqX<$bQHj4hUgdM)^~mlfzdN%PbRzSx~W>IXH)-!T%V}w5BDM zQNaOnTpXxG%nne0gQ9+y7Zof;{Ra?xT|p}=<^PIJ6j92t=WO+E!XZoUvECugqgJo? z!3;fOA{y8c4(ypw`nL(ScH2TU6ne~UslSk7I?)R+C7ihc%8ZhS&J+FQ%l zJqxjIoP)mi>}|lVt*hasT7xGUU4;cZ`2=>1n8N5SNpe~Pwbd?Y?VxVC=eh%ito9Ts z&A&%(hA(m%iw!JWdpmw=x{G@vO@9*2H_XCD>O9_(POzh})stB9!D z_&rDGYe-WV4Q}S0UO1auS$!wxN}GeG4ndMYQ>=&n;xYBdGfa~S1mHQ) z2QDzFljbkJQw)*#Zv;b#m%OpbS2}DAxYUi?6SF)4%%j|pvaw@D2_3S*khDDO%lU@$ ziW-(E;mioA*houTy8yYUk^BIc?ZEfU4=@2$-33zYwsGML>Opt!i37LJhv(B@#{>JDN*2fGwmdTY=r~E-{`{#>t zwQH|WwzlRD4i~N8F>4h2!!=w|rT4~GRDh!d_}E6EnL;rIo_W(C7Q(L$r6v&^A#b|P zFje|Q;n;NKR9Z(DZNMIMh}j%6pLQcl;Yv2&Ho3MLuWQ_J+y2tBwk{9zN{ zq{SVuX0f`8+(wEF#jDn}am!5-46DB`sW8bYln*PwU&`Kgh}viTQq&#S zYn!8q2vc^?y=;(xD3HnwOpmcpvv)PjzL_Vx8UoHr6@@612t!Te7*96y34 zsnWeJTaQ4jFxHJ{$W#ffuv*Tz-bH1_==aMBk5PZxgb^GjayaXyRe^+v@ZyCuTSDjehb7 zZl_H>`WJDw*pUcVA7?WJc;q%r!MukELvRN}i~T6OvD3pOWWah@3s0F^4r71ES|Cvq zv**l7%iLiFD8X$y2QS2#@q7UXD6#8H7?vz$voW3F$XZPYV<`*4fnV}wWMe5$D#8%j z?w+tx#mSRj26vuI2XiEoovXA*D80B-mXZI6NlMmIv)bEwz&BY*)vw*Ac&G;hi$5dA;NK~7@{KjmJxCO4m@XUQM=uv0#o*jQfgw~IF?chnj z6U)bli9~vE`RDC)gi4gWRVlTEA-1!{C#)gjQvnfIw4p=IR~yWI(d;v3LdbUs=Dcb{)I)8KpD?)n1 zp}aMTE`FpK{5gByQdZ|R`{oY6$J^srL-LLmO|glJ+qd@r9eX%U(eTLR-4B=WR-K3y z*+^e6sx~Nko(Z2_;f%mLpUTuH6VXti`ACqVe|>JRpMjwaZ@)Lgx4$&;bu77|3s%2C* zvl$%Kg3Pv#ZbmF6DqDQQ7Y4D}HsBxR-V%(V5~DKbuol|!fPLb7`q_=b1+4O^=g$Pt zy8G#;vn?3C<$QTsc}HMhxav-v@Z@eEmHrUJXPSW>b3aDj=PNQS8)y}aiI@FGr|$<- zg3R@(NxoR4Zqhu1tjTcn6N9>D&=VuaJ)zXVjRLNrRC-Lsr!0Ek!6+!Mo$n(mlUZU* zYTs%XvVgY<(cLELy4M<$?-_g3RZqN8_l8IAprJ?hU>}uOG;Fgii1sN{pnbV}$FE+X zT_9TMu{0gt#xkHUTIE&7#B|JNe+RY)F26U&>bo}B8xs4zMvOJwFK;cLv1Tujg>1*5 z&3IsbO^ZGxp|LMTd`8~Cv27kiu7_zo?-sPXgdrSfJkkQ};x0&A6#ur$9bmiMEbs>; z8aE{FBey-NHuQJc-EzV)z+)hIBm3aI;XfqGKuP=;fl<j7@EV2no^= zKnxlRstn@0U&u+Xqc*l9xE7kMDiQd6rR94wMeg}jN&4;hAhHMx&N<8MPax$*i)(}& z<;V|O@t41b8F)7T{3d8#7XpmC)z{Iof`f49T1Y%t%Qb9O<%}fnbTzyrP244%2Wc8| za8}BkL@}uYvz|QDrCxxeH^ej7Rt^+xr3YX0xpyTyf4Xh8_F^emQWlER_-yg#RU9iL z%XoVjwtqvYIe#O3kw!VJ7W^%^h}N*bQH&@R5|PNyx#Wq6Lab(%eH6~rk+Bx} z)U_RV57)G>a-Q%?1p*gUrKcJi8wuyz?1i~I9FQaG#b%ArNAki=+2NI=SjJ>aU=7qp zmX?-IPv^~_Z*~Ww{WljDu}nyBr*WOL+pa18-D7RxGu@$72#)?hPWLIbdD)o_?k8J7 zs)3FkTOKjmu?RK$e?)AF;b3e5k@0A?G9RV;R>Smchk#AG?X&uO`>nQLU-5Rx`k@%Q z)u9zzl6=s23_xKA%YnXa8>Rsj-!}rUVZvg=~- zUbLQ_VBsEAT}xU}^(0Wo6D|izV#M&o_%j5kmqFD1zpV zjXpyd_K$89?)4{m?8|2p;3CO2+sX4w4kw;evHY{zpEHU4>8q)EV|2sPfYUP%@;UFf zXTG`}I6dryqO!GO*%VdrijF_em&Q-Oj>P{UdPpok1~TXUg8mDV4M>%dG4#9jjbEsW z!dG-UY(+MW#fwRmDEW@5+$tdo$;!*K<1OHh{_8bd|3E}1o|h_kF%;U!Hd%$unbq-vz0(Ds^3N{KrkB-a)QRr* zX=8n|J3@A$cxg+JaSbW0M9h4rvTKqZYEo@WoW`G(xI8h;Osj%6lB3_@aNIej4l*v+ z>B>Q5gSo6+Xf)@R`I&)FnMmZ9?WV{AkUXcgSjXMI+!K?nTDF4W!D9Z4thvFcxygt!{O@Eo9lP#(zwzj_qFt%i8%kFMkO zf~4X`OE}J1^6>_46YM+}9di36{_q#21I^!uy~^1AyhpXglEV%eLKWeu+tzb}5YTLp zRY!4YyaFfiOi=TfLXr0(pG%gO9DF{0dm#k8cq=v77HCOL`LEj59jr>8NKRCBU}nOD z=LV){nb2$VwmMa#)}2jr5%Sf^Pm80Ij*~c2g~;U4!mtm#PX3L-uC}6Cr+inHCB#{R{H?DGjlyd?OSzd}K&P`mlsRmzqnKZx$ik06(*4AKJR%oCD0$?SQ9s07G?uXU0$ z)tbG;M)hYN{EaTg4Ecfc=_OFlcrfn;GzDa%S!+JcYth0lpPG~xG+$~0L z{rL^+I>I7RX_I^1|2Ojka&gcAoX`vJvF-;dxawcpCI=r)mJcyKURBG9U~cQeZ3Gzg zB%&on<5{x-VjP35vx~m$nx*_;bi&!zttYMQw9bp)-)!V&$e>xxU3S%71GX=ysmw8E zC6*?|&K+K#R!YJ2Iga6EtpXI_i6zazT^7HTg@$X73K7B&-*z`KW zKbp+GfgkxL13F?lMyC5Ks0Kd5QImE$i~OBP?N>5+T{eEHflcV=*I7@t4__Q`6)(c@ z>4%PX4$6NiNCN;T%>(!06S=b zE2<=^tkf}q_p;2YBlUR&?Wz51^4q-neEjS6jzr=KIlUa-(cX?Pu^(~fAGktPPTQKc z>*p~EVxsb5vx^+0x^y%|We}x!zL+3eE#ZN`w*5GR#qE(BYkA%!ldWcxLd%_uA{IG! z_u;Upmct8`>IIrioWM=tdrw+Uefc1kiLNk2^y=N|z$NEj)8qo)Ki*)Sf5t>PG#>b! zuI=3S8}urdd>7i|HP69R+K0B;CM@g+w#Zwrc+5cGZ~=dUAG)6^*!)ZZ+qz*pdA_ku zLsGfrSo5V2zb@l*=;{a#Mpbb1lHDJ;O3yK7w^8vL}?-A85Aha#3#Ah;CD zrPXjhk|TES`)$XtVdlQ!w%5y2ybE(-Kg6{%y<5!xxO9=vPDx0f1Bx|mcv;XkBU8N* zyl4moqZVn-le@vaBanID1#ZwP-$~5)VzPevlwj#1}vxRWpQU zFpS71(PBel2bXGupz04V@W)SB*s!F{4TVQyDAesiDB!(nVkynHx&6xpYsqa&hYwWv zC9hH25UF7FB}cLN?BSZyE*S&?0^6`o0h76Tq#vjOeimCz13OOvv@qA|8hs4D0FO?r zZ|<5Ks#k9xK&jYlzF)4a;Y8t3;9207uL6b?mhON0@gu}~y{=mgcfxf3jdD-ND;yd{ z@PPpStt7z^96^B|g>whmM_Wl5-co@uP0qY|fq0rsDG4Sk<`<02+i&62FRm-jKn6?) z6A6xWo2~8Q@greNBo}RPvfSgb&s^~Q<`kn*XHL$Gu~F0K*wYji)+H(yBN|!$QhR6V zl$J-9oWkggA6fj#3ct{+EcYq0>kBJ&z3&@6A&c9{0_LHIw;aR~G;fwUulWS%JEAyr zD(nrC^EwFRJO9!N+Z(F%+lwXR-@;h;F7J&bf8U_b98s_by+yfyQPso%iN2it6S4i` zc9;YvsliW6L25JD`2lR~2Yi!YG)z3n%$d3;z1b2+j&t|SUgVLOW}X}oE`SeNk#v00 zO28f8>8DOm=B2Xpei-#hEP>)mZV4PedN%6G;1nRAPuWKDsEqDwBWdAa-%E}2me?c- z-g(`V$NkQyF}4x?)Vdlxt$SI}H6z9K3ed#pk$Yg3m+ci%34u$wg~k6Qd#GmXQMesC z3n6VgbdGCj;5v;B1-AC>bM0RDGRv73srR2KFk=}g#EBxEbuCa1MdpXE6!x8+$~yfC-+VP!eAO#tjr1I!F?0m5=8w*KKfiZ5@@0HD?di8K9eef?f14-*`}#$n z+5pxfD7}H+eO=zYa=AQj+-jG&$wkcY%mlaP&OJXDH1gStrj2P@q}%SDWifhhPI%7r zuaJ@-?m_A=@JW2F)1SCu$mbxqO9Y)A=5;hMLc`Q@a}aE)NDlpgWbbzcH3iLiW5S)D z{3^4&Q2BHR5qP%QIV2`N*Wt3r?iZN&H;86ExNLWN47rx;aPM(BX}nGSz3UYXmcP;J1EmIr?rN)f2gnR z=Rww1bzg4RD#vt;0a}GuxO~HGP4=AW1 zN_y#Xy_r%1XCnVgqF?-k5BnW7_QK8K2|QY4c3>Tiu^8w&wMzOrbtja*mp6cuOo$v# zNP-Xg`m`~@Z85=pDgVhH3f`8K6{z*484_5JCZ1;KzZqc@Bbvu0m>&x94H*M7cmpBd zqx4VWmLKf&vc-1$&g2Nifzm6>Css=kfwr7&I}fZW-_KN(e;zA;J}#ZMcz&YP(>E2J zH~|t)`kco_(=1y#fw{7s@lgqphjT%Zs|E6_;3J#iI$vCWJ(?oift4ny+Id^Fdn$^U z-IVwjj?Dg-1Rvz%V`s;4 zh$Uo8ajPeKD~$Lim_W~p!(j@R$F^TMQm1)LsWp z=WG16)K)bdX!rX!SvNh3ZOg}2@L8M5sR{J=q4Y@!nb82MOT)0;D2l9DPG-F#qlY^S}+rFen-AB$3Q(qzER2Hy>O8 z(H#C@5$Yz*SM?~b;}~OAUQQqOJSqw~7)#jl5@i~dxqHuBHE?}V?$v9Y($ zyu+w7NWPO|a0Un3?4IdS5wmZEIr@Tdk0!^@MwRba%`t3n^R`30@W@^WzbREiJ)Vw` z<(z&0N))JCJ<+WD{~t+L9o6*zeus2POG&GMASKcvjnbls(%n6pF}l-2Iu-m#O6TYh z>5kE`QKK0!2ERAo-#I({!`UA@ue$d>_qop?Z_5Etv$O88or$;5j6y@-6wcK=ALm97 zTUupfPRy%QT%lP^@%voDi?N8pwAhTWLxFVGK8@wmalLTs@0PPHd9CA~mI3swi2?-K zIG+^mWjpW{CF5bYCBR6^CCn09?q(~~&9$L|TX0|I-4rc`G~xd-YMoGT)QbT0tCb-^ zT>4x>DTJ@gqBB)57XNw%B!j!cf}T0z&Q)Py$R8+f zno8?KJnI6;c{2kH+80N88u+vIz0?)dw?aXdA!EO^ z;g5vOgU_6e9rIh~6)UFtD&>`>)bsS|JBfV=u0?r%xbK$Lw;e|c26d=S_|S*NZeZU> zvFtqm9{@FmeJ5k63#kKH?OR&Jffij z(0TEuTpEDCoj);x@DvWZc(Zh#g|nGotSCcN9O&9#p$DrHaVkGEx z!sklWVWuCqAo}{FpTNYrRcsvfbbOfUe?&Tb;7xl`NR{G}L~cT^>rAF#NphVN>C$)p zq}h${)+hI7WH|J)qe6}>%tiFQ!kS363z)Qx>pL40uT0e9n#d^%clveNYF`;=dNC`N z*0^@n=k%xicz-k0OQ5~@!t~;NXn+N>wDb$X*+^Q*_XJDXE3whIphdWXey z-jHF41Ilu;Q`?qQDy9IjUs*&m<-Wdkuz{42cNQ2V5pY_vR1dwS+1=g6wkxIAL)xli z)B(Wg4iVZs3qA!>?q(G}wLuusCs0t!5x)7^8Q-yAfl0#Yh%|>R?NX#8gD4_)sbWk- z%e+qTuFNqbl&O935OZvHFS0evB3yS$dBGP)=D_yX0g02_Jv$ibBNI$~BYQ;u8#Jeq zRbGPXx6}M+NKxy9aez4wKmCJx3Wnik-v>&n@6d}j5STu7J@H?3(LU)}*d(KDd^4-`M+&l( zC%hRupz%;9;`KU5nT5q=8_gDTQA%zW0)d41+*FiZ&Vs~t?~o>X)hI|kEfp$i1s?*^ z*gsiF@fKD1j=7Rjr*S(AhgdPMYL(hI!;IsZMX>D!@ukmVC zp5@zH`Ee&p5KGoa{>J+}XSWCJaMLTDb`2<5DGdLS?2_kAEl;n#wADL1Msw=#MaiWzisPm#^B-0JR3%sh;?L#buCEm@Ebxf)!H3>Nv-WAR zk)jNq(&?@XeOK3h^u60mVq z`DR?5VAB3Se85mSnhvrIBe^Xw>#d=3H1@%e1PR1hq`RMzt78m5k>W<3(CcKqJ*~WW zyaxy5P@or2rwyBC^K}y_vhvCTmvP_zQF6k~o;&G@TVMaaeLh(|n4scAjp|vTu`m}M zf20DNQVaZ%IPFPVw)tQl)l)cN9wYh+UTZG%9Kuw<)7gq%3OvresfL~(kg|?8JR@q3 zvUdX-;5v1j#nz3-=)aJ3-nXp5k{*(d;JO77OPsw}S*$)!m)sax*HjNO}nY zCIJiL90buIjT=gZ7b0Y%=#T#JhYve9(0?XRA(v8b-UXm*|NP)6-21x){Sz(VAL8p% z@emT=>nM?(E(6UN1ZT;?Q&UdXw6YWwmWe9i4=2XZ9&!AKZoSq+cvj8Aaz_F-uf*3# znhd$5%)#D}Ey>D8*VcYGy{cv)%T)hF@TWA1zidI~cbBzrLM*Nh%t)yV)Z0e+;vgk3 zHH&oX^I9W%&W_NAjPpfODl1n{DlX}rB6l0k{5_LRN8D2u+(Nw^Y2n_7d(v>Z%Hi5z zMDQe=xq8d&=xe$q^O+eV%$_=cbY=*#H% z3Ve-Z$)q5U!tu68ht+e%cn zeiRE~tUaNQz9I)wB_e)*8znYY9vjdZY#GKV1}hxmlCzcg{Wrcv8zP?7(6)|!=75W6 zvr}p#6Z0!$Pe`Xdq5cjA0g6@YgFj1BpQc5|&!3J5GfR>8=%72BGV@Uop+d&J_5Fsy z-$Xmje>a@H<8nLc%Go00^+@I~=rfxbcm7K{;d9B_oje*J2nXV+;xDdq1=n7lLpLnvX`pL3}*uk;-3o z20XslD2UkYe+Ke3I@jP8yF$Lie(RXGQR>AKe`;b>r+c2&KU+T>yRp{~Cglp6@m6(t z(y`aZ;rRUgPx-GDl$pfe2yjM?2Z!;Z{}KD^`hN>^&a`AA~1nO(E%YO`4}8| z_Z9;baw&j5+=p#|UFDm#LEgyT#ELz%IM1|VojZ7q+teSC?Q810Oaf(Jr*K$WdeJG{ zQli*k+Yjr$Q?C_m#zX1Gmaj<;TbJ=nuepFyfSAD*9pxDBh$II#+Eq2+qi}cp3{T6@ z!N|{7tZo|L=@lAY&+aH0jCr1RBj`cFdXy2ADxCg$COqCaS%ilqAs*KuES(H5xzFF9 ze0{HCM|*sf&jS9LuTTCR4-i*BpQhC8@10t&bB>>j03|5!c=%X4>E#-pw>+~+qsA|q zVXUS%)nvuPOuHOJv2ZX!Af6Q`{mqZ4f32n953`$D*#Y`7fkVe1m&<+5Td z-8qNiANIKq^seLj9jE&Tq36~wrmd>|u6Pr@>}>031yr40s*xM9_ho#1D}xSeJXUZ? zDAVta@~Yx&g3j4TWxUdRFXniCy|@5GOW?hhOig!jn6$yQFn$>co@otNY@(QWbJaO^ zEU_)+Du&O<}u)z(y?2ZR0@O9~(zASSb~i z=in^`kog@gFEk*FVdOO<^X>ux?|*i@>jWWjE~4U7ZqRiR4rL{Xeq7+=;^aNI`N(9slthiSdTefdp|4y*63w_Q}mJr})n8>^oUI zMpTE!$v%9;2_TY1a_rWpfd7YF%gvOhKZK%c^FMR=>lI`|+8lm1(NVX~3WQxPne+d* zaJe+!r!S7e|AA8ZDVGxvM(}2;os#^~f1x-T3x#fnPw^z z!QEEmesulsZF1#2kFp-w=2bl1FgfSCU3zlQ$*jbf@dqkd5hjxK_~;x?vF-ly^vPDA z7b>NMCFms}-H%5(wUs|PnD+Rhd?y0DgG)bN^+7$FetaMSywT!5$sj$k7{Ak|Z3i3^ zW^rcOL9#!ZT#S#9wJuqw=dVe#rvM6Paw-jZgyjJC`*`&u+{H`zXZ1?~yNAfJ!d&Rd z#z11b(swpA5;tSSH_<$qMCz_}T{hl$CX$7n`CjWgzPwyWZ?7U0^8u{6pq>IL|?UI8O88YwD9M7TQuo z_sf(hq=dF9RlSa~Vvz3nX24%E5NCwVcq(pNhiQs;B&t|@mJ1&0L?2K zEoV~KRf{8dBPy)iMZ8CzWwd=q3NLMfbuu@KG ztbdtIlWwo;A|{U7aVdfjgJw6!=ACTe9bQv0|FzzE$GAfM1?0I|ONa-)aW$Olw#;lb-TtNE9T$AmAsb{qd(aiA*BhR;es6 z=&5^$%zala##8%U?f#e*( zk_kaYf{P?P&DoMzjk{BE;{l%lD^SGH6UUttehDXY-)ooAUUYx(+)H+Ow|5~&D3(F) zI4#y{RA&}OCc4rPEZ0FOlG_9t@uhb%+0RAt%cNDnl;GV$R5ND zV)atIG7^|1ouT=Qccxo_w!2|X{Km^6-#UVO2MAsH%h=i>OI|FO;wPL;P z5BPq2Gis#XC#%NoR%ZVnfLh9(6&egGpPQC}zS}S+yh^#>EY!vN33zA{HPoj^78rK2 zUjW7sO{p5eN7a#I>B4oWZN9Ieo80q@5vD-crP9S zwi+(N2kxisGD!!&SCK8MkPD{!|6pNC@fGF|D)J?bdygQ(N&9YV7j06Gel+#V+lZ{s zZAzLhdkL;P;;LK|OyN0nl{13nR%e}0=lNX7ns9x!{S|`viC1u#{#~ zNT0;y($#b!v3(O+h}CA>pAr)jsI3h4z}>&Q^jJ=%eGCGmG}Wrcswd0cKB5{CIjBZb z`WxPw^L18;MB#d#eEwxuCi@;gX998Oi=l2_R;lI2Up`(r{oFnv zIGYwNhn8;FxTW%2*SJ%LM+LG^dU^K)9h4m#mI*G1^9E z6P`APd5&85R){-T!&jIkzDQ9Wj3bBSckk{^v<^YmY;rBX`L*h3f!OX<=I$-j88*Rx ze&jkN2dY-|$vW~j(9k7?9PjXtW1zQEqj>7CVA8!;SLebZ1A7|!541tmgrOxL-{P;5 zScwWPf`*}NhS2yK6m{>g)Vp5o%UDjnKYbo7s!k<5sl z^Cxt7_qx~q(W|%}`EsY(@BHZf(fJ8?RRb(`D~QJ987tOM zIr4O9tufRi%>SDtNA|xr;;6{Nd6>KCV2TZagQc0o{D<9w*2TJ26N7nVskab7b5Enx zqqljst_&=TaN9dO@3BHo#{^~05zw12jMzUyVc+O@lcmF04({Xnu{kt9`*JS{+Meik z4X^WTI*{lRtGtdQ=kR?j2^JTE-YaN;v6M`m0=sDxU!Sr$+=jD!*Pu9m^{DxDJ%4?CzE2+_dnJ8bz zIvm-SH4EcodmKNS_U9;@LIlofw(f8w_-V<+0GY8eA~t9tvxY23W@$?j#31<$&jP)Q zU}S6RAAO){d~rW^LpUTuLpY>K;E&tFT6c8F!VRbUN>aNx`yLNG zzP$$#`u;YP#oadrio5bVw4(>n2EA%~4Xs?oPN4PNM(+7hgxnIhXZ>FAK;8UqCr`fT zrRJCD{-QuXa2>t%K7@4SXdeE<;5QCQj3brf83E-BD)B9xup4MxW&9b>qp4cMRc?lbU9L0|O=rr^U?va%^Ip)(a@ z!?_TjG$VYV@_DXAK2z!E&QiZP-rj*roH4`!A}{0uUp_cq0VO-p@S@2# z*(*IC_<)@6c`iOb?8nyXK1qyJ1t#V-r*EG>F5o4A<4EnYl;#-qT}8gA`DQfRP!oz$ zr5IrMs2Z}Kk;|yA($@PQy`(K(}A4bbNOV`Wm(J|s;FNzoaw)zz0QEe&U;bpcgF-$LwxxxbWl)>oJ+U;r2<{2U#*T_nnMYG(D zf3e8!`EL!(R)4%|AI-z`^4`j0bio*4kjqYvN63t5n3|(Gn}DdG z>ECfXr>g#)+{KaXdvez@q~vDS4GUiyQgXNr0)*kk4tQtypxgRv+KFASmsV6UnVB$< zh20o$%IRKvQx{C^_8ZN_w)whn5p=w52OmE}pDO!i#fza`$+d2Y`U5&?Y>`5A%f|M~ zw4>o7IQ(0yL(AgiPFrvZUJL=HEGGnv-~zcq9I)FQ5i7J4kno+$Lvp7fHCfx zR30bbd{5tb`iDa7ur9a5R7JPX&u_(MXI|M=WlXX2z7oEVM68Jdmk6V!bxb0}WP9xL z#r1_9fv#h9ztfC)o;OQ)Fgd*d$ZoiZ;e6jLh(*?*YpjsuxmI`pB!;JMSBSvSEVs|M zjgBks0m#}=swshxO(@3c++naH&{CY(U$JS7;GpGL;O4M;xvL6xs!=k8DvVDY{SX$v ze66(TJD7Qa)Pd5Tslp=z=YUsH@RJt@eACCLN#j@OG~@WAuDl5~JKzhX%!ZQ9VTl^d z_7yc_KoNeKkzL~rcaximI$;O}1gVr(^9FVdFV1a48V9#z`dl}&wJ%%$UViXgbJmG0VMI3&VTOpF|&&_CJ{67DQ*3qcR_cvF|)pcO6~wC_;7o1n8C>8~Mc0)X_aG;Id=IK|f%Tf)i#2lXRzZH0WW04q#^tWsp`4wZTqG^VAh{jp`d#=^c zcBut|<~(m_FRqB{##@qy$Pum(g}{)({SKeJNjvHC4JtU|xJuOL{H78iF}7Q}nP!Ss z%T%Hii!r_99+T%R3NFFKdR7mfmN(CBuQTpEJ)Vd%$3Nq#^TAhuY((=Ne924d#E)cA z?P!1bfrI6In@2Tjww3=B8H&H?g#mbS-7vCbj+DRkpA@VLx^2D~uU)8%j8FRNb|u1w#EO7_LdDA2%uax_l9ROO=SeH4}nP zKtLf4ko$dhqK;=k+{+uXtt5q>7uHy@;p@4I6+7sW!o$YPepSoPT@Kg! z!<1G7*#qol=j_a&CD5Tv2>l{v@}uOvfb^7Ml~WmEIG$$? zB~PHe?279-5Ikto;7RpVCll$+^YJ`PTFdm`MsNlbNUp`GIy_Q#(0B1=nmFZ=@~RD8 z|8w-8R4nMc5tc$3!523@->dsxK%j0srhp0jt z#h&zVKYvMG%q)A=RCI^5Xo++iba;hc>PF}MULPgAp?*tSSa&3FgCIO#hhCQ}@~ z%qGsp&cHBnf@#6>!rDbex58)(c?A*mlqar@E=1dB0W54chtaUp&XW=OrQNgZfdd$$ z+}0S)Q)@MpVAYb&U8*(kDd&y?eZy(Fx8hLzBFpP&tkG{c(#v#7izA!n_^w`;hEx7A z;;-D1r(S_&gP^`V-Kc+H4ikvgyWr?y_z8FG7Uqi5;CWKG?c6kJB#0)H3X_o(+aQ& zwmx+>+rsoyqs@aGI4tlO21R+@7SvWLgwLN;35cRDKMyVk`Y-Eo{~R2+n@mj9c@_bK zHW97xf^vO5#-%0KBjcvw#uww&SqJkFn5-+ zQY53OW%h5d`nT2FSuQ+Bv)55S@Uo+X=%b3zQ`KT|Wjp&(ZRT0~k%HXCkP`&G`_bS_RnL!iOEyW}!Bv4m{y>NtM2AO6+6WUg_y@03qN!06yD*sB5#Hmfm!x z9sh=e?e?NiP!5AVxLx0jrqEL{9|odAVV{Rb71o5+{i}={oE=MV}ffnAnNoseS8UV7^Zvr2ABr zcE$zhB;@oMRj_`$yb0;2H+txO`bHr;SFt9ijyZj)i{;YU)NodK?}!c3rP{%R&;BP& ziqqau&xFf|SFv7Rxi~lPxvqWj3-A>%L^gDD(?2V?J{AzySF(M#M#aTfI{(Z5>T2Et zPOcSwfY@?hPjpePS~~rt7c!*E%}{7Tc6c6tVEF?|R;}iS3;HJjOG=ja6kM~vmNE3nm9CEsC}(d&iX@~KK)Wh#dX@um;z(mJp@qZmY5sOL+Jy!0SN+ zZw&&|a>3*F-m2>aC^2(E8Y8DBejCDSlFs6p0lvDQaGIa|IcI)$XMt$n6FHi{Du2^= zd%*|05xm_*{Nd+g-ql>`K9<`-Z-xej1nDm6+-0~Db-sx67&&!9!JTw){Km0U(&W1$ zi6PqhIWfaDFkjNgFxcdMs$*uL7z+?V3Zq4}uPM5Je-|n?2%a>hqztG1xNHR$$JO@A z%GDr1T^TKT5BCjKjXY*?A-I({gzH%3jYaV+3<`xUAGl%r7;%+7M4zgr((SEDL`|o= z)fJ*pxBpCYo{dlX)& z7$8z3$UOAPxh2<#X#XC_%gd`vjSZOcA%~e8xw+4XZts;oSZ5Xv{T%-=GL;4QBISS0 zKw<30g$%`ygJ{}was60dGQXsz9Pv-*X5mSD{GZmL$P7Q=8&o>SyE_M{F1AXUQ;tD| z|F04`owo={^wCv+&j~HZ$(8L8mU#LzswXeVea+wA{BQXArfxZ0a9Yjy`X=gxw9{Y| zBrr5QEZ1CF>26fNaE5huteLJ$V_Gm;pN;xl8P-IgNl?=7ZT;fG#JdgfHc=jjiSzF& zS?Y?R+55433JNUi1URX(X7nRvM4w@t7LL7r)A2iU8Er#lF|G-Tzg!0$A0-;4!s8HJ zq3{uPG)r$oEl=XCbxArc#+GZ*r|-v@sb9xpE zj?cdeZi-pm@z=%NlMTZRO^yn&+y3F7>pKVvMcyj7E{a*v>z{+R zKZgmCE76xDBZFbLe~aa@+vh(t(p>k>0*u;zGFtVv(z-?kWN^G8`5=Xt5GBl;FdPDi zaVjr2I@@?C0hpUjSBiANPKT$KzV7NCeQt9Mp1tDt)`U7nzUOpi^bEq`E}d9+knStW zD>qL_u0{m`T5Ms`TGM}FKoV^f1Mk*95!XgOM&iwmIi#`XOmB~7ecI(E*2`~wfID?~ zVQ!lvs!YQWay@fc2*rkfmlu)`s4AJBFRxHn*P$j0j3wXq^uXOk%v1%B{Ty~A3`c=p zxy4w2S1g|Y`LEoU@87?FD}vXNutVee<=a|u?VLS4);4>_?k#Sm5>1LH&%_stB2~@r zW=#MEqt+0Q5o5$1OqB%5yPu1M1iySJs3E0$F84I+WaD7&0`gEN81_rci$c)Na**O{ z82j5N2MV!r)|Xjz%Wx6fwGZYFlypH=ibV!9yC>3JhA$Txq%*D+-p0@m5+uTVD)%j`1^~guJ5JY(kvrjtWXz;#anAnW-h1t`ZICUg=ySQ+}d+2&%U+hykjk~W{eSRsASJshy= z%-$;o1r0<$73oC+gN0jN&NZ;Gqur&qCZhg%w97U->Cma0|Qlg`MHQIj)|Bys5lu_Dr+q zE3ng6*YU9C=!8)C;asHTsbF^RuNi|%_Y*9*ukw7H zCT3VRO6O)zjjE5ThLLpJK&Jj))0nGj)AVS%LdGL5j@H_i&_oRv0ROxU{1F-4oUC9M z0{+gaA=0er7#&*%xZDbelI5=KF*oSegImmnRdQ=jZ^LMKx*%6dAnnm*IE`cV7OSXy z<@PAaj0iJo>9ykZ-9sEmw;yqe$aX!X6X!T6n4pYPKGDs-KPxJzkstUXCq@5!V~#`h z?0*k{{%PLEE>izwg9hAC&aaoB{bVVr?u;0v=-W(+7EwA^X%J%s`SnHmO42cOBUfmd z8jcBm{&x|K@LInzU+X?)q?(N6HT0DyYWs(A`aKnJlq8Lk03WUO6n^-2wE2{Vc5;GD z)#*Eb1s&$xw7bn|W93qcV+#i!x~R$n`butgpStqoQ4BPgNBJFc){&rUv?kY_~O`1|CG%ObNH z?$)AT{;F1w?>^}OY*DlH^+4+<_2iCHv!T6MQ*#`k6LOc4uh{-#E*$&rQXq`ma&_wT zz4;QN>p?!ajJbzu+N55>tV-u6W_zH_WTb*$*^3?9{8ANBA9X^HnpQm@dp}ZkCujgt z6L`7_=}VwaK>SG|3@mZkIacP`MJ`^$7J$qjx#>8#z47fo3+0wCKN23v&gRNg+T}Fe z-ue1_Lcpgf=J$-4ET|YK3v8(jkJS5O1z0!PjT0Hr58Fsq9)^e;KRl(+Ha+~58M{Oh zgM7=6*c1V1T)y(b!bK~S&gsd82s(Q2_5a9RG^b66yrF;Q)$tA`CCtG{>bdOO5lFrd zViDhcY)BXF65$lxO}xEKaF`2^S5(AhW~%{K=~G8cTE`XV5U-NBRq%uMU~Z|=V16Rj zeZ2U3P*5N7PD?Hm$kxiL(Cqh=>2<%F+;OOWvG$O&w-2BB3`38Bp#E!)Bv9G&ZauQX z7v>`4ANDoDbW^3HEIsAgIB^laj6JIFebQr5+P2m2zyFZ?kY((uX&U%?^n<3K%8a-^ zY5VHATvj~&IGrdbFt41r4#aZr2*u7t7Z~YXN(TjfO|Y7@O>r9AJuzKd@E@r(+-X&Ho3b z9(?3;0nbPweXkhKfz%d#=J}rJtT{(}dJxd!CHr|D&O9l-z2PTtL%Y6#kZ^G`&Vj^e)W zKY*z4K1zB2VY<+`A%c!x8nQH`OJB~iL~zIuGSX=F?b5uDhNUtnDXfKTewio8{RArK z^N)Bpe=fN5OltwYB8xH&S}%?`VHUt`uUXi?(GrKB_NH>FE%^dz3oa%z00QP_Zf|E# z`a*tSN%lvys%|(-5ErEU8t{G_4M_?nT`}+#ERY{b0iJ{RhXV$6>Oq;^C|wL?Bi#ZQ zH2l4we*F4Gr9V8_%ZkG!xf>iwR#mlX!Z~{=fXN^sq{!}dIT*-$yY;O?ju}oeQ^!hx zQYp~Z^p$_a(rCffhB3P#8yta<=U!eCx*zr`@jq#*&SuE@!T1Ld>E)Fxrj(o-BWq8b z3}FpP)1J)xn-7}yS)w){J^a2-g>8KoRH_B98dYvD-Q?qmwj5)-@n3|Xzmn5q4`9uiso0Z zlAEh`AB!i|-a8s?Okw?ReO}QteTQ7;C{Q%GqW56%0-I6qpiO+q)A+x)Xfsk?SC4I| zF?j})RV)MLiJX7Kw%AjKFwHov8?-b2MA+6kkb$8oyWJreWRp4)7Hx zUcmXcAfxm<26qlK5c%iFLJkD@iTsT1MM}))J+0kT1iG~uvUD-J_W^+&-@;7wy^GWA z?Et^`8*v9IE*^88t1vAwyP|p6QwqB(V0hCN zS9&N3et=%e<@oOhm&amx@;}vOKu_T;vTHL{V$L)Qg%9b@5IiTXE=j*{y90#$^erK# zZIoIr#O8Z6X3|wNih!#Rpyibw4!BPA)0F|XbY&XPYTkcDmZOF27e)oPg%rfV)pHZh z*N>e;3)PZcfgEVr+ns^poB)#E!=uDxm(u_R?4;U}4T_>e+JCLH%mge?4yt!4y^YBORdUVGVpu1DcEl(~5cJm3Bw zbF;n7DSry$^7s?1m;@ewgb{L`z=#Cs^wQju{83Uaa)&N}6;;+V<0+1vj@(glIiWUr zpUQ?R@Ee04x=Bz$a^ufQ+iJz!6P!mksk4Qczj>>HV<3N9mCOv4D8L&v^-%|#|C zTNaHNJCO2d-M01a!QZ7UH;K|#hc00+SDnhU@Lby|k$nUp(}3+CUiEOF1t&rZ)|OiU zkS|bIBnTI#2&*Kntu6HJ!z4ZCnJejoS$}kW@aR$ z!SYTKCM5PQVKDPQF}?XbrcLIiULunR&x|YHk6NorQEro^j>RlGgKs;>?pl!7W*KD; z&Et56_x^dd53BmxDX%(%ap`}?wD`Scwl@;Kzq)3dEtqZCIfPz{;7Q_ME5uxErB4f` z2aeeT7MiB))TNIO`QE=Ghd8WZcSWs#cGxao&pA76Ic*g7(|aw zVDyMw@0+c88||!yjbIR}IWQd}kT&r2?l$!~MDr+d$J86wgp#@fxhGnR0X>Ny1REQW zi0q~3{ZxZWHl}L&NV)iB=vbg&4zks-e=9aPI0JF{m&ch;@jJV*sUn5SWbte`gH8>L z+h@ec?}|@e({RDB8Un+1aFdspJ`sG$Y|hl;DfbuiE+2z*HpqhWI}#~u-w{-GhT4%_ z1YC;=G=<*a`G>w&WqtXB%`}j~HvyZ=VCpFz4Al;%EP%ZDG7-Ex z#o5M*H<{LZzHE)UZ@D95;|gq!OD1`89hnLw>8HT~S4jQBUuW2Y^SY=KTWF7Z4eu)vsbrfMMf4vKdg0 zuOAEzk&6MlWw4v;ctN>D{=#)5WJbqlnCZr2o&K#x=|b_%tP@n96*PAfJ(NrP{&K*> zWHmW4x2k^C_7nmiQbnKD$lDa%`rZC%hArvb9P2l`@JMcjxevYUqmWZ|-)Nyfz9L{z zLK?2+BJ|NMlinj52NL8f(I~;6ZTrXX;g4$Hp$i3O@cq`#Y;1C`+l~TDbqjK%gH>Il zsj;ptS|^;D`ftS*wcjW-v_uRyrZ_6N<+Se8Bu290f6ASrMihN)-;%5--gQo4*zxvV zzZC}6H%H5_?y!4QFXp%xSZxKTw{5V_9}`GP&DvNW9^*31zI->SYPQnEr$*depULf+Bs!N6h^2F*RuG+ZlA4()$tyxUcQ*dR#qf4eE{+q&~ zQ&OSI<75^z;dScTI@hdzK9BRed_l^Wgjyk>rbXTa*YXV610*hIXF?{c=X!Wt+_O8H zS081nfD_V$4RqfN#Uzlk6=_B>0W2hrOT(*#`**{B`MZbBRc=;A7#nXxWwzLjsDJnD zs>dJ<-#z*t;7X*LNRMU30a31r{DXPV!}(tUv3$GZ1RsC9{LgbS2^8w$gYAIOf#^H# z_e81b!rSdDA*&xK8HfkEy^)69Vs5_&KBz!8 z^g>8c!H&I`uJ;b9(71mR+}=|><5mtDoSP@6-gQk-T;W6x)=-3AzX+4x!Ym5I#^47) zyL-J5D!_fogyPx{WI3}~4SpsRb>XDkJjM3cI3m< zfcTZ6*y;Dq%#;KkK9I*RCB9rWqEyylT=(l z_##)aAiy-eJbo*+nYe+uor=5i1cI*P-YDF-te{h*M-~7%J1Z;t_9EC}T-=>D7VD*d!0n|qSb?{-DbZ0n}rA?oL0 z7%75!C%Wbt&{z1aqS%{jxliuA3Y{efxjMMh15S#t-+oQ)d+8e|Q>jo++1Jt`F_~U37hlryzMKk)iQ5`JU-K*a9+Q+;B1b)_Mj|1I z;rv}cT;;-2>O41D`sEjWLtMT|DbuCYk#(e}#Ya$LKLZc_{EsMr2b`36>#Vj#>+ebL zJ)v)`?k3$j6l5j;r;6qQTWmAsV1ERf$N7c!l+yO%y!LSR^IQ|og#31Jr z8~qfk37jgHG;X;kM@Jf)nz}2o72KXQ3@G<|&9}Sh?XgV*X})2bmuQh|hDf5?)pZ5r zcf=e7t#t6pZo&rZtGVB@NJDj-m09E&avjpSFoAs+8c>NPpCVPHi@VY`WkE+@$)ev4 z{03N%pKNh|Uj+?oFkDFBG9}`s??u4=`wgZ8mo}D^{YzzHm$c5otUm!3PMVn3s3bNR zeLngbFV#Tne$R2vAZ8eW(XxlgEIY2D4PFAw-f0Exo?tpo0cF+ZRy z$sP|&%C%46d|8k?!uekOhfpj>@t%|!;gG``W_=J0#oF=wm2C+sYZn~84jUoF$w7j; zT%=Mqi8oG1D(t0~zLiJ2rajUAa9f0pLjQhh)8uTrTxioK4`yp+x%*v-)vUH9b};t~#h{e6myeZ)B$aEQQ1%G{;`yO3ctck<{_`jZjqpZL5~}3GGj=uF3Q2|W zA7KHL6Jo=JqJ@P?tz{(nRmr0?t`kS}h5x=goBj-KLkl*##>Wg31 z+-`1)Mh5xE?h@wHeq=j4!fyER&_U#LWTcayx~S5cJOVb0|J`Ou!DKDSM6%Y|uTeNp zmSXmY%w-yDC_f-_{=Bs8?;K_`I_90|EEMy*KVU)2!{uvj+5ppA zCU~~9hj|E((*Sli$%kfAvC;>OoaK*0sswlVsmIg=Sszyq?US9Y%^{;&{3b~cq)seb z=%#9?)d_f`;5Y#5llsl#%4%eOT*8KVsf592UL2{}U0# z>}n|Qx6v;jcyoz><#H9Bc#L4MXWf|Vqz#r=(D94zzQ=N|M@R8Xc1Iq=X_rlx=NEDp zSdz`fE!ruQ#KUz(H1s6adKWAFQ_Q7!)}wgeFK{^u)3Usd9;`^l__LSf759Tocm)3_eVHQ7{Quno;O6{AZc~BRD%hkgV7u7-vS&2ys~)jIZv)adR%VYRoTXoT})^X=u*>#4_&P- z=H#Dc#?O`j$0utgGgitTcqLEXx)A7D5u9B9zUTjfL zG3n}&Kk@98p+GCH7pFxAz_Eqcv8uZn%9h4XM1>zxa;}lRe_DifQa$ZkZ}yHB$RAUkgUwEw@?0(X<7 z@>j7;o@R9bMV)M9`}*Vh&#kci_5T~_m)Scq^NI!@Y)S%Q1#r=(Q|PEl#?=LT$6%2A zD()v8<3}rDlJwMmz}1o&w9Iquhv~+|=+x*O1wZ(Y^sCY?Vxf58z)lafYGZMo9gzgh z8EM!Il65JL9m3GN>0rT-8uHnrqP`S1yCv=xmejLfup{xCUU;!~_En=@j{jEOqazN% z`up^g>mSK=g$w*1)HbT*iG|Pa6=ePhraX)6DtXpWDfpZ;W~ch4arM#6yPQ`-a(fz2B6*Mt(-R%#p4a}NVDci`F7Hdd~nMy*otToJx%1#;HEZGf(?Aezw3L)DN zvWz9`*v2*nGh_Kb-tX`H&-wk%nVjM@KJ)oJ&;8u@bzj$YtBBX~^@r9ogJkA->e~-r z(ty5a{rx5x?`Rs+#R!*hela?jVedd9mM`OV&f?5S4KE zak`^Gl7DhSNAB;NLxypyAF8CJLtW6g8rM7Ylf@)d^!U->!hJ$VYO_Wc z5tC{Vr=p!_BYAil>5zn}>pxOB)|A&nW%qBin8!RwOX#z&H>%RF61js&f7{rRrf~oh zT|FXH+e7)0DY>pK1@T}OB_t&5_|ouxI||!U#l<|-LJjrU9hIFe)WONP1-zHYKLm)& z3M;cHeq>xNlLfE|WE*rcs4D9Td(6A>HaA$`@V{LA~AK^tP~de$f@1m7ubPG1r9{%o96 zw`)M)4OjZ#xCEW2h!_YYxYA_%!>W7RTo5w0lrCcg`i-k%Caf%OlxEgT(CFUgpBtr$ zaJ~tZ2?IZk`EO^aY)K@rXaZoFOS39u2b>}0@OSK0ywSq*&}($5{SG$%;|{L{UXUuj zsM<`&D)ayk*axY{io!L7} z09AHf*vKw3D6feR7TH2UTJt7X6_X1++J7M|^Tf?>J&+S&^SIMj>7T!3(%Y(P(v+kM z0+Ffxylc#pl~z~E1r*;+t$l__Uc?|(tV*UTQR}%kL31xU!wq;|1{~iWqp+Xj@EOgt z;~E>W(W^Q_(^Hp7!syhVmq{_{zFDQzL#}Q4*4y_a;z>XlIv)d=e1Oyk6kO#%b5r!H z$C(P25zs#x9I5Tzj0*8_Qoc~V-Xf5`SCh`DA?&pm@3vn%GHpH2`s|@fLHEpi|9!P- zuj)}EaujRF!`J;)=)&s!hG?=|vN+xZcz3QefTPz~kxldKyvGc6G}|68OQlqL?~Ttv z_xC8%q=d;D}$`tu|daqwz0=i?!oGMe7Kn#sxG~XS(sd}szzSA8a`~Tg0yT$#py<7zGdLomGGu%UuA=7s}a!wXZ^pu*6uP!k$ZI8X0z>6HLiyZtU zpts7l|D|7163uN2Mum^LP)1}e3d3_1BI%>({<&>X4KY>F0zu~Teq{9Q)UZCNi*g@w zOBbmZsteNpxtxh<`tf*Kpkf{B?gcUcj7+PFo&QvAP64{=q>px^_>+_buV$|v``em{ z_C*=4VSFFO?te{A9B=*hg&((__UhZ~Tt1#&1;3hH?zY4*=!TQXZ+qD^R*=4MX?6ka z4DeR~-csIw>Kv~Sqvgh^a&O7Xh7~k`|XszD~W^tNcbf~ znjOzZC+R>Rk_cSs6cvqimGWh*ukfzlUxI;JNYL3r(zKDI;BOcI@?{jRAk2u!V^)zW zzxRsw1p#9lV}x;SEBg0!!wjn6j_}6p>}Z;JFf<2L=46e$a;Y!v`iGhBC2#hS;~S>k z+yR^v5D3o(luS#N8{>`AbQne`Vc1;k0Nj0U_XBEt4EHW zoZ^P?`9Qz7Kt<}2{SkAp=$x`%pXd5i*13#yGiW>49m-i?&RK(tS%WK2 zdiWm?35fBF_k6XL>rku{;`@lI>+J5{3RuiRFMf!lQsH|WeE65~?;qKiUUTvFbG%vG z(6Y1Ty{p?z4fXX)(y`-#_$N=euUC%pl`cTn_BH?&qkXaX+=g1rL;!5HWA{Pc4cqb3 z{%+@{JxQAJ!Z(Wjo#u9Y{lu%qoVD5>wAs$ayOIIu4~DQrF~K|_(FnEg*S3ThPQSaE za;hRnwdyM-ouX{@Y&T;%Omz1Bj?<%wDDjo;9#5F&*q~xwCAVxJ8jjuCeeIzhOQK~P z;o!ag>C$*7rYQV|G0&0nwZm53gsXN5>$6zQ<@ou zFp-&XI&A~|KjegCH~6{v{eUacuik6!tN$fC4sY|v^+nMg;cTFI?6Et`m2NW5x2RMO zZWYotEK`y$6EIth++fw(`9Wx){&}QSgf_?>aAq1UpeFIQWW7G_;dM?tFAG}5u|5jz zC&inB;|O5DzAYg5&Ooe(BKtK!E-w!Nu=~WQo!fTc*d)pWh6axgTvsCu}zo|HX0@UDg#Bt$tEa# zeka)YzV0p>u}GPrISRiM7Qv@V{+$L}xqTEKS12c8Q|I!W}Yu1ksJYucFGwiRFfS8ac!>0|{ndK9pSDz!Q5EvQ)M`w6ylI zJb4^ct(EjY;M77w*HKyaZVbh)nsg#qs5#k-{{<7#Rl(0_H_BTrNU(4x^6+6YA~!Od zw}}b5D*q4~tS0%^aGsK+N)u%C@5{Y@i-dfRS?mn9Qo_5_DRVD)TlIw(JPs#G+ruJa zY-j4mv8|e$dpmwfGQR_GUBvHH^*bO&lGYhq3L+-uaGIX3{Msnddo0Udi~7}MtQLpc z4G1`d;mFOAw>4p=m?agK_vv4RuRVYJkh>!BSpOWD2x)x-H5rXkSO6)?Ts&u&+{G82 zBYd$f)Z1pL&42H0bMc77Ez~y5%!KS3Y?Em9WDWgBzoM5=ak$NP?7-?}T!&HVZKfQT zyi2o3n8*0LD{t3)T8O#BnS8qSg3Qi*t5t>=k)$J5ixT}BP?MXAaC`su*C$7}-HrRE zgHU6?=S`*0oFblR{V2J1<5gBDu$xQ;C(aUR0gc?Z0h9^%Z6FD5yQg{f_XmZn5;=9z z&jw~emkgr30~Qj{3*Q2E?lx=|16_%cQZGt4>20?cbUfJelveJ_Xa3>+3ta6qpWtlM zWK-cgl5I6Y(j?l}sohVncOAqe23Q_R2~@!zlJ?3Ce=*$l)+tM$(MeY8eLicW<~|K9 zZ_5VoXBP*tisZ6U5oyX69=9NTrG!1;$}Aa~NdF4qK*QFTK8Q|-HQYB%7jf26+3uaK z!JHilRm>~rijZQkM=mgd9Hy~372=9HSu;{E-5$P2TTSks$F#dQmmpK3O{wsub)<*2Yt z@q&C3aFob+WH$EGuvjd!&gZ>OU3Iiv)020=h!mC|I)0Obd{tebez3HxuWrfqav+wQ z7@EcRo}Tc5Ui?HN$eZc)+7H$QcTmqw?Dhf3Um_)XrB%tT&l4u#E)Z|Uzx^ObWLRU} zx#d2kRBt<&6q|>yKd%1ursRExHqvZsd7e=R?#zVn&%yQ8y5-mFezojr=GB;OTkTIF zgCA3!7RFFdDA55f6IB+&M z<5YB1?I-MDsNVI=)=?5pvsh-s^7bw?x3eLRXXMq&Gr#A{8wauSK8b&Z~?(Kfs zup=-cIPAW77I`6*1}H8}Vf!?#1JXfpz=p~GuhdlI)|yJphg9G??{B6VVRybcY$_Xg z+um^Xgyl5q+TEhAO`}H=+XhP_<)}OOtz0XMnjpQ;RV0G z-RDu_xO?;)BImLY`Wc0%#?P-F3x#K^f*V|pIz*>5CSd=(EY&`?yLtY%-CeBx2y1S! zqYyrg#N#)rv*U*sLKo;RWkB(xzC+&-x>YxK))SU$<`uszdb zr+Ni#O{Y=l;gEy@^W>s*BBC``V!Sw0Q2p{}(l9sCQ6;(JP^heh28Ju?DB5g7;Ss#< zj`boF=YUxMi>o*E-@F*&U-S_$*Axy8u-0>(%s6wPXlGYo(1pJMI{9jh7hBU4tZ-kR^}}1}`jiPIlW4u*D_+C< zqwMm}46WvjzA8ZfaM`Sgii{iA2b#}GuuN`6pLV&^@leT43p=I^LQLX9&( zwL?Mj_@&OS&6=&_a_m?uv|IS#q}Fp2QBhaNTe<%!7aA8Q7)a&wRT_+MckJoU_IzWf zArc4IE$(Z%PA$nu`xDJ)rhQ{D_wF~i>hN&@TG?qVB?e3g>UQVJO-SKEf_&(F~Py(;_@#y)Muug z-LSM*?|@wiigL2tE#36bSejnSMztrXjv92J)kB2L-5BUVL9C4>a?&%6;BLTd8W|Z` zVb>ZZq>kKK(?Zf0axlx!h7u$zpIF~48{p*}e43lfo_jpg52PQ6Pq{0=%hSNst>Fw! zvEfR)o*uAK;*nQc@RuX9Oz1D$-u``pICA=_EOWL2g1xKz$(h|*I z6a2ZE5>pdbrqj8(gxp$Q&o$M29>FV@Ykkj9zfnB!%A;5PQr)4^&|v}dc*rCg*lsH8 zD&Bg$>*5^>h885I{#~hCZ3*On?hH$$qv=aICaEu2gI+=z8nNa?mOoD#Qat!CZ~H)L zQ3kG@#B@Pr(U*l`5Bwhzh#PtdY{SAY_-J{h|7}jSvsyRD`5GCz)Nv2vvJ)*J6(1kJ?DguQnDN(B6fR(mgSXA_{?HK>OA+=ig zQqe$0g^oqCwvD?^{&}!enw28M9OlfDLDn&)ovd!AnPwZ5cl9Pj+A@Z59U=Odlk<;) zo6`Q~TeYfB4rSln>g_(#Bc*u8s&4(GP_3t21#`gI;9V#&Z;Y3Ib$TDZUVc3=$xq;wRtDG4+i%05>?FnIGXNeV-_-{_99QpN7&&8t zKVza2a!zP7L?xv|p1sU zB!A!7x_e=;SMi97jl-8pg0AnpnpwO~hsE$Y*Cw(U+_JK4x%_>1#Fa)2$F^7cDM7CW zS*?9hM}b-+{An%Ncmk_d8d__?PbWPNokqS_9`NqXDb%whKX=kBfLh0+7&{xv9=P;$ zXF)W14UZcoj?9jmv8>wXxe*!oBnu#I96NN70%>IRd6qUyaiilpMM{zwM2w*qE}u zkt|})3z2lY=(*lMO+O7VF`3Tt4oG4FogddakFCaOKHq9v4~f^RBLi zWEY<}Q2@`Uis`(2kaNA9bW!N@t&dognUr#AfA|77*3LHy3=R65=D&hi&VJ-Z8x=VK>d>cAlHDkT zs)=}x%dHLj65M>?zfmIPx?c;RvAc>`^6QOdv5ATkny_7^zUjp!To>jlmEma_G4gww zgk>Bp9W#Bj+QCS{xz(+a*^cBCU<|>(5vsw1G)iDPH?|f>mGa$Rr}Q-ul+cA4)TABc z#(AsND*YwIqtz_c?L*X3VwqikLbbR;zGS^85bCjwk5N&1$5}3*q5AtEIUIl5^X8QFNN8uwMaAs20|1aXBOZ$hroBFxXX< zgI*z_SN0&dwZ@5n^`CqWzm@-~!=WrbbGFK9FeH~Fb$C?G>Qw@B$62P1gPzROYme$x zst7Ij(<`KstZ$5d3eCI5HINK?yJ1iH?rKV>6|PjCdEbO%Y5MUUa(79yIZfUvd3~ev zmk=??r|L}xH14G_(vFX-$AJ3rNUgiwm`Z=gP!9GzbF`?U%5vlx+P`9dbOk@%en~hg z6LtYL-`RD``&h9x($V#lK$6n*A*j=8r?q9;vB9v{Hm% zG4#ylgs+RFnyRnqjVK)QiVh|&6zztVjm$v(NYI_3sqQki?Znxi1P#(= zs($W`8!Sm7_Ygb-C+l>FUkT@tpd+k~-6$M1mTy=To>(83LPS7ea&{wI#LW3dK!csl zSx%XuBBMFRWM^m*_pFn9=+zho*h8iCdc)ykQ1>^JM>!8G4iG8C%V8kZXj5Oor7xEg zh}aaOK9pzY*j;P5{EYex>eex&-~_Ag5|cWVi}F>_BROJjoa8F~sV`a%p`!*ykrBe)@%1Bp{=O zB?12+h_xB2B?KLw>}A@eDwFqdcoAm7YNO$Eb)iF-_b%Gcx@p==cW&&kqfVTKZbYQlGQ1K(BdoqFaAM+85>tUu>I$MsLiYP-qZC#29gVF6Tkr zDWgPT*wze9)1K<yqlW^0(ysN+qrCK4dTEW>NpCEV9P3~fvbx9^2fSS+Gab6{HT_tf2IApvy zlPl?4HjtXT@{@8y^8EJ*M&;%`wF zl?NZ1y(YvBZlv=JlMB3$O5|c-cV1)|K5eR>XSNt={oQ$N6io^_L;Agf9b5sBHx{7Y z6X5HGr(_-Ad>o?eqtx5SqIUOjw6;Sc3h^~L9RCq=?u)FP+!P;rk`K@D4*)hps}zUs z^1IFJc|LfTPbTW=Cgp~%^2CI%n!S(0$sN-lpZuPqVtsMTa>PGR4Ml18nbQ9P{y^$#Q$>vruJt<_67`1*#j zN>>LmHrixJ4U5*Eq+(0O(C+3UpGGY58b>QRl;6kz4X#`7iJXVH!NH72-4N!w({w7y9@QNtoJFtD2a%o z8zU?~DP|RXg!=R_QkMP3vCZ&}Hm$T&_S7S4%)gnVH?jZ9%}uk!AXp>4Y)|_Gw@OWc z-}bIyA7szmReG0vA3d2t}f2)WUvu*@u}^UoP{aT`((P`uR z@23_f6b*RX2G!8f^e+@DAADSrJC}sdqm~=NYEGb$`J3rD6@)Kn*jY-k5kacagP&^% zz`rlfa@80&=>T*zzVfd_Mh+SN0k>|E0JPv^o-8pMaIklmLu+>pgIantLErrKQDVCW zHFgzO0;OgCK5sUvXW{%E000%orxF1iU@dU!xo>ay5@UIpny7!x9Cgkt%SoSV)L6^L zI^D1@=rNXL=Wk)chCHXf&c!ODq%(laaTV+N9ywYb6)}C8(vqD>Dw0-aATv=>Z`@92 zyidL2#&q%S6Yo>cP8yDYi8S(o?42cn1rzW1y`!lQ!@4+~+>Z`tV4n3Ds4eR{NP!@& z%>Q0_uJb2_a8@Q|HRR2Ts^6w0l#&P(-HS`b2P-m=`puP*k%wnFn`^tN-A=5@SRRS_Iaiqb6Pe+d_F~*f~baA$f=P4jh5p4p0MC^xj$qC>%-Wa_BrGPzxp)i z&rwl0C9^1_?;{E~vu)$clPS%Q?f6u=SJVjM1mW2>HZ=N~@0%tvl*_EZ86~-`;j2)GI1{+o8 zCtb*OX=!KMBmwKg^~*TZ7wBN4l=PMQ*&MRn)!2(PCM$!(`AL5iq}`Gb#)~x% z+`4X01RXwWrSqwc&!h}hf^Hx0X%gNnVbcVYp{feU+_ksW+d^!g1qzpH^Qj5xI7k_) z1@-d3|CLekAtsiD!-IT<60825 z`IM!p){kxiZ&k|KRjHz&8xS;>dFOzw;_KA3{R&&ERX=;GGXmd3Tg48Z7>|M(L?B~v z^d2>xiMOE;$g*%BdJsX@-B*OSjYnZdMBy=A9XL6HRdYG{Rchu(V=&w!u#^%z80vNw zz&oMHzPYp>HC;d>HQ_nKu78wEQs7Q~m3uKyE)i z*BV~6j?h~+J#}(?bZ!bU{+^mSL+neDK<-Y9Xg$au5MJ=D3m|{ZNqgwYz{{9w3$_2W zVCDRIpM~{>%4TE)*Fe%%@Rtw#jMCpNDZGRAnq^_Rs*%+Sth3L{^8JqXI=1+o*1IZ^ zA+T}8{Qa@5zsp|fnD-u*-}yd&_T&DMcHP(QY-gcYBQHCpaZnqTd zXSQ{?f5IfR=NFUOf;LAjc&eq^tbRQev=UaOWl;fN+dAgh?&vSN^DZYooo;b-EG&Fk z)XJz%)}aG&>2H7FC7l0i9JQUWKjwb0b(gufP7*PR%X?$|QMASc_x_z?Yqao9*Pd~K z+zGdCSJ)ibUUcWU9)-^n#|k+rs5^Gn{m=7vs3B2Y6XNboOH#PPi#As*$jLY%2q=(> zBe81u0<9`s!#uL1?&gkSF^Qx>H5Y+9jMF=EM~sJ1?NRz>0OFT6u?t1wQU=9~QLtg4 z_X0^Yu(t{Zvn=y5rCxD^q&NiZXLkn$iSW)i{VQaYv1}gyyFaK|Kodm0r0upRK}+%R2Q` zHT|1$!Wqze_DVA?9-M~n&mO)Q74SOLHM_4z?^{^i`2e%Xd+Kap#=@)Lb5k@T>4r^c z-T>E6A3Z9+x^w-4!)L-s!l&*|aN3%jSn@y}&pXruEqC0tJk9%4UOMF73(q;V@6Qv} z>;COYGq6Sp7d)CfIalsxp<0y8IYDXmVv@gqeS4}V9mW3f$FuO%+i9l@-lVaU3n)(r z+1h-=C9J7KiKOR4p~kFjAu2PG>ET7*r|iz2|H#~Ou|x6Gdl!!TdJ{%ydQQNFuHoT> z)&Tmn7Ftz+-FzEJ$B8-7k3o^LZ0=Y;PHNb}vBZ19`Lo7vBgI<@sJ=h5;6628mL^qu zrbGI+_CNi$dvtTaUdQz{|69KmHnaPX6A2%k7?<1$9ik!-^9i?k$Vpbyn>^+2UZVHLQGY|~It-W1RWDux}<4Y-5Elg0N$q@5D z*=-3{-4u_!@|yTuMfsqSmvG07)598oYHe?lHo>hHB`V@c@AXB3w-d>^Bk)AY9@WT# ze}q5nI=$qWDB`}FRaxvMO%_jgU+u7%DN1T@-ZIT3ZmSwGWv~ltJUHkT+3PicA=iIm zs)*!Ju)1xnD(ZR?;*Lzq%bQsQs&Ih}$P8FEF5P%`Yy)J&(*@T^8H>JKexslC`^zDU zA1-*gJ+DiySb@V92eZV!M=qUuR_Ukw4f3Y=C@nA7T}gk^R>$QOO;JHTdC29@RyO~V z_T*?n*Y#^7a#*GFh2gK$nAO1O=eB>}^0w{CdO@O)dGt=|QOp z8s(jPcsnyKvP*w98DX2DYqf>QqX)@H2pO29L5elEDT+r>Z*>!}WSx$6zm<-xI|AC( zDTYJ|ASr;(?C3%{ij(J3It2tIMFV(6u8@W;KULPhoRw6+kEKiFGxyCc3{d($kJb-C z>=m`$LpkSw(XeW=mC0V+6Dui_S;bhztpR4S{vyXUwt-;e=wU10vQ52mRAkW#L|!53 z|I%SUY)au)OrdPTAgkkqnQ?VC5M-$EHq<}v-Ya(-(Hs1^9V(u3-Q(#N=rZj+ZkRaG zLaj%_Qv?EVV}Wdo7a_7AoI%9AX<+Ix7O_MPIm2r1E|v$Zl^qIgtELeBDZ2fiv}b~R zfilLTEYr^-{cVKn`SZMk%WP)YH*FD1$M1KFIM4raFj|$x76@^-=o*G-h^laR6?R-W zb=jhQUO%%$si)#Y0Q+=fa9turU2vHGv>)$3tKm{=l9D&p1-EBXq}7 z&ub#8_+xy%tMp}1qUibxjw@{2j}%3avFJtO zsYkZPoJA~_3};wfbVFM!!SYV~5bn%B7IRCv?d9a)v7AK(DQCXC;whqW z;-J~a;>NCMwv)f5skbO6%jDwcW!#m#93RW&R7pMsBcgMn({YY*-=xy2$PrV3M&9#I z0jbmKvvk>~NtHSZmW;@DrzO<>r=WKGJ>73A*k^IWU1G1&c8tsuKXotB{E&&O+$KyJ z`y256j)PV!IEre%ilcPz!-`3xb&>a8@R$hcSyYKWe0nWQBP8NQ*rL&SNr}>HH=ouR zsm%FVc-5pA!rXz*T07qPhW^!ym7-5#BQkJpMFrJvv3ny08Ez^kms$c`v5CupAeEpUWk-`2w*5d-!;w2tdn z0t}g#pov>u^8_jaN7eFuPNcQ=5SwA2d*n#SVl^h+1eexGoTFVw?v-~Y%-XNA*$U*z zyZTRVD3HHNy?|SU-q?)6~G60bM66Z$GRLmZ#4)dU}ZVIo0E2F-< zJn%ROzLrSDfBh;GDfKk0-(p7@1&I^PEHJXJFG+Nwv)K6WYns$WnNIwLCgnoJW}}CU zg56dyN1m#hAgJCbZ{ld$(8QN7Uq-SpP`^iI!@FzF#r42@9)_^@sDhp4Z)~|%^+dg( z>3N0UnHDAx8vm5MtB!aQTM7{^94HK1Ikxris9B-vIikRQ7pr~!oQjZ&X*G+nib!Xb zt=fn;L*Y9ysF<%uQifK1U+{>BAcK#U_3k)R&&gB#D zQHhkC8}Sc&N2B>dvrihTyb)$Ec#u|$y#D5wO?~p)qOxW=;Fw_jVme)*PBZl%Q+fH8 z?stQU-0dF{ch1+*bj4P&ELn4f`=rVDk7;9gH zNiR!_=1?Ws#(<8p8U-o1GCix9?Fz9$S*V8CyXsI!TRZx8Ku_5o^m$~CXeEMq2@ zu!|_Cboiw|g}Ql(@Kt>6G3w~cmVT;srH>rE?CR~@>h1J~)D9+BEG%xOc=Zku|IkA?k$b)H zHDD_Bww$7)w}l=$pSPX$9uf8sw0r(soW^?aR|HIU0fu)C^!7-I8%q#*?3VY~I6J7= zGnQR3q9jpj=onB&HWYXH#2ci*T zGDW)D`dshL-juHY$*N}05|artP|I)t^4OQB z>W?%l8*A?=a2mY9iawq1&g;ERM#3&Zg=0jR4Lu zw^755Z@1E_cjn!)5lKUpuxHz%j}-+BY^84G=zf1@+QxJ>4Y8tI4Tg%Y7Nw@55sdGk zVKl4-I?h$XfB{sze}JZ33;5e@Aont~-Tuj=jeFztGg6^0>87Szm7yc{YnA0WX4UBl zQlNt`rSGHTv*W=+bJO)f>{KE;LU#3A<@?9Y%Tq4eL>l&y^2^UuOhVBsy>zF=T#WnC zw_CUrg8|>h@vOyfSDdXZ8V1xXatU^TI}sOT{2X|8pX*C$wRc5mLcA&;K`gQy|DFVy zMJ)M`duSYZyDqYdYrupWLzunwFE{P}gsq}>{^b@wj zbHb44I=i|CR%(}urqk*DIq3Ck=;>>2{HKpkoA@7FQ|dn=oLSeY6$?j93X|5^->91BKRw}5Pq)vS%Zwb||B_vlBYEz4$n^6J zf$wu8-N$p@sf`+Xr~Z@mU|!zXVsQUwrk%&Aqk6|E;V~wbyAj9(%8X8(ca``paI}z` z`wG)oy<>|zGF3wY^Qv|Z-I%}(Y{cAzTR~9~74T;mzPe)9_?l5u9=%^N5_sX-La}6t z*dgWZ9Z%y><|7>$pHXH)o{PHBJJ$84hV$qBb_W17PLC#tBZ{@>-JS zi+JjHsAt^Rl6jimMBFhrm>1a#&H;V?R+BUhS{j(omG3secx|6M0B-#4-A*499&3-W zo3{K7FD<^F$h#l-r{&~K4BNs~uqTNEs8CEI2B^(<7S6=2m3;Hh>XOx?0UwI0s)y%a zzPoDp+~I9<=Rn<>bRsYQ!=L+{*W@}Qf8CtAZc}$l>ikFToRdsPQ?r>|1bByS+kSgL z)yjR%UcxDtAjPisPn4aYnz!S0xB4ow@Q>qePO;Yh&fOJ(>8G#KjLdJ{g4{(u0)iUY zk&c?;w&SWKNt}`J;hpI=uHb5yQj6bLmwRE(0xw$r)a!>Y$Z-*R_p-3`BTB2hC>pY= z(abZ*`cP!#xO73FlB@p{_iu62>SRTGa>ruM6Ny2ef#_F?Z0}086X$m2UOckkdpfeE zd9=QvCjWaM?Mc&ksg%ex*Zy!C@^y>1W-k4Fgc6+5Y3Muy(YjbdBEs`T@X zr~t0R(KoewTSSsu&1^hi+pM<`G`5E9w$s#KxpfcN`tB}!3)=~uU;P##{*zjLj#wi9 zhPS!CN7(wU(8|y3hXN95GJ0kjNltG1-m@c(^`HAs&b1%+Sr_UqcIR$+AUaBvyIE6V zyX;+keYRyNalXj)^IsMpSBJu;!n^!+WLd9t@DK%=yf5re+VOa_g!4;jffFy9As59ld~j(5Bx-J zBMLRXojNG&mYC^RLXEG`|A7X+N|Wf+xO!eY&w<^ zIuaGYl9|0PW!g&j(G#V<)5diJ@#f{rzERuC9maj}rNH=)Y~Js#vA;7@G23eLtrDL$ z2klkS504zO*(|!ZB?S>QY%{1zP3Y6pimX}>H$hG{Pfbn154M29`g==Di_O26@%s@| z`o51!tOeD7q*@@jU{W%<{>yibZF9M=D+t9nJ3HjcY&V(}Ughds@I^@`^;juNW&6W< z^zU~H*Dv=iR<{hTLEiAY-jU)9(RY@7;BWrmT-A!~KhVLg7l5{X960WdrPC7ARcTFp z@ZAsY0hDBiG1WP4zPiYEFyDrXZLR`LT>M(l8{0$0def4wkQ8R@g^Z1`#orx1ZDPC- z!D-}Pwv)_>K}B^Rxiu ziM|<0l_<-+f>%{hd%l0_Qtg9NzvObPPxHL!AkM@&6^+*7Y_ED?lOu^1=LwV=rt#!m z9I6eF`*<11OLef~{6nkYqMKRkF%=aR7~IZOB%|2dhAOtv*!0rk8Qe_`+rjOj5i#Hx zqTcz8wEnQdHoo97%hHRRCh>)RCucrFzlTqDyL-Y;R@hShcA-ee9To2?WL`8`7@;ww80KrXhCm;Ku<;Eb+W0!h;(0(GuTQByF(!v z6NtF2x?n+n?V(P$G`>wFglIhAtUK(dV_{qM(zPUYx<1uDXVTM^l=nfx6 zqV@f14VPD@#FY)pA!DtP?$XBb#_gXy3MA;mtxC~K>2HWrCx`y)#-_ba2B0CrENRD( z>SwFD*`v$43I=gu@L)G;Z8vk9REt{yN2uYHptn*wKlkl0Uu$LG#I!@PdGVcRuO)u< z{@OoMS@ZCiH^F4L*`#39v*Sv`L0!Na>%{pjKi#w4KUrAF(I>h)G=djvFrY>s?Y?_r z2#ae2Dl3!WQPCW`x(>FwyJqlQ&*hEy;?jbPC)AsK301gRO7|+@93iy7vu|gm+6-Pb z7!SU|8RVQic76MmU8)YWPNACIqDC3|uwN>$#N(Tghm!MlsUalnsi9P3z3L=`o0m1# zle43XbLHGo2%_9w?sV$fWRue2;ko}?0K^z<)dZR`4-A3lyt_{?*1zE!E52-1cPp(G zJUBNHf+}=F+3R=z26CWD@Pj|@DBi8Eijd24&%EBMUk(D{ORn7b1&MrgOp7NL@E{_W zIqj*UyR@p0%Pnfb$V$&qGtZQ4YlmJxAZq3Jozjp|E6y)!a1?sSIpw*T2nK~~8VzvU zfRBV3Q#*L&T>s9#>UibYLwBya0V`kU`o?ZW*K{_a!Dx(*{wxm2^Y1fHs$G6z#nnt1 zu~_Gwwfty+S_>4>=y6eTXIg7pTwHVj*pU9cD>fanva)}Hx+cdj$0U89Jn-RzRX13N zHIaM}_PcsZ(qgZ31ve6g5yTw(B+ioj8DSV`5Ez~C8z*0`tAPC|9hf#cDU?-MaIIVz zh%2MWDRzA+efq@2=bG={bo4vOwW@4s=u1?BUxOQ8|dtMy263L@%*w z`sWP+*Aw#~t-+ur4!`9pBIeNjq-fLUVG&2;K*;8=2%Ck&JlUVE=K1oOqFHTI`d_Mk zE`*QD3^V9RZhrQ!SDma`ZxY)mV(MCzF5YPwwZ583IM(PV*FOz-c_ijUr$-Ems$WJ@YH=!kLr4Zz(PWqM z`le6AZb!pzFL1&{Erv^^RfEByAGzMVhO}BW{4u)&lJ>HIgZ<5;B0JxIF;*K6I@0$( zOuQBxo;Uic?C~Rsji`@EEH3D*G9inldx%s-kUK=xEr7;tRb?}UrwHm>7SQ&MFQ`6T z>(wg?{o)BraIJ~a+K&#edZ}fgiz@%-jtFk+>u*d4ow+zi2LRd;od{^!Mi4pLbj2&_ zwUBEQ5nQqBT%6@!rFDW<`+qLsA=k!VPp|#{{hO7Lt`%TcHjLW_mwlc+v?%fA7vLhh zvp)Uc;lovUI_xim5}^3C3ENm~s;n6CIyCd6GTs(jBmwC4y>DnEP0a+h`X81f?VIV;EZ< zzeYy|4_kzfU0unTZa8iy71T@>A1W&Tfb&-V;*HRIX&GI|R>c%j7&=s3lsm*?>*POB z_fSu_{}|i=hdg{SMYI0%e_Xn64cDJ8CdjY`&%ExU7csPa`c=GDE zuQ=#XlUbfV4Gntc&PQ`R6+ZIlmo8o!2=^0q9ZsRPMtA=_a!<8=@Zh?jesAy3pFagE z{%o@!58TGDHL@9kw{^_8Wi_gH&6 zOJ$A!4N`8vo8G|=yBxW3R^QAMxOoC#eGJU?!0HnIT=>9;W=!l8uN{SO9FqZ(kIbvv z9&gnl95fvrzj4LUqNI7!rtklIfuYcy|DNi_WpIJc;Ku1aeohMiH7a+<=DQqsJwlUE z10k%UEZg(`Qg~2XrYrn$zzPQ=Trlv$fHm+(II!g=*8%rek?US_oye@-YBI<|?+FM9 ze7p)lv&?7BjjYFd?XBgxch>=L!BnUUk?Dg-52SNnP!IPAcD`X#{j3D~*w?`5>E=z0R9I@-{@t=0Tir`*}Pn(N&ZoG*Z7fxkiG&a1y2 z%0M37Zhr{k{qIBH3=)3!zrSs%S+02K0C5Og^PwNYXN@Q7CZ{1~;Fcv00#Q-fEXs|8 z>IDZn!KUB8?~#F!vh4@D0lw<3Hc$1N2Vc(|Z%>%;BD#W^PTqYwN!dLQFBzFLefmTe z){hC#JmDdDDdJGSp=TDO_ z=vm8c0b`!gRTOrkJUo(!(0ScfRO^y!6Td^sw093ZBq4yKgzbOfuF--;RPy$_$Sp-2#Zv@)|8HrIgVdtBO~zuT=<|YAiU+HcKS_Cc zoY-7qD#4n)(Z|p2qB(EbZVB_;GdR1`-Y&bHCZ|G?8A^rxV4c-)2J;JFMU=}Dr@@3* zM@c-8%_K~bNL3MKg^_{!lKRk)8{|5l6&?>E2z`8w0~}c}T1t%U?nSd-%Olqf6@0&K z@^!jHjX{4r70%$A2u&q9h)2kVNIR#g4nk@bN)m88nT^sL4w!a?9b*Ag#;kbqjoXo~ z-*C0Ubpc)`rY5ikr2^U;kB`>PzO%hu!@;8*8!?f<)sc2pLQZ52u2=q=G~}wjd18rU z$&nEP^bJtlG;APc7?Jaz6&1(17UcgLv1Vm| zmvU^O%X|;iV+omO{3-N+eh)^b>VB!}j;Oif$rq#zDCy%|sUjkgYY;$NZ0+gFzy0p5 z%9Y&oDzXgss)b*CE^f$`6-drqyu(HUwAMUSx0UBMukhRNE!IwEBOBRI*K^^F5b+y( zHB{(Gpc&-pc{vSslRk_A;T{P_0~0CqlOApR6_^i!g?c+Z9L&OHDFw^xh*hKN zQEC4?84|E&cfQ+yAoWz~wrh70OxT+Stp%-WWTde6o_Y^O=OF*Ge}YlV0ZIT>bt$>J z1sl5r3OTKZ38l`g*tkkJhT=)O>=*IeCZUK(kvnHs-BLO;8*3u&{>nj$w^yC4%0?K9`NzpyuRz2cMH>7crWZ4 ziOvDG)2suF^HHPxcWt+yeyutCuJl{IHRcgDpsHd`P%hs<*v?KXAs2vXRfY7Tiw-f3 zPwflZJ7FZ5u&i}nF1(|W`qco32vfnf3bWNaTjTd|`6Khzq}>b6?2L?5%#*?E(+X!p z10yTPGm&Y`3ZWBS+?jX*WQn@P$IE{Iq){ z(9GF;3J!J-bWZH}>r7sC?mn|?Xggc^Lgq0f3wD^T^H#vTZmt1by_Y9fm&6%VA7ae1 z5gD%7g29MNWVwiw(dJfROYeQuP^ySf3mIEXf%!o|?)AMk@neG%{u;^LCh5^h{84BR z2Z*07jY$M-R~UX8CDn3`S%`m{vkx8z$1|dgo73W@V5)`jEH`3vYq%HGNX_Esr#*Sz zyJHaZc?+t*!g5OpSn3mMfGSca$Vf_i12YiSAj~wkKWgIlgk1nnGc#uy)nxn1e)v z^i%*zMb}=uN!awB%$z0@0r;WfK7@EgYKp{rx-&w0Y60j0Cg=YFiLiV;Ye(5}qxuf| zMMOW7pq*h;AHO(bEY|kr-1ZjB(FKQ?e>9p>B0dx)DP|EmGYm|~S22NM+CmCzTQuSI aSAqAHpVMbI@KbNW?^EiTPekN%`Tqj0%NGFv literal 0 HcmV?d00001 diff --git a/static/assets/js/actions.js b/static/assets/js/actions.js new file mode 100644 index 0000000..2887003 --- /dev/null +++ b/static/assets/js/actions.js @@ -0,0 +1,120 @@ +document.addEventListener('DOMContentLoaded', () => { + initModals(); +}); + +let activeNotepadId = null; // Tracks which notepad is currently selected + +function initModals() { + // --- Create Notepad Logic --- + const modalPad = document.getElementById('modal-create-pad'); + const btnOpenPad = document.getElementById('btn-create-pad'); + const formPad = document.getElementById('form-create-pad'); + + if(btnOpenPad) { + btnOpenPad.addEventListener('click', () => { + modalPad.classList.remove('hidden'); + }); + } + + if(formPad) { + formPad.addEventListener('submit', async (e) => { + e.preventDefault(); + const name = document.getElementById('pad-name').value; + const isPublic = document.getElementById('pad-public').checked; + + try { + const res = await fetch('/api/notepads', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, is_public: isPublic }) + }); + + if (res.ok) { + const newPad = await res.json(); + modalPad.classList.add('hidden'); + formPad.reset(); + // Transition to the new notepad + if (typeof loadNotesForPad === 'function') loadNotesForPad(newPad.id, newPad.name, newPad.is_public, newPad.owner_id); + } else { + alert('Failed to create notepad'); + } + } catch (err) { + console.error(err); + } + }); + } + + // --- Create Note Logic --- + const modalNote = document.getElementById('modal-create-note'); + const formNote = document.getElementById('form-create-note'); + + if(formNote) { + formNote.addEventListener('submit', async (e) => { + e.preventDefault(); + if (!activeNotepadId) { + alert("No notepad selected!"); + return; + } + + const title = document.getElementById('note-title').value; + const content = document.getElementById('note-content').value; + + // Use current map center + const center = map.getCenter(); + + try { + const res = await fetch('/api/notes', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + title, + content, + lat: center.lat, + lng: center.lng, + notepad_id: activeNotepadId + }) + }); + + if (res.ok) { + modalNote.classList.add('hidden'); + formNote.reset(); + // Refresh notes + if (typeof loadNotesForPad === 'function') loadNotesForPad(activeNotepadId); + } else { + alert('Failed to create note'); + } + } catch (err) { + console.error(err); + } + }); + } + + // Close buttons + document.querySelectorAll('.close-modal').forEach(btn => { + btn.addEventListener('click', (e) => { + e.target.closest('.modal').classList.add('hidden'); + }); + }); +} + +// Helper to open edit notepad modal (called from index.js) +window.openEditPadModal = function(id, currentName, currentPublic) { + document.getElementById('pad-id-edit').value = id; + document.getElementById('pad-name-edit').value = currentName; + document.getElementById('pad-public-edit').checked = currentPublic; + document.getElementById('modal-edit-pad').classList.remove('hidden'); +}; + +// Helper to open edit note modal (called from index.js) +window.openEditNoteModal = function(id, currentTitle, currentContent) { + document.getElementById('note-id-edit').value = id; + document.getElementById('note-title-edit').value = currentTitle; + document.getElementById('note-content-edit').value = currentContent; + document.getElementById('modal-edit-note').classList.remove('hidden'); +}; + +// Helper to open note modal (called from index.js) +function openCreateNoteModal(notepadId) { + activeNotepadId = notepadId; + document.getElementById('modal-create-note').classList.remove('hidden'); +} diff --git a/static/assets/js/admin.js b/static/assets/js/admin.js new file mode 100644 index 0000000..df7178e --- /dev/null +++ b/static/assets/js/admin.js @@ -0,0 +1,257 @@ +document.addEventListener('DOMContentLoaded', () => { + loadStats(); + loadUsers(); + initCollapsibles(); + initSearch(); +}); + +let selectedUserId = null; +let selectedNotepadId = null; +let allUsers = []; // Store users for client-side searching + +async function loadUsers() { + const userListDiv = document.getElementById('user-list'); + userListDiv.innerHTML = '

Loading users...

'; + + try { + const res = await fetch('/admin/users'); + if (res.status === 403) { + window.location.href = '/login.html'; + return; + } + allUsers = await res.json(); + renderUsers(allUsers); + } catch (err) { + console.error(err); + userListDiv.innerHTML = '

Error loading users.

'; + } +} + +function renderUsers(users) { + const userListDiv = document.getElementById('user-list'); + userListDiv.innerHTML = ''; + + if (users.length === 0) { + userListDiv.innerHTML = '

No users found.

'; + return; + } + + users.forEach(user => { + const userDiv = document.createElement('div'); + userDiv.className = 'user-item'; + + // Handle "Unowned" user display specifically or generic + const ipDisplay = user.id === 0 ? '' : `
IP: ${escapeHtml(user.last_ip || 'Unknown')}`; + + const infoDiv = document.createElement('div'); + infoDiv.innerHTML = `${escapeHtml(user.email)} (${escapeHtml(user.first_name)} ${escapeHtml(user.last_name)}) ${ipDisplay}`; + + const actionsDiv = document.createElement('div'); + + // Ban IP Button (only for real users with IPs) + if (user.last_ip && user.id !== 0) { + const banIpBtn = document.createElement('button'); + banIpBtn.className = 'admin-button'; + banIpBtn.textContent = 'Ban IP'; + banIpBtn.onclick = (e) => { + e.stopPropagation(); + banUserIp(user.id); + }; + actionsDiv.appendChild(banIpBtn); + } + + userDiv.appendChild(infoDiv); + userDiv.appendChild(actionsDiv); + + userDiv.addEventListener('click', () => { + selectedUserId = user.id; + loadNotepads(user.id); + expandSection('notepad-list'); + }); + userListDiv.appendChild(userDiv); + }); +} + +function initSearch() { + const searchInput = document.getElementById('user-search'); + searchInput.addEventListener('input', (e) => { + const term = e.target.value.toLowerCase(); + const filtered = allUsers.filter(user => + (user.email && user.email.toLowerCase().includes(term)) || + (user.first_name && user.first_name.toLowerCase().includes(term)) || + (user.last_name && user.last_name.toLowerCase().includes(term)) + ); + renderUsers(filtered); + }); +} + +async function loadNotepads(userId) { + const notepadListDiv = document.getElementById('notepad-list'); + notepadListDiv.innerHTML = '

Loading notepads...

'; + + try { + const res = await fetch(`/admin/users/${userId}/notepads`); + const notepads = await res.json(); + + notepadListDiv.innerHTML = ''; + notepads.forEach(notepad => { + const notepadDiv = document.createElement('div'); + notepadDiv.className = 'user-item'; + + const infoDiv = document.createElement('div'); + infoDiv.innerHTML = `${escapeHtml(notepad.name)} (Public: ${notepad.is_public})`; + + const deleteBtn = document.createElement('button'); + deleteBtn.className = 'admin-button'; + deleteBtn.textContent = 'Delete Pad'; + deleteBtn.onclick = async (e) => { + e.stopPropagation(); + if(confirm('Delete this entire notepad and all its notes?')) { + await deleteNotepad(notepad.id); + loadNotepads(userId); + } + }; + + notepadDiv.appendChild(infoDiv); + notepadDiv.appendChild(deleteBtn); + + notepadDiv.addEventListener('click', () => { + selectedNotepadId = notepad.id; + loadNotes(notepad.id); + expandSection('note-list'); + }); + notepadListDiv.appendChild(notepadDiv); + }); + } catch (err) { + console.error(err); + notepadListDiv.innerHTML = '

Error loading notepads.

'; + } +} + +async function loadNotes(notepadId) { + const noteListDiv = document.getElementById('note-list'); + noteListDiv.innerHTML = '

Loading notes...

'; + + try { + const res = await fetch(`/admin/notepads/${notepadId}/notes`); + const notes = await res.json(); + + noteListDiv.innerHTML = ''; + notes.forEach(note => { + const noteDiv = document.createElement('div'); + noteDiv.className = 'user-item'; + + const infoDiv = document.createElement('div'); + infoDiv.innerHTML = `${escapeHtml(note.title)}: ${escapeHtml(note.content)}`; + noteDiv.appendChild(infoDiv); + + // Add delete button for each note + const deleteButton = document.createElement('button'); + deleteButton.className = 'admin-button'; + deleteButton.textContent = 'Delete Note'; + deleteButton.addEventListener('click', async (e) => { + e.stopPropagation(); // Prevent selecting the note + if (confirm('Are you sure you want to delete this note?')) { + await deleteNote(note.id); + loadNotes(notepadId); // Refresh notes after deletion + } + }); + noteDiv.appendChild(deleteButton); + + noteListDiv.appendChild(noteDiv); + }); + } catch (err) { + console.error(err); + noteListDiv.innerHTML = '

Error loading notes.

'; + } +} + +async function deleteNote(noteId) { + try { + const res = await fetch(`/admin/notes/${noteId}`, { + method: 'DELETE' + }); + + if (res.ok) { + alert('Note deleted successfully.'); + } else { + alert('Failed to delete note.'); + } + } catch (err) { + console.error(err); + alert('Error deleting note.'); + } +} + +async function deleteNotepad(notepadId) { + try { + const res = await fetch(`/admin/notepads/${notepadId}`, { + method: 'DELETE' + }); + if (res.ok) { + alert('Notepad deleted.'); + } else { + alert('Failed to delete notepad.'); + } + } catch (err) { + console.error(err); + } +} + +async function banUserIp(userId) { + if(!confirm("Are you sure you want to ban this IP address? This will block all future access from this IP.")) return; + try { + const res = await fetch(`/admin/users/${userId}/ban_ip`, { method: 'POST' }); + const data = await res.json(); + alert(data.message || data.error); + } catch (err) { + console.error(err); + alert("Error banning IP"); + } +} + +async function loadStats() { + const container = document.getElementById('admin-stats'); + try { + const res = await fetch('/admin/stats'); + if (res.status === 403) { + window.location.href = '/login.html'; + return; + } + const stats = await res.json(); + + container.innerHTML = ` +

${stats.user_count}

Users

+

${stats.notepad_count}

Notepads

+

${stats.note_count}

Notes

+ `; + } catch (err) { + console.error(err); + container.innerHTML = ''; + } +} + +function initCollapsibles() { + const headers = document.querySelectorAll('.section-title'); + headers.forEach(header => { + header.addEventListener('click', () => { + const content = header.nextElementSibling; + content.classList.toggle('collapsed'); + }); + }); +} + +function expandSection(id) { + const el = document.getElementById(id); + if(el) el.classList.remove('collapsed'); +} + +function escapeHtml(text) { + if (text === null || text === undefined) return ''; + return String(text) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} \ No newline at end of file diff --git a/static/assets/js/auth.js b/static/assets/js/auth.js new file mode 100644 index 0000000..87c8fb9 --- /dev/null +++ b/static/assets/js/auth.js @@ -0,0 +1,59 @@ +document.addEventListener('DOMContentLoaded', () => { + const loginForm = document.getElementById('login-form'); + const registerForm = document.getElementById('register-form'); + + if (loginForm) { + loginForm.addEventListener('submit', async (e) => { + e.preventDefault(); + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + try { + const res = await fetch('/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }) + }); + const data = await res.json(); + + if (res.ok) { + window.location.href = '/'; // Redirect to map + } else { + alert(data.error || 'Login failed'); + } + } catch (err) { + console.error(err); + alert('An error occurred'); + } + }); + } + + if (registerForm) { + registerForm.addEventListener('submit', async (e) => { + e.preventDefault(); + const email = document.getElementById('email').value; + const firstName = document.getElementById('first-name').value; + const lastName = document.getElementById('last-name').value; + const password = document.getElementById('password').value; + + try { + const res = await fetch('/auth/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password, first_name: firstName, last_name: lastName }) + }); + const data = await res.json(); + + if (res.ok) { + alert('Registration successful! Please log in.'); + window.location.href = '/login.html'; + } else { + alert(data.error || 'Registration failed'); + } + } catch (err) { + console.error(err); + alert('An error occurred'); + } + }); + } +}); \ No newline at end of file diff --git a/static/assets/js/index.js b/static/assets/js/index.js new file mode 100644 index 0000000..d60b096 --- /dev/null +++ b/static/assets/js/index.js @@ -0,0 +1,1024 @@ +document.addEventListener('DOMContentLoaded', () => { + initMap(); + initSidebar(); + loadNotepads(true); + + const form = document.getElementById('form-add-collaborator'); + if (form) { + form.addEventListener('submit', async (e) => { + e.preventDefault(); + const padId = document.getElementById('share-pad-id').value; + const email = document.getElementById('collaborator-email').value; + const permission = document.getElementById('collaborator-permission').value; + + try { + const res = await fetch(`/api/notepads/${padId}/collaborators`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, permission }) + }); + + if (res.ok) { + form.reset(); + const padName = document.getElementById('share-pad-name').textContent; + openShareSettingsModal(padId, padName); + } else { + const err = await res.json(); + alert(`Failed to add collaborator: ${err.error}`); + } + } catch (err) { + console.error(err); + alert('An error occurred.'); + } + }); + } + + const formEditPad = document.getElementById('form-edit-pad'); + if (formEditPad) { + formEditPad.addEventListener('submit', async (e) => { + e.preventDefault(); + const padId = document.getElementById('pad-id-edit').value; + const name = document.getElementById('pad-name-edit').value; + const isPublic = document.getElementById('pad-public-edit').checked; + + try { + const res = await fetch(`/api/notepads/${padId}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, is_public: isPublic }) + }); + if (res.ok) { + document.getElementById('modal-edit-pad').classList.add('hidden'); + loadNotepads(); // Refresh everything + } else { + alert('Failed to update notepad.'); + } + } catch (err) { console.error(err); } + }); + } + + const formEditNote = document.getElementById('form-edit-note'); + if (formEditNote) { + formEditNote.addEventListener('submit', async (e) => { + e.preventDefault(); + const noteId = document.getElementById('note-id-edit').value; + const title = document.getElementById('note-title-edit').value; + const content = document.getElementById('note-content-edit').value; + + try { + const res = await fetch(`/api/notes/${noteId}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ title, content }) + }); + if (res.ok) { + document.getElementById('modal-edit-note').classList.add('hidden'); + // Refresh current view + if (activePadId) { + loadNotesForPad(activePadId); + } else { + // This was likely from a search result, which is harder to refresh. + // A full reload of notepads is a safe fallback. + alert('Note updated. Refreshing list.'); + loadNotepads(); + } + } else { + alert('Failed to update note.'); + } + } catch (err) { console.error(err); } + }); + } +}); + +let map; +let activeNotes = []; +let userLocation = null; +let activePadName = ""; +let activePadId = null; +let activePadIsPublic = false; +let activePadOwnerId = null; +let activePadCanWrite = false; +let currentUser = null; +let isTracking = false; +let userMarker = null; +let notifiedNoteIds = new Set(); + +let isLoggedIn = false; +function initMap() { + // Default view (e.g., Oklahoma area if geolocation fails) + map = L.map('map').setView([35.6528, -97.4781], 10); + + // Ask for location + if (navigator.geolocation) { + navigator.geolocation.watchPosition((position) => { + const { latitude, longitude } = position.coords; + userLocation = { lat: latitude, lng: longitude }; + + const centerBtn = document.getElementById('btn-center-user'); + if (centerBtn) centerBtn.style.display = 'block'; + + if (isTracking) { + map.setView([latitude, longitude]); + } else if (!userMarker && !new URLSearchParams(window.location.search).has('pad') && !new URLSearchParams(window.location.search).has('note')) { + // Only auto-center if we aren't loading a shared item + // First fix + map.setView([latitude, longitude], 13); + console.log("Map centered on user location:", latitude, longitude); + } + + // Add User Location Dot + if (userMarker) { + userMarker.setLatLng([latitude, longitude]); + } else { + userMarker = L.circleMarker([latitude, longitude], { + radius: 8, + fillColor: "#3388ff", + color: "#fff", + weight: 2, + opacity: 1, + fillOpacity: 0.8 + }).addTo(map).bindPopup("You are here"); + } + + // Location-Based Browser Alerts + const userLatLng = L.latLng(latitude, longitude); + if (activeNotes && activeNotes.length > 0) { + activeNotes.forEach(note => { + const noteLatLng = L.latLng(note.lat, note.lng); + if (userLatLng.distanceTo(noteLatLng) <= 50) { + if (!notifiedNoteIds.has(note.id)) { + notifiedNoteIds.add(note.id); + alert(`You are near a note!\n\n${note.title}\n${note.content}`); + } + } + }); + } + }, (err) => { + console.warn("Geolocation error:", err); + }, { + enableHighAccuracy: true, + timeout: 10000, + maximumAge: 0 + }); + } + + // Add OpenStreetMap tiles + L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '©
OpenStreetMap' + }).addTo(map); + + // Listen for zoom changes to toggle note display + map.on('zoomend', () => { + if (activeNotes.length > 0) { + renderMapMarkers(); + } + }); + + map.on('dragstart', stopTracking); + map.on('popupopen', stopTracking); +} + +function initSidebar() { + const sidebar = document.getElementById('sidebar'); + const toggleBtn = document.getElementById('sidebar-toggle'); + + toggleBtn.addEventListener('click', () => { + sidebar.classList.toggle('collapsed'); + // Change arrow direction based on state + if (sidebar.classList.contains('collapsed')) { + const sections = document.querySelectorAll('.list-section'); + sections.forEach(section => { + section.querySelector('.list-section-content').style.display = 'none'; + }); + toggleBtn.innerHTML = '<'; // Point left (open) + } else { + toggleBtn.innerHTML = '>'; // Point right (close) + } + }); + + const centerBtn = document.getElementById('btn-center-user'); + if (centerBtn) { + centerBtn.addEventListener('click', () => { + isTracking = true; + updateTrackingUI(); + if (userLocation) { + map.setView([userLocation.lat, userLocation.lng], 16); + } + }); + } +} + +async function loadNotepads(isInitialLoad = false) { + // Reset state + activeNotes = []; + currentMarkers.forEach(marker => map.removeLayer(marker)); + currentMarkers = []; + + // Check auth first + try { + const authRes = await fetch('/auth/me'); + const authData = await authRes.json(); + isLoggedIn = authData.authenticated; + currentUser = authData.user || null; + } catch (e) { console.error(e); } + + // Reset Sidebar Header + const header = document.querySelector('.sidebar-header'); + if (header) { + let headerHTML = '

Notepads

'; + if (isLoggedIn) { + headerHTML += ''; + } + header.innerHTML = headerHTML; + + if (isLoggedIn) { + document.getElementById('btn-create-pad').addEventListener('click', () => { + document.getElementById('modal-create-pad').classList.remove('hidden'); + }); + } + } + + const sidebarBody = document.getElementById('sidebar-body'); + + if (isLoggedIn) { + sidebarBody.innerHTML = ` +
+ +
+

Loading...

+
+
+
+ +

Loading...

+
+
+ +

Loading...

+
+
+ + +
+ `; + const listSection = document.querySelectorAll('.list-section-header'); + listSection.forEach(header => { + header.addEventListener('click',toggleSection) + }) + setupPublicToggle(); + + try { + await loadNotepadsOfType('favorites', 'favorite-notepads-list'); + await loadNotepadsOfType('shared', 'shared-notepads-list'); + const res = await fetch('/api/notepads?type=mine'); + const notepads = await res.json(); + renderNotepadList(notepads, 'my-notepads-list'); + } catch (err) { + console.error("Failed to load notepads", err); + document.getElementById('my-notepads-list').innerHTML = '

Error loading data.

'; + } + } else { + // Logged out: Only Public Notepads + sidebarBody.innerHTML = ` +
+

Public Notepads

+

Loading...

+
+ `; + + try { + const res = await fetch('/api/notepads?type=public'); + const pads = await res.json(); + renderNotepadList(pads, 'public-notepads-list'); + } catch (err) { + console.error(err); + } + } + + // Initial Load Logic (Check for URL params first, else default behavior based on auth) + if (isInitialLoad === true) { + const params = new URLSearchParams(window.location.search); + if (params.has('pad')) { + const token = params.get('token'); + loadNotesForPad(params.get('pad'), undefined, undefined, undefined, true, token); + } else if (params.has('note')) { + const token = params.get('token'); + loadSingleNote(params.get('note'), token); + } else if (isLoggedIn) { + loadAllMyNotes(); // Default action for logged in users + } else { + try { + const res = await fetch('/api/notepads?type=public'); + const pads = await res.json(); + const globalPad = pads.find(p => p.name === "Global Public Notes"); + if (globalPad) { + loadNotesForPad(globalPad.id, globalPad.name, true, globalPad.owner_id); + } + } catch (err) {} + } + } +} + +function setupPublicToggle() { + const btn = document.getElementById('btn-toggle-public'); + const list = document.getElementById('public-notepads-list'); + + btn.addEventListener('click', async () => { + if (list.style.display === 'none') { + list.style.display = 'block'; + btn.innerHTML = 'Public Notepads ▾'; + + // Lazy load if empty + if (list.innerHTML === '') { + list.innerHTML = '

Loading...

'; + try { + const res = await fetch('/api/notepads?type=public'); + const pads = await res.json(); + renderNotepadList(pads, 'public-notepads-list'); + } catch (err) { + list.innerHTML = '

Error loading public pads.

'; + } + } + } else { + list.style.display = 'none'; + btn.innerHTML = 'Public Notepads ▸'; + } + }); +} + +function renderNotepadList(pads, containerId, isFavorite) { + const container = document.getElementById(containerId); + container.innerHTML = ''; + + if (pads.length === 0) { + container.innerHTML = '

No notepads found.

'; + return; + } + + pads.forEach(pad => { + const item = document.createElement('div'); + item.className = 'notepad-item'; + item.style.padding = '10px'; + item.style.borderBottom = '1px solid #eee'; + item.style.cursor = 'pointer'; + + let icon = pad.is_public ? '🌍' : '🔒'; + + let favButton = ''; + const editBtn = (currentUser && pad.owner_id === currentUser.id) ? + `` + : ''; + + const isOwner = currentUser && pad.owner_id === currentUser.id; + const manageShareBtn = isOwner ? + `` + : ''; + + if(isLoggedIn){ + const action = isFavorite ? 'unfavorite' : 'favorite'; + const label = isFavorite ? '♥' : '♡'; + favButton = ``; + } + + const deleteBtn = isOwner ? + `` + : ''; + + const shareToken = pad.share_token || ''; + const shareBtn = ``; + + item.innerHTML = ` +
+
${icon} ${escapeHtml(pad.name)}
+
+ ${editBtn} ${manageShareBtn} ${shareBtn} ${favButton} + ${deleteBtn} +
+
${pad.note_count || 0} notes
+
+ `; + + item.addEventListener('click', () => loadNotesForPad(pad.id, pad.name, pad.is_public, pad.owner_id, false, null, pad.can_write)); + container.appendChild(item); + }); +} + +let currentMarkers = []; +let topZIndex = 1000000; + +async function toggleFavorite(padId, action) { + try { + const res = await fetch(`/api/notepads/${padId}/${action}`, { method: 'POST' }); + if (res.ok) { + // Refresh the lists + loadNotepadsOfType('favorites', 'favorite-notepads-list'); + loadNotepadsOfType('mine', 'my-notepads-list'); + loadNotepadsOfType('public', 'public-notepads-list'); + + } else { + alert(`Failed to ${action} notepad`); + } + } catch (err) { + console.error(err); + } +} + +async function loadNotepadsOfType(type, containerId) { + try { + const res = await fetch(`/api/notepads?type=${type}`); + const notepads = await res.json(); + const isFavorite = type === 'favorites'; + renderNotepadList(notepads, containerId, isFavorite); + } catch (err) { + console.error(`Failed to load ${type} notepads`, err); + document.getElementById(containerId).innerHTML = '

Error loading data.

'; + } +} +async function loadNotesForPad(padId, padName, isPublic, ownerId, centerOnFirst = false, token = null, canWrite = undefined) { + activePadId = padId; + + // If metadata is missing (e.g. from URL share), fetch it + if (padName === undefined) { + try { + const res = await fetch(`/api/notepads/${padId}?token=${token || ''}`); + const pad = await res.json(); + padName = pad.name; isPublic = pad.is_public; ownerId = pad.owner_id; activePadCanWrite = pad.can_write; + } catch(e) { console.error(e); activePadCanWrite = false; } + } + + if (padName !== undefined) activePadName = padName; + if (isPublic !== undefined) activePadIsPublic = isPublic; + if (ownerId !== undefined) activePadOwnerId = ownerId; + + if (canWrite !== undefined) { + activePadCanWrite = canWrite; + } else if (padName !== undefined) { + // Fallback if not passed: assume true only if owner + activePadCanWrite = (currentUser && ownerId === currentUser.id); + } + + const currentName = activePadName; + const isOwner = currentUser && activePadOwnerId === currentUser.id; + + // Clear existing markers + currentMarkers.forEach(marker => map.removeLayer(marker)); + currentMarkers = []; + activeNotes = []; + + // Update Sidebar Header + const header = document.querySelector('.sidebar-header'); + if (header) { + const addNoteBtn = activePadCanWrite ? `` : ''; + const manageShareBtn = isOwner ? `` : ''; + const exportBtn = ``; + header.innerHTML = ` +
+ +

${escapeHtml(currentName)}

+ + ${manageShareBtn} + ${exportBtn} +
+ ${addNoteBtn} + `; + document.getElementById('btn-back-pads').addEventListener('click', loadNotepads); + } + + const sidebarBody = document.getElementById('sidebar-body'); + sidebarBody.innerHTML = '

Loading notes...

'; + + try { + const res = await fetch(`/api/notepads/${padId}/notes?token=${token || ''}`); + const notes = await res.json(); + activeNotes = notes; + + // Render Sidebar List + sidebarBody.innerHTML = ''; + if (notes.length === 0) { + sidebarBody.innerHTML = '

No notes yet.

'; + } + + notes.forEach(note => { + const item = document.createElement('div'); + item.className = 'sidebar-note-item'; + + let actionBtns = ''; + if (activePadCanWrite) { + const escapedTitle = escapeHtml(note.title).replace(/'/g, "\\'").replace(/"/g, '"'); + const escapedContent = escapeHtml(note.content).replace(/'/g, "\\'").replace(/"/g, '"').replace(/\n/g, '\\n'); + actionBtns = ` + + + `; + } else if (activePadIsPublic) { + actionBtns = ``; + } + + const dateStr = new Date(note.created_at).toLocaleString(); + + item.innerHTML = ` +
${escapeHtml(note.title)}
+
${escapeHtml(note.content)}
+
+ ${dateStr}
${note.lat.toFixed(5)}, ${note.lng.toFixed(5)} +
+
${actionBtns}
+ `; + item.addEventListener('click', () => { + stopTracking(); + map.setView([note.lat, note.lng], 16); + }); + sidebarBody.appendChild(item); + }); + + renderMapMarkers(); + + if (centerOnFirst && notes.length > 0) { + map.setView([notes[0].lat, notes[0].lng], 13); + } + + } catch (err) { + console.error(err); + sidebarBody.innerHTML = '

Error loading notes.

'; + } +} + +async function loadSingleNote(noteId, token = null) { + // Reset state + activeNotes = []; + currentMarkers.forEach(marker => map.removeLayer(marker)); + currentMarkers = []; + activePadId = null; + + const sidebarBody = document.getElementById('sidebar-body'); + sidebarBody.innerHTML = '

Loading note...

'; + + try { + const res = await fetch(`/api/notes/${noteId}?token=${token || ''}`); + if (!res.ok) throw new Error("Note not found or private"); + const note = await res.json(); + + // Set active notes to just this one so renderMapMarkers works + activeNotes = [note]; + + // Update Header + const header = document.querySelector('.sidebar-header'); + if (header) { + header.innerHTML = ` +
+ +

Shared Note

+
+ `; + document.getElementById('btn-back-pads').addEventListener('click', loadNotepads); + } + + sidebarBody.innerHTML = ''; + const noteInfoDiv = document.createElement('div'); + noteInfoDiv.style.padding = '10px'; + + const p = document.createElement('p'); + p.appendChild(document.createTextNode('Viewing single note from ')); + + if (note.notepad.is_public) { + const link = document.createElement('a'); + link.href = "#"; + link.textContent = note.notepad.name; + link.style.fontWeight = 'bold'; + link.onclick = (e) => { + e.preventDefault(); + loadNotesForPad(note.notepad.id, note.notepad.name, true, note.owner_id, false, null, note.notepad.can_write); + }; + p.appendChild(link); + } else { + const strong = document.createElement('strong'); + strong.textContent = note.notepad.name; + p.appendChild(strong); + } + p.appendChild(document.createTextNode('.')); + noteInfoDiv.appendChild(p); + sidebarBody.appendChild(noteInfoDiv); + + renderMapMarkers(); + map.setView([note.lat, note.lng], 16); + + if (window.innerWidth <= 600) { + const sidebar = document.getElementById('sidebar'); + const toggleBtn = document.getElementById('sidebar-toggle'); + if (sidebar && !sidebar.classList.contains('collapsed')) { + sidebar.classList.add('collapsed'); + if (toggleBtn) toggleBtn.innerHTML = '<'; + } + } + + } catch (err) { + sidebarBody.innerHTML = '

Failed to load note. It may be private or deleted.

'; + } +} + +function renderMapMarkers() { + // Clear existing + currentMarkers.forEach(marker => map.removeLayer(marker)); + currentMarkers = []; + + const zoom = map.getZoom(); + const showFull = zoom >= 14; // Zoom threshold + + activeNotes.forEach(note => { + let marker; + let actionBtns = ''; + + // Determine permissions: Use note-specific info if available (search results), else fall back to pad globals + const isOwner = currentUser && (note.owner_id ? note.owner_id === currentUser.id : activePadOwnerId === currentUser.id); + const isPublic = note.is_public !== undefined ? note.is_public : activePadIsPublic; + const canWrite = (note.notepad && note.notepad.can_write !== undefined) ? note.notepad.can_write : activePadCanWrite; + + if (canWrite) { + const escapedTitle = escapeHtml(note.title).replace(/'/g, "\\'").replace(/"/g, '"'); + const escapedContent = escapeHtml(note.content).replace(/'/g, "\\'").replace(/"/g, '"').replace(/\n/g, '\\n'); + actionBtns = `
`; + } else if (isPublic) { + actionBtns = `
`; + } + + const shareToken = note.share_token || ''; + const shareBtn = ``; + + const dateStr = new Date(note.created_at).toLocaleString(); + + + + if (showFull) { + const icon = L.divIcon({ + className: '', + html: `
+
${escapeHtml(note.title)}
+
${escapeHtml(note.content)}
+
${dateStr}
+ ${shareBtn} ${actionBtns} +
`, + iconSize: [200, 'auto'], + iconAnchor: [100, 0] + }); + marker = L.marker([note.lat, note.lng], { icon: icon }).addTo(map); + } else { + marker = L.marker([note.lat, note.lng]).addTo(map); + marker.bindPopup(`${escapeHtml(note.title)}
${escapeHtml(note.content)}
${dateStr}
${shareBtn} ${actionBtns}`); + } + const bumpZIndex = function() { + this.setZIndexOffset(topZIndex++); + }; + marker.on('click', bumpZIndex); + marker.on('mousedown', bumpZIndex); + + currentMarkers.push(marker); + }); +} + +window.displaySearchResults = function(notes, location, query) { + // Reset Pad State to "Search Mode" + activePadId = null; + activePadName = `Search: ${query}`; + activePadIsPublic = false; // Mixed results + activePadOwnerId = null; // Mixed results + activeNotes = notes; + + // Update Sidebar Header + const header = document.querySelector('.sidebar-header'); + if (header) { + header.innerHTML = ` +
+ +

Results: ${escapeHtml(query)}

+
+ `; + document.getElementById('btn-back-pads').addEventListener('click', loadNotepads); + } + + const sidebarBody = document.getElementById('sidebar-body'); + sidebarBody.innerHTML = ''; + + if (notes.length === 0 && !location) { + sidebarBody.innerHTML = '

No results found.

'; + renderMapMarkers(); + return; + } else if (notes.length === 0 && location) { + sidebarBody.innerHTML = '

Location found on map.

'; + renderMapMarkers(); + map.setView([location.lat, location.lng], 13); + return; + } + + // Group notes by section and notepad + const sections = { + favorites: {}, // Map + mine: {}, + public: {} + }; + + notes.forEach(note => { + const pad = note.notepad; + + // Helper to add to a section + const addToSection = (secKey) => { + if (!sections[secKey][pad.id]) { + sections[secKey][pad.id] = { pad: pad, notes: [] }; + } + sections[secKey][pad.id].notes.push(note); + }; + + if (pad.is_favorite) addToSection('favorites'); + if (currentUser && pad.owner_id === currentUser.id) addToSection('mine'); + if (pad.is_public) addToSection('public'); + }); + + // Helper function to render a collapsible section + const renderSection = (title, dataMap, isOpen) => { + const sectionDiv = document.createElement('div'); + sectionDiv.className = 'list-section'; + + const arrow = isOpen ? '▾' : '▸'; + const display = isOpen ? 'block' : 'none'; + + const headerBtn = document.createElement('button'); + headerBtn.className = 'list-section-header'; + headerBtn.innerHTML = `${title} ${arrow}`; + headerBtn.onclick = toggleSection; + + const contentDiv = document.createElement('div'); + contentDiv.className = 'list-section-content'; + contentDiv.style.display = display; + + const padIds = Object.keys(dataMap); + if (padIds.length === 0) { + contentDiv.innerHTML = '

No matching notes.

'; + } else { + padIds.forEach(padId => { + const entry = dataMap[padId]; + const pad = entry.pad; + + // Notepad Header, styled like the default view + const padItem = document.createElement('div'); + padItem.className = 'notepad-item'; + padItem.style.backgroundColor = '#e9ecef'; // Differentiate as a sub-header + padItem.style.cursor = 'default'; + + let icon = pad.is_public ? '🌍' : '🔒'; + let favButton = ''; + if(isLoggedIn){ + const isFavorite = pad.is_favorite; + const action = isFavorite ? 'unfavorite' : 'favorite'; + const label = isFavorite ? '♥' : '♡'; + favButton = ``; + } + + padItem.innerHTML = ` +
+
${icon} ${escapeHtml(pad.name)}
+
+ ${favButton} +
+
+ `; + contentDiv.appendChild(padItem); + + entry.notes.forEach(note => { + const item = document.createElement('div'); + item.className = 'sidebar-note-item'; + const dateStr = new Date(note.created_at).toLocaleString(); + + let actionBtn = ''; // Renaming to actionBtns for consistency + if (note.notepad && note.notepad.can_write) { + const escapedTitle = escapeHtml(note.title).replace(/'/g, "\\'").replace(/"/g, '"'); + const escapedContent = escapeHtml(note.content).replace(/'/g, "\\'").replace(/"/g, '"').replace(/\n/g, '\\n'); + actionBtn = ` `; + } else if (note.is_public) { + actionBtn = ``; + } + + item.innerHTML = ` +
${escapeHtml(note.title)}
+
${escapeHtml(note.content)}
+
+ ${dateStr}
${note.lat.toFixed(5)}, ${note.lng.toFixed(5)} +
+
${actionBtn}
+ `; + item.addEventListener('click', () => { + stopTracking(); + map.setView([note.lat, note.lng], 16); + }); + contentDiv.appendChild(item); + }); + }); + } + + sectionDiv.appendChild(headerBtn); + sectionDiv.appendChild(contentDiv); + sidebarBody.appendChild(sectionDiv); + }; + + if (isLoggedIn) { + if (Object.keys(sections.favorites).length > 0) renderSection('Favorite Notepads', sections.favorites, true); + if (Object.keys(sections.mine).length > 0) renderSection('My Notepads', sections.mine, true); + if (Object.keys(sections.public).length > 0) renderSection('Public Notepads', sections.public, true); + } else { + if (Object.keys(sections.public).length > 0) renderSection('Public Notepads', sections.public, true); + } + + renderMapMarkers(); + + if (notes.length > 0) { + map.setView([notes[0].lat, notes[0].lng], 15); + } else if (location) { + map.setView([location.lat, location.lng], 13); + } +}; + +window.reportNote = async function(noteId) { + if (!confirm("Report this note? It will be hidden from public view.")) return; + + try { + const res = await fetch(`/api/notes/${noteId}/report`, { method: 'POST' }); + if (res.ok) { + alert("Note reported and hidden."); + // Refresh current pad + loadNotesForPad(activePadId, activePadName, activePadIsPublic); + } + } catch (err) { + console.error("Error reporting note:", err); + } +}; + +window.deleteNotepad = async function(padId) { + if (!confirm("Are you sure you want to delete this notepad? All notes inside will be lost.")) return; + + try { + const res = await fetch(`/api/notepads/${padId}`, { method: 'DELETE' }); + if (res.ok) { + loadNotepads(); // Refresh list + } else { + alert("Failed to delete notepad."); + } + } catch (err) { console.error(err); } +}; + +window.openShareSettingsModal = async function(padId, padName) { + const modal = document.getElementById('modal-share-settings'); + document.getElementById('share-pad-name').textContent = padName; + document.getElementById('share-pad-id').value = padId; + + const listDiv = document.getElementById('collaborators-list'); + listDiv.innerHTML = '

Loading...

'; + modal.classList.remove('hidden'); + + try { + const res = await fetch(`/api/notepads/${padId}/collaborators`); + if (!res.ok) { + const err = await res.json(); + throw new Error(err.error || 'Failed to load collaborators'); + } + const collaborators = await res.json(); + + listDiv.innerHTML = ''; + if (collaborators.length === 0) { + listDiv.innerHTML = '

No collaborators yet.

'; + } else { + collaborators.forEach(collab => { + const item = document.createElement('div'); + item.className = 'collaborator-item'; + item.innerHTML = ` + ${escapeHtml(collab.email)} (${collab.permission}) + + `; + listDiv.appendChild(item); + }); + } + } catch (err) { + listDiv.innerHTML = `

${err.message}

`; + } +} + +window.removeCollaborator = async function(padId, userId) { + if (!confirm("Are you sure you want to remove this collaborator?")) return; + + try { + const res = await fetch(`/api/notepads/${padId}/collaborators/${userId}`, { method: 'DELETE' }); + if (res.ok) { + const padName = document.getElementById('share-pad-name').textContent; + openShareSettingsModal(padId, padName); + } else { + const err = await res.json(); + alert(`Failed to remove collaborator: ${err.error}`); + } + } catch (err) { + console.error(err); + alert('An error occurred.'); + } +} + +async function loadAllMyNotes() { + activePadId = null; + activePadName = "All My Notes"; + activePadIsPublic = false; + activePadCanWrite = true; + if (currentUser) { + activePadOwnerId = currentUser.id; + } + + // Clear existing markers + currentMarkers.forEach(marker => map.removeLayer(marker)); + currentMarkers = []; + activeNotes = []; + + try { + const res = await fetch('/api/notes/mine'); + if (!res.ok) throw new Error("Failed to load"); + const notes = await res.json(); + activeNotes = notes; + + renderMapMarkers(); + + if (notes.length > 0) { + // Auto-center map bounds cleanly around all the user's notes + const bounds = L.latLngBounds(notes.map(n => [n.lat, n.lng])); + map.fitBounds(bounds, { padding: [50, 50], maxZoom: 15 }); + } + + } catch (err) { + console.error("Error loading all my notes:", err); + } +} + +window.shareNotepad = function(padId, token) { + let url = `${window.location.origin}/?pad=${padId}`; + if (token) url += `&token=${token}`; + navigator.clipboard.writeText(url).then(() => { + alert("Notepad link copied to clipboard!"); + }); +}; + +window.shareNote = function(noteId, token) { + let url = `${window.location.origin}/?note=${noteId}`; + if (token) url += `&token=${token}`; + navigator.clipboard.writeText(url).then(() => { + alert("Note link copied to clipboard!"); + }); +}; + +function stopTracking() { + isTracking = false; + updateTrackingUI(); +} + +function updateTrackingUI() { + const btn = document.getElementById('btn-center-user'); + if (btn) { + if (isTracking) { + btn.textContent = "Tracking Location..."; + btn.style.backgroundColor = "#28a745"; + } else { + btn.textContent = "Target My Location"; + btn.style.backgroundColor = ""; + } + } +} + +function escapeHtml(text) { + if (text === null || text === undefined) return ''; + return String(text) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function toggleSection(event) { + const section = event.target.closest('.list-section'); + const content = section.querySelector('.list-section-content'); + const isCollapsed = content.style.display === 'none'; + content.style.display = isCollapsed ? 'block' : 'none'; + event.target.innerHTML = isCollapsed ? event.target.innerHTML.replace('▸', '▾') : event.target.innerHTML.replace('▾', '▸'); +} + +window.deleteNote = async function(noteId) { + if (!confirm("Delete this note?")) return; + + try { + const res = await fetch(`/api/notes/${noteId}`, { method: 'DELETE' }); + if (res.ok) { + // If we are in a pad view, reload the pad. + if (activePadId) { + loadNotesForPad(activePadId); + } else { + // Otherwise (e.g., search results), the safest refresh is to return to the main list. + alert("Note deleted. Returning to notepad list."); + loadNotepads(); + } + } else { + alert("Failed to delete note."); + } + } catch (err) { console.error(err); } +}; \ No newline at end of file diff --git a/static/assets/js/nav.js b/static/assets/js/nav.js new file mode 100644 index 0000000..8484dce --- /dev/null +++ b/static/assets/js/nav.js @@ -0,0 +1,42 @@ +document.addEventListener('DOMContentLoaded', () => { + checkAuthStatus(); + initLogoutListener(); +}); + +async function checkAuthStatus() { + try { + const res = await fetch('/auth/me'); + const data = await res.json(); + updateAuthUI(data.authenticated); + } catch (err) { + console.error("Auth check failed", err); + } +} + +function initLogoutListener() { + const logoutLink = document.getElementById('link-logout'); + if (logoutLink) { + logoutLink.addEventListener('click', async (e) => { + e.preventDefault(); + try { + await fetch('/auth/logout', { method: 'POST' }); + window.location.reload(); + } catch (err) { + console.error("Logout failed", err); + } + }); + } +} + +function updateAuthUI(isLoggedIn) { + const loginLink = document.getElementById('link-login'); + const logoutLink = document.getElementById('link-logout'); + + if (isLoggedIn) { + if (loginLink) loginLink.style.display = 'none'; + if (logoutLink) logoutLink.style.display = 'inline'; + } else { + if (loginLink) loginLink.style.display = 'inline'; + if (logoutLink) logoutLink.style.display = 'none'; + } +} \ No newline at end of file diff --git a/static/assets/js/search.js b/static/assets/js/search.js new file mode 100644 index 0000000..caadbf0 --- /dev/null +++ b/static/assets/js/search.js @@ -0,0 +1,59 @@ +document.addEventListener('DOMContentLoaded', () => { + const searchInput = document.getElementById('search-input'); + const searchForm = document.getElementById('search-form'); + + if (searchInput && searchForm) { + const performSearch = async (e) => { + if (e) e.preventDefault(); + const query = searchInput.value.trim(); + if (!query) return; + + // Show loading state if possible, or just proceed + + // 1. Search Notes (Backend) + let notes = []; + try { + const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`); + if (res.ok) { + notes = await res.json(); + } else { + console.error("Search API failed:", res.status); + } + } catch (e) { + console.error("Search error:", e); + } + + // If notes found, display them and stop (don't geocode) + if (notes.length > 0) { + if (window.displaySearchResults) { + window.displaySearchResults(notes, null, query); + } + return; + } + + // 2. Fallback: Search Location (Nominatim) if no notes found + let location = null; + try { + // Use local proxy to avoid CORS and set User-Agent + const nomRes = await fetch(`/api/geocode?q=${encodeURIComponent(query)}`); + const nomData = await nomRes.json(); + if (nomData && nomData.length > 0) { + location = { + lat: parseFloat(nomData[0].lat), + lng: parseFloat(nomData[0].lon) + }; + } + } catch (e) { + console.error("Geocoding error:", e); + } + + // 3. Update UI via index.js helper + if (window.displaySearchResults) { + window.displaySearchResults(notes, location, query); + } + }; + + // Handle Enter key on input & Search Button click + searchForm.addEventListener('submit', performSearch); + } +}); diff --git a/static/contact.html b/static/contact.html new file mode 100644 index 0000000..6d58802 --- /dev/null +++ b/static/contact.html @@ -0,0 +1,38 @@ + + + + + + Contact - SpotNotes + + + + + + + + +
+ SpotNotes.app + +

Contact

+

+ benjimanmiller@gmail.com +

+ +
+ + + \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a69f4e43365046e42be8a1cbd9200347b82ca773 GIT binary patch literal 3692 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 KMNUMnLSTXe + + + + + SpotNotes.app - Location Based Notes + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/login.html b/static/login.html new file mode 100644 index 0000000..bf5a0cc --- /dev/null +++ b/static/login.html @@ -0,0 +1,47 @@ + + + + + + Login - SpotNotes.app + + + + + + + + +
+ SpotNotes.app + +

Login

+
+
+ + +
+
+ + +
+ +
+ +
+ + + \ No newline at end of file diff --git a/static/register.html b/static/register.html new file mode 100644 index 0000000..69e30d5 --- /dev/null +++ b/static/register.html @@ -0,0 +1,55 @@ + + + + + + Register - SpotNotes.app + + + + + + + + +
+ SpotNotes.app + +

Create Account

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + + \ No newline at end of file