diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..66a926dc --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +ignore = E501, E203, W503 +exclude = conreq/templates/* diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2b11280c..e3fc4d7c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ +--- # These are supported funding model platforms github: [Archmonger] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 0526f6fb..f16766b7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,3 +1,4 @@ +--- name: Bug Report description: Report a bug with Conreq software. labels: [Bug] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 01ea9039..dd57a344 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,3 +1,4 @@ +--- blank_issues_enabled: false contact_links: - name: Feature Request diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4ec2cedb..5d90f114 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,8 +1,9 @@ +--- version: 2 updates: - - package-ecosystem: "pip" - directory: "/requirements/" + - package-ecosystem: pip + directory: /requirements/ schedule: - interval: "daily" - target-branch: "develop" + interval: daily + target-branch: develop open-pull-requests-limit: 20 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a401dccf..0093a8f8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,3 +1,4 @@ +--- # For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # @@ -10,7 +11,7 @@ # supported CodeQL languages. # ******** NOTE ******** -name: "CodeQL" +name: CodeQL on: push: @@ -19,7 +20,7 @@ on: # The branches below must be a subset of the branches above branches: [main, develop] schedule: - - cron: "34 16 * * 3" + - cron: 34 16 * * 3 jobs: analyze: @@ -29,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - language: ["javascript", "python"] + language: [javascript, python] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more... # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index b59e43d7..22460c93 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -1,3 +1,4 @@ +--- name: Django Tests on: @@ -12,12 +13,12 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.9] + python-version: ["3.10"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install Dependencies diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml new file mode 100644 index 00000000..7e5a9d60 --- /dev/null +++ b/.github/workflows/test-docs.yml @@ -0,0 +1,23 @@ +--- +name: Test + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + schedule: + - cron: "0 0 * * *" + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: pip install -r requirements/docs.txt + - run: mkdocs build --verbose diff --git a/.gitignore b/.gitignore index fb8811b1..d7a8bce4 100644 --- a/.gitignore +++ b/.gitignore @@ -82,13 +82,11 @@ celerybeat-schedule.* *.sage.py # Environments -.env/ -.venv/ -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ +.env*/ +.venv*/ +env*/ +venv*/ +ENV*/ # mypy .mypy_cache/ @@ -111,11 +109,11 @@ Control.system-ca-bundle GitHub.sublime-settings # Visual Studio Code # -.vscode/* +.vscode/*/ !.vscode/settings.json !.vscode/extensions.json .history/ %SystemDrive% # Mac file system -.DS_Store/ \ No newline at end of file +.DS_Store/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e6f150c..12340355 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,82 @@ +--- repos: + - repo: https://github.com/hadialqattan/pycln + rev: "v2.1.3" + hooks: + - id: pycln + args: [--all] + - repo: https://github.com/asottile/yesqa + rev: "v1.4.0" + hooks: + - id: yesqa + - repo: https://github.com/pycqa/isort + rev: "5.12.0" + hooks: + - id: isort + args: [--profile, black] + - repo: https://github.com/psf/black + rev: "23.1.0" + hooks: + - id: black - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.3.0" + rev: "v4.4.0" hooks: - id: check-merge-conflict + - id: end-of-file-fixer + exclude: >- + ^docs/[^/]*\.svg$ + + + - id: requirements-txt-fixer + - id: trailing-whitespace + types: [python] + - id: file-contents-sorter + files: | + CONTRIBUTORS.txt| + docs/spelling_wordlist.txt| + .gitignore| + .gitattributes + - id: check-case-conflict + - id: check-json + - id: check-xml + - id: check-toml + - id: check-xml + - id: debug-statements + - id: check-added-large-files + - id: check-symlinks + - id: debug-statements + - id: detect-aws-credentials + args: [--allow-missing-credentials] + - id: detect-private-key + exclude: ^examples|(?:tests/ssl)/ + - repo: https://github.com/asottile/pyupgrade + rev: "v3.3.1" + hooks: + - id: pyupgrade + args: [--py310-plus] + - repo: https://github.com/PyCQA/flake8 + rev: "6.0.0" + hooks: + - id: flake8 + - repo: https://github.com/Lucas-C/pre-commit-hooks-markup + rev: "v1.0.1" + hooks: + - id: rst-linter + files: >- + ^[^/]+[.]rst$ + + + - repo: https://github.com/adrienverge/yamllint + rev: "v1.29.0" + hooks: + - id: yamllint + - repo: https://github.com/thibaudcolas/curlylint + rev: "v0.13.1" + hooks: + - id: curlylint + args: ["conreq/"] + - repo: https://github.com/adamchainz/django-upgrade + rev: "1.12.0" + hooks: + - id: django-upgrade + args: [--target-version, "4.1"] diff --git a/.pylintrc b/.pylintrc index b334c13c..0a786400 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,7 +1,7 @@ [MASTER] ignore=migrations -disable=broad-except, fixme -load-plugins=pylint_django -django-settings-module=conreq.settings +disable=broad-except, fixme, missing-module-docstring, missing-class-docstring, missing-function-docstring [FORMAT] -max-line-length=150 \ No newline at end of file +max-line-length=150 +[TYPECHECK] +generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id diff --git a/.sourcery.yaml b/.sourcery.yaml new file mode 100644 index 00000000..0778aa5a --- /dev/null +++ b/.sourcery.yaml @@ -0,0 +1,2 @@ +refactor: + skip: [use-named-expression] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 5599cba8..f1f0b806 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,12 +3,14 @@ "irongeek.vscode-env", "eamodio.gitlens", "github.vscode-pull-request-github", - "knisterpeter.vscode-github", "wholroyd.jinja", "esbenp.prettier-vscode", "ms-python.vscode-pylance", "ms-python.python", "mrmlnc.vscode-autoprefixer", - "gruntfuggly.todo-tree" + "gruntfuggly.todo-tree", + "sourcery.sourcery", + "njpwerner.autodocstring", + "github.copilot" ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 31a9be25..064f06aa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,23 +1,27 @@ { "editor.detectIndentation": false, "editor.formatOnSave": true, - "python.linting.pylintEnabled": true, - "python.linting.pylintUseMinimalCheckers": false, - "python.linting.pylintArgs": [], - "python.languageServer": "Pylance", "python.analysis.typeCheckingMode": "off", - "python.formatting.provider": "black", - "python.sortImports.args": [ - "--src=${workspaceFolder}" + "python.languageServer": "Pylance", + "python.analysis.extraPaths": [ + "data/packages/__installed__", + "data/packages/develop" + ], + "todo-tree.filtering.excludeGlobs": [ + "**/node_modules", + ".venv", + "docs" ], - "terminal.integrated.scrollback": 20000, + "terminal.integrated.scrollback": 10000, "git.autofetch": true, "prettier.tabWidth": 4, "prettier.useTabs": true, "prettier.endOfLine": "auto", + "prettier.proseWrap": "never", "autoprefixer.formatOnSave": true, "files.associations": { "**/requirements/*.txt": "pip-requirements", + "*.py-tpl": "python" }, "[jsonc]": { "editor.defaultFormatter": "vscode.json-language-features" @@ -32,6 +36,10 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[python]": { - "editor.defaultFormatter": "ms-python.python" + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + } }, -} \ No newline at end of file + "files.insertFinalNewline": true +} diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 00000000..64bcf90c --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,6 @@ +--- +extends: default + +rules: + line-length: disable + comments: disable diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..936c4a24 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project will be documented in this file. + + + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + + + + + +## [Unreleased] + +- Nothing (Yet) + +## [0.100.0] - 2021-08-18 + +### Added + +- App store support + +[unreleased]: https://github.com/Archmonger/Conreq/compare/0.100.0...HEAD +[0.100.0]: https://github.com/Archmonger/Conreq/releases/tag/0.100.0 + + diff --git a/README.md b/README.md index dae4afb8..6f9907b4 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,59 @@ -# Conreq Beta +# Conreq Core -[![Docker Pulls](https://img.shields.io/docker/pulls/roxedus/conreq?style=flat-square)](https://hub.docker.com/r/roxedus/conreq) -[![Docker Stars](https://img.shields.io/docker/stars/roxedus/conreq?style=flat-square)](https://hub.docker.com/r/roxedus/conreq) -[![Docker Hub](https://img.shields.io/badge/Open%20On-DockerHub-blue?style=flat-square)](https://hub.docker.com/r/roxedus/conreq) -[![Discord](https://img.shields.io/discord/440067432552595457?style=flat-square&label=Discord&logo=discord)](https://discord.gg/gQhGZzEjmX "Chat with the community and get realtime support!") +[![Discord](https://img.shields.io/discord/440067432552595457?style=flat-square&label=Discord&logo=discord)](https://discord.gg/gQhGZzEjmX) [![GitHub Discussions](https://img.shields.io/badge/-View-purple?style=flat-square&label=GitHub%20Discussions&logo=github)](https://github.com/Archmonger/Conreq/discussions) [![Reddit](https://img.shields.io/badge/-View-red?style=flat-square&label=Reddit&logo=reddit)](https://www.reddit.com/r/conreq) [![Selfhosters Docker Pulls](https://img.shields.io/docker/pulls/roxedus/conreq?style=flat-square)](https://hub.docker.com/r/roxedus/conreq) [![Selfhosters Docker Stars](https://img.shields.io/docker/stars/roxedus/conreq?style=flat-square)](https://hub.docker.com/r/roxedus/conreq) -Conreq, a content requesting platform. +Conreq bundles together the best open source technologies to create a web development platform. Key features include a full-stack framework (ReactJS in Python), deployment ready web server, database ORM, and background task queue. Creations made by developers can be shared with others through our app store. -Want to join the community or have a question? Join us on [Discord](https://discord.gg/gQhGZzEjmX), discuss on [GitHub Discussions](https://github.com/Archmonger/Conreq/discussions), or see our planned features and roadmap on [GitHub Projects](https://github.com/Archmonger/Conreq/projects)! +Designed as a passion project to push the limits of web development in cross-platform **pure Python**. -Looking for more info? Are you a developer and want to contribute? Check out our [Documentation](https://archmonger.github.io/Conreq/)! +View the **[Core Roadmap](https://github.com/Archmonger/Conreq/projects)** to see what features are upcoming, or the **[App Roadmap](https://github.com/Archmonger/Conreq/projects/7)** to see what will be added to the app store. -## Installation (Production Environment) +Or, check out the **[documentation](https://archmonger.github.io/Conreq/)** for info on how to develop with Conreq! -Install through **[Unraid Community Applications](https://squidly271.github.io/forumpost0.html)**, or **[Hotio](https://hotio.dev/containers/conreq/)**/**[SelfHosters](https://registry.hub.docker.com/r/roxedus/conreq) Docker**. +## Features -Here's a list of all available environment variables: +- Installable Apps +- Behaves as a Progressive Web App (PWA) +- Customizable Core Webpages (Landing, Home, Sign In, Sign Up, Password Reset) +- Graphical Database Administration +- MySQL and SQLite Databases +- Automatic Multi-Database Routing +- Customizable Base URL +- [Interactive HTML via ReactPy](https://github.com/reactive-python/reactpy) +- [Support for Django Features](https://github.com/django/django) +- [Background Task Processing](https://github.com/coleifer/huey) +- [Async and Websockets (ASGI)](https://github.com/django/channels) +- [REST API Framework](https://github.com/encode/django-rest-framework) +- [Static File Server](https://github.com/evansd/whitenoise) +- [Media File Server](https://github.com/jazzband/django-downloadview) +- [Database Field Encryption](https://gitlab.com/guywillett/django-searchable-encrypted-fields) +- [High Performance Webserver](https://github.com/pgjones/hypercorn) +- [High Performance Caching](https://github.com/grantjenks/python-diskcache) +- [Automatic CSS/JS File Compression](https://github.com/django-compressor/django-compressor) +- [Automatic HTTP Compression](https://github.com/friedelwolff/django-compression-middleware) +- [Automatic Cache Busting](https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage) +- [Automatic Code Performance Graphs](https://github.com/jazzband/django-silk) +- [Automatic API Docs Generation](https://github.com/tfranzel/drf-spectacular) +- [Automatic SQLite Database Optimization](https://www.sqlite.org/lang_vacuum.html) +- [Automatic Database Backups](https://github.com/django-dbbackup/django-dbbackup) +- [Automatic Health Checks](https://github.com/KristianOellegaard/django-health-check) -```nginx -# General Settings -TZ = America/Los_Angeles # default: UTC (Timezone for log files, in "TZ Database" format) -BASE_URL = requests # default: None -APP_NAME = RequestCentral # default: Conreq -APP_DESCRIPTION = Get yo stuff! # default: Content Requesting -ARR_REFRESH_INTERNAL = */15 # default: */1 (Cron minutes for Sonarr/Radarr library refresh) -LOG_LEVEL = ERROR # default: WARNING -CONREQ_ENV_PREFIX = CONREQ # default: None +## Coming Soon -# Data Storage -DATA_DIR = /example/directory # default: /config (Defaults to "data" outside of docker) -DB_ENGINE = MYSQL # default: SQLITE3 -MYSQL_CONFIG_FILE = /config/mysql.cnf # default: None +- Support for MariaDB, Oracle, and PostgreSQL +- [Automatic SASS/SCSS to CSS Compilation](https://github.com/jrief/django-sass-processor) +- [Automatic NPM Package Installation](https://github.com/kevin1024/django-npm) -# Security -SSL_SECURITY = True # default: False (True enables advanced SSL security features) -PWNED_VALIDATOR = False # default: True (False disables checking for compromised passwords) -X_FRAME_OPTIONS = SAMEORIGIN # default: DENY (False disables X-Frame-Options) -ALLOWED_HOST = 192.168.0.199 # default: * (Comma separated list. Asterisk allows all hosts.) -TRUSTED_ORIGINS = https://*.example.com # default: None (Comma separated list. Required to be set if using https.) -DEBUG = True # default: False (Only enable this during development or testing.) +## Communities -# Email (Required for password reset features) -EMAIL_USE_TLS = False # default: True -EMAIL_PORT = 587 # default: None -EMAIL_HOST = smtp.gmail.com # default: None -EMAIL_HOST_USER = myself@gmail.com # default: None -EMAIL_HOST_PASSWORD = dogmemes123 # default: None -``` +- [Discord](https://discord.gg/gQhGZzEjmX) +- [Reddit](https://www.reddit.com/r/conreq/) +- [GitHub Discussions](https://github.com/Archmonger/Conreq/discussions) -# Screenshots +## Installation -| ![Login screen](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_discover.png?raw=true) | ![Discover tab](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_more_info.png?raw=true) | -| :------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | -| Discover (Desktop) | More Info (Desktop) | +Install through **[Unraid Community Applications](https://squidly271.github.io/forumpost0.html)**, or manually through **[Hotio](https://hotio.dev/containers/conreq/) or [SelfHosters](https://registry.hub.docker.com/r/roxedus/conreq)** Docker. -| ![More Info Tab](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_modal_episode_selection.png?raw=true) | ![Content Preview Modal](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_modal_filter.png?raw=true) | -| :----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------: | -| Episode Selection Modal (Desktop) | Filter Modal (Desktop) | +See our docs for information on our **[environment variables](https://archmonger.github.io/Conreq/configure/env_vars/)**. -| ![Discover Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_modal_preview.png?raw=true) | ![More Info Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/desktop_sign_in.png?raw=true) | -| :------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | -| Preview Modal (Desktop) | Sign In (Desktop) | - -| ![Discover Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_discover.png?raw=true) | ![More Info Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_more_info.png?raw=true) | -| :------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------: | -| Discover (Mobile) | More Info (Mobile) | - -| ![Discover Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_modal_episode_selection.png?raw=true) | ![More Info Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_modal_filter.png?raw=true) | -| :---------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------: | -| Episode Selection Modal (Mobile) | Filter Modal (Mobile) | - -| ![Discover Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_registration.png?raw=true) | ![More Info Tab Mobile](https://github.com/Archmonger/Conreq/blob/main/misc/screenshots/mobile_sign_in.png?raw=true) | -| :----------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------: | -| Registration (Mobile) | Sign In (Mobile) | +Since Conreq is pure python, it can be **[manually run](https://archmonger.github.io/Conreq/develop/run_conreq/)** on any operating system. diff --git a/conreq/__init__.py b/conreq/__init__.py index e69de29b..16f53608 100644 --- a/conreq/__init__.py +++ b/conreq/__init__.py @@ -0,0 +1,3 @@ +from conreq import app, config, utils + +__all__ = ["app", "config", "utils"] diff --git a/conreq/app_template/app_name/__init__.py b/conreq/_core/__init__.py similarity index 100% rename from conreq/app_template/app_name/__init__.py rename to conreq/_core/__init__.py diff --git a/conreq/app_template/app_name/main/__init__.py b/conreq/_core/api/__init__.py similarity index 100% rename from conreq/app_template/app_name/main/__init__.py rename to conreq/_core/api/__init__.py diff --git a/conreq/core/api/admin.py b/conreq/_core/api/admin.py similarity index 100% rename from conreq/core/api/admin.py rename to conreq/_core/api/admin.py diff --git a/conreq/_core/api/apps.py b/conreq/_core/api/apps.py new file mode 100644 index 00000000..5e51f635 --- /dev/null +++ b/conreq/_core/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "conreq._core.api" diff --git a/conreq/_core/api/authentication.py b/conreq/_core/api/authentication.py new file mode 100644 index 00000000..1edb4ab7 --- /dev/null +++ b/conreq/_core/api/authentication.py @@ -0,0 +1,6 @@ +from rest_framework.authentication import SessionAuthentication + + +class CsrfExemptSessionAuthentication(SessionAuthentication): + def enforce_csrf(self, request): + return diff --git a/conreq/app_template/app_name/main/migrations/__init__.py b/conreq/_core/api/migrations/__init__.py similarity index 100% rename from conreq/app_template/app_name/main/migrations/__init__.py rename to conreq/_core/api/migrations/__init__.py diff --git a/conreq/_core/api/models.py b/conreq/_core/api/models.py new file mode 100644 index 00000000..e737a510 --- /dev/null +++ b/conreq/_core/api/models.py @@ -0,0 +1,13 @@ +from django.contrib.auth import get_user_model +from django.db.models.signals import post_save +from django.dispatch import receiver +from rest_framework.authtoken.models import Token + + +@receiver(post_save, sender=get_user_model()) +def create_auth_token( + sender, instance=None, created=False, **kwargs +): # pylint: disable=unused-argument + # Create an API AuthToken if it doesn't exist + if not hasattr(instance, "auth_token"): + Token.objects.create(user=instance) diff --git a/conreq/_core/api/permissions.py b/conreq/_core/api/permissions.py new file mode 100644 index 00000000..7b09b0fc --- /dev/null +++ b/conreq/_core/api/permissions.py @@ -0,0 +1,14 @@ +import typing + +from django.http import HttpRequest +from rest_framework_api_key.models import APIKey +from rest_framework_api_key.permissions import BaseHasAPIKey, KeyParser + + +class HasAPIKey(BaseHasAPIKey): + model = APIKey + key_parser = KeyParser() + + def get_key(self, request: HttpRequest) -> typing.Optional[str]: + # Prefer key in header, fallback to URL parameters. + return self.key_parser.get(request) or request.GET.get("apikey") diff --git a/conreq/_core/api/serializers.py b/conreq/_core/api/serializers.py new file mode 100644 index 00000000..57e9bd33 --- /dev/null +++ b/conreq/_core/api/serializers.py @@ -0,0 +1,23 @@ +from django.contrib.auth import get_user_model +from rest_framework import serializers + + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = get_user_model() + fields = [ + "id", + "last_login", + "is_superuser", + "username", + "first_name", + "last_name", + "email", + "is_staff", + "is_active", + "date_joined", + "groups", + "user_permissions", + "profile", + "auth_token", + ] diff --git a/conreq/_core/api/urls.py b/conreq/_core/api/urls.py new file mode 100644 index 00000000..f3a8588f --- /dev/null +++ b/conreq/_core/api/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +from rest_framework.authtoken import views + +urlpatterns = [ + path("v1/user-token/", views.obtain_auth_token, name="user-token"), +] diff --git a/conreq/_core/api/views.py b/conreq/_core/api/views.py new file mode 100644 index 00000000..63ec916d --- /dev/null +++ b/conreq/_core/api/views.py @@ -0,0 +1,22 @@ +from django.contrib.auth import authenticate, login +from rest_framework.response import Response +from rest_framework.views import APIView + +from conreq._core.api.serializers import UserSerializer + + +# TODO: Create some API views. +class LocalAuthentication(APIView): + """Sign in to an account.""" + + def post(self, request): + """Authenticate a session using a `username` and `password`. + Requires CSRF tokens on all further insecure requests (POST, PUT, DELETE, PATCH). + """ + username = request.data.get("username") + password = request.data.get("password") + user = authenticate(request, username=username, password=password) + if user is not None: + login(request, user) + return Response(UserSerializer(user).data) + return Response(None) diff --git a/conreq/core/__init__.py b/conreq/_core/app_loader/__init__.py similarity index 100% rename from conreq/core/__init__.py rename to conreq/_core/app_loader/__init__.py diff --git a/conreq/_core/app_loader/apps.py b/conreq/_core/app_loader/apps.py new file mode 100644 index 00000000..d5bc398d --- /dev/null +++ b/conreq/_core/app_loader/apps.py @@ -0,0 +1,36 @@ +import pkgutil +from importlib import import_module + +from django.apps import AppConfig, apps + + +class AppLoaderConfig(AppConfig): + name = "conreq._core.app_loader" + skip_module_names = { + "admin", + "apps", + "migrations", + "templatetags", + "management", + } + + def ready(self): + for app_config in apps.get_app_configs(): + self.auto_import(app_config) + + def auto_import(self, app_config: AppConfig): + """Imports all submodules for a specific app.""" + if not getattr(app_config, "auto_import", False): + return + + fail_silently = getattr(app_config, "auto_import_silent", False) + + for loader, module_name, is_pkg in pkgutil.walk_packages([app_config.path]): + try: + if module_name not in self.skip_module_names: + import_module(".".join([app_config.name, module_name])) + if is_pkg: + loader.find_module(module_name).load_module(module_name) # type: ignore + except Exception as exception: + if not fail_silently: + raise exception diff --git a/conreq/core/api/__init__.py b/conreq/_core/app_store/__init__.py similarity index 100% rename from conreq/core/api/__init__.py rename to conreq/_core/app_store/__init__.py diff --git a/conreq/_core/app_store/admin.py b/conreq/_core/app_store/admin.py new file mode 100644 index 00000000..c325092b --- /dev/null +++ b/conreq/_core/app_store/admin.py @@ -0,0 +1,143 @@ +from functools import update_wrapper +from urllib.parse import unquote + +from django.contrib import admin +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.urls import path, reverse +from django.utils.safestring import mark_safe +from ordered_model.admin import ( + BaseOrderedModelAdmin, + OrderedInlineModelAdminMixin, + OrderedTabularInline, +) + +from conreq._core.app_store import models + + +class DragDropOrderedModelAdmin(BaseOrderedModelAdmin, admin.ModelAdmin): + def get_urls(self): + def wrap(view): + def wrapper(*args, **kwargs): + return self.admin_site.admin_view(view)(*args, **kwargs) + + setattr(wrapper, "model_admin", self) + return update_wrapper(wrapper, view) + + return [ + path( + "/move-above//", + wrap(self.move_above_view), + name="{app}_{model}_order_above".format(**self._get_model_info()), + ) + ] + super().get_urls() + + def move_above_view(self, request, object_id, other_object_id): + obj = get_object_or_404(self.model, pk=unquote(object_id)) + other_obj = get_object_or_404(self.model, pk=unquote(other_object_id)) + obj.above(other_obj) + # go back 3 levels (to get from /pk/move-above/other-pk back to the changelist) + return HttpResponseRedirect("../../../") + + def make_draggable(self, obj): + model_info = self._get_model_info() + url = reverse( + "{admin_name}:{app}_{model}_order_above".format( + admin_name=self.admin_site.name, **model_info + ), + args=[-1, 0], # placeholder pks, will be replaced in js + ) + return mark_safe( + r""" +
+ + + """ + % (obj.pk, url) + ) + + setattr(make_draggable, "allow_tags", True) + setattr(make_draggable, "short_description", "") + + +# Register your models here. +@admin.register(models.Category) +class AppCategories(OrderedInlineModelAdminMixin, DragDropOrderedModelAdmin): + model = models.Category + list_display = ("name", "order", "make_draggable") + ordering = ("order",) + + +@admin.register(models.Subcategory) +class AppSubCategories(admin.ModelAdmin): + list_display = ("name", "category") + + +class SpotlightAppPackagesTabularInline(OrderedTabularInline): + model = models.SpotlightAppPackages + readonly_fields = ( + "order", + "move_up_down_links", + ) + ordering = ("order",) + extra = 1 + + +@admin.register(models.SpotlightCategory) +class SpotlightCategories(OrderedInlineModelAdminMixin, DragDropOrderedModelAdmin): + model = models.SpotlightCategory + list_display = ("name", "order", "make_draggable") + ordering = ("order",) + inlines = (SpotlightAppPackagesTabularInline,) + + +@admin.register(models.AppPackage) +class Apps(admin.ModelAdmin): + list_display = ("name", "hidden_description") + pass + + +@admin.register(models.PyPiData) +class PyPiData(admin.ModelAdmin): + def has_add_permission(self, request, obj=None): + return False + + +@admin.register(models.Screenshot) +class Screenshots(admin.ModelAdmin): + pass + + +@admin.register(models.AppNoticeMessage) +class NoticeMessages(admin.ModelAdmin): + pass diff --git a/conreq/_core/app_store/apps.py b/conreq/_core/app_store/apps.py new file mode 100644 index 00000000..0b426cc3 --- /dev/null +++ b/conreq/_core/app_store/apps.py @@ -0,0 +1,15 @@ +from django.apps import AppConfig + +from conreq.utils.modules import load + +MODULE = __name__ +APP = MODULE[: MODULE.rfind(".")] + + +class AppStoreConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = APP + verbose_name = "App Store" + + def ready(self): + load("components") diff --git a/conreq/_core/app_store/components/__init__.py b/conreq/_core/app_store/components/__init__.py new file mode 100644 index 00000000..83318df0 --- /dev/null +++ b/conreq/_core/app_store/components/__init__.py @@ -0,0 +1,47 @@ +from copy import copy + +from reactpy import component, hooks +from reactpy_django.components import django_css +from reactpy_django.hooks import use_query + +from conreq._core.app_store.components.nav import app_store_nav +from conreq._core.app_store.components.spotlight import spotlight +from conreq._core.app_store.models import Category +from conreq.types import AppStoreState, AppStoreStateContext + + +@component +def app_store(): # sourcery skip + state, set_state = hooks.use_state(AppStoreState()) + state.set_state = lambda obj: set_state(copy(obj)) + nav_category_query = use_query(get_nav_categories) + + # Don't render if there's an error loading categories + if nav_category_query.error: + return "Error. Could not load apps!" + + # Don't render if there are no apps + if not nav_category_query.loading and not nav_category_query.data: + return "Error. No apps found!" + + # Don't render if categories are still loading + if nav_category_query.loading: + return None + + # TODO: Update app store entries every first load + return AppStoreStateContext( + django_css("conreq/app_store.css"), + app_store_nav(nav_category_query.data), + state.tab( + *state.tab_args, + *state.tab_kwargs, + key=f"{state.tab.__module__}.{state.tab.__name__}", + ) + if state.tab + else spotlight(), + value=state, + ) + + +def get_nav_categories(): + return Category.objects.all().order_by("order") diff --git a/conreq/_core/app_store/components/card.py b/conreq/_core/app_store/components/card.py new file mode 100644 index 00000000..96a4cc72 --- /dev/null +++ b/conreq/_core/app_store/components/card.py @@ -0,0 +1,147 @@ +import asyncio +import random + +from reactpy import component, hooks +from reactpy.html import a, button, div, h5 + +from conreq._core.app_store.components.event import ( + author_click_event, + details_modal_event, + subcategory_click_event, +) +from conreq._core.app_store.components.modal import package_install_modal +from conreq._core.app_store.models import AppPackage, Subcategory +from conreq.types import AppStoreStateContext, ModalState, ModalStateContext + + +@component +def card(app: AppPackage): + modal_state = hooks.use_context(ModalStateContext) + animation_speed, _ = hooks.use_state(random.randint(7, 13)) + opacity, set_opacity = hooks.use_state(0) + + @hooks.use_effect(dependencies=[]) + async def fade_in_animation(): + await asyncio.sleep(round(random.uniform(0.35, 0.75), 3)) + set_opacity(1) + + return div( + { + "class_name": "card" + + (" special" if app.special else "") + + (" fade-in" if opacity else ""), + "style": {"opacity": opacity} + | ({"--animation-speed": f"{animation_speed}s"} if app.special else {}), + }, + card_top(app, app.subcategories.all()[0]), + card_btns(app, modal_state), + div({"class_name": "description"}, app.short_description), + card_background(app), + ) + + +def card_top(app: AppPackage, subcategory: Subcategory | None): + state = hooks.use_context(AppStoreStateContext) + + return div( + {"class_name": "top"}, + div( + {"class_name": "text-region"}, + h5( + {"class_name": "card-title"}, + app.name, + ), + [ + div( + {"class_name": "card-author", "key": "author"}, + a( + {"href": "#", "on_click": author_click_event(state, app)}, + app.author, + ), + ) + ] + if app.author + else [], + [ + div( + {"class_name": "card-category", "key": "category"}, + a( + { + "href": "#", + "on_click": subcategory_click_event(state, subcategory), + }, + str(subcategory) if subcategory else "", + ), + ) + ] + if subcategory + else [], + ), + div( + {"class_name": "logo"} + | ( + {"style": {"background_image": f'url("{app.logo.url}")'}} + if app.logo + else {} + ) + ), + ) + + +def card_btns(app: AppPackage, modal_state: ModalState): + async def install_click(_): + modal_state.show = True + modal_state.modal_intent = package_install_modal + modal_state.args = [app] + modal_state.set_state(modal_state) + + return div( + {"class_name": "btn-container"}, + button( + { + "class_name": "btn btn-sm btn-dark", + "on_click": details_modal_event(modal_state, app), + }, + "Details", + ), + a( + { + "href": f"{app.contact_link}" or f"mailto:{app.contact_email}", + "class_name": "btn btn-sm btn-dark", + "key": "email", + }, + "Contact", + ) + if app.contact_link or app.contact_email + else "", + button( + { + "class_name": "btn btn-sm btn-primary", + "on_click": install_click, + "key": "install", + }, + "Install", + ) + if app.compatible and not app.installed + else button( + { + "class_name": "btn btn-sm btn-primary", + "disabled": True, + "key": "installed", + }, + "Installed", + ) + if app.installed + else "", + ) + + +def card_background(app: AppPackage): + return div( + {"class_name": "background"} + | ( + {"style": {"background_image": f'url("{app.background.url}")'}} + if app.background + else {} + ) + ) diff --git a/conreq/_core/app_store/components/event.py b/conreq/_core/app_store/components/event.py new file mode 100644 index 00000000..b8d2ab3e --- /dev/null +++ b/conreq/_core/app_store/components/event.py @@ -0,0 +1,71 @@ +from conreq._core.app_store.components.query import ( + get_author_apps, + get_category_apps, + get_subcategory_apps, +) +from conreq._core.app_store.models import AppPackage, Category, Subcategory +from conreq.types import AppStoreState, ModalState + + +def author_click_event(state: AppStoreState, app: AppPackage): + async def event(_): + # pylint: disable=import-outside-toplevel + from conreq._core.app_store.components.filtered import filtered_cards + + state.reset_tab() + state.tab = filtered_cards + state.tab_args = (await get_author_apps(app.author),) + state.set_state(state) + + return event + + +def details_modal_event(state: ModalState, app: AppPackage): + async def event(_): + # pylint: disable=import-outside-toplevel + from conreq._core.app_store.components.modal import package_details_modal + + state.show = True + state.modal_intent = package_details_modal + state.args = [app] + state.set_state(state) + + return event + + +def subcategory_click_event(state: AppStoreState, subcategory: Subcategory): + async def event(_): + # pylint: disable=import-outside-toplevel + from conreq._core.app_store.components.filtered import filtered_cards + + state.reset_tab() + state.tab = filtered_cards + state.tab_args = (await get_subcategory_apps(subcategory),) + state.set_state(state) + + return event + + +def category_click_event(state: AppStoreState, category: Category): + async def event(_): + # pylint: disable=import-outside-toplevel + from conreq._core.app_store.components.filtered import filtered_cards + + state.reset_tab() + state.tab = filtered_cards + state.tab_args = (await get_category_apps(category),) + state.set_state(state) + + return event + + +def manage_apps_click_event(state: AppStoreState): + async def event(_): + # pylint: disable=import-outside-toplevel + from conreq._core.app_store.components.manage_apps import manage_apps + + state.reset_tab() + state.tab = manage_apps + state.set_state(state) + + return event diff --git a/conreq/_core/app_store/components/filtered.py b/conreq/_core/app_store/components/filtered.py new file mode 100644 index 00000000..ba633aad --- /dev/null +++ b/conreq/_core/app_store/components/filtered.py @@ -0,0 +1,20 @@ +from typing import Iterable + +from reactpy import component +from reactpy.html import div +from reactpy_django.components import django_css + +from conreq._core.app_store.components.card import card +from conreq._core.app_store.models import AppPackage + + +@component +def filtered_cards(apps: Iterable[AppPackage]): + """Displays a list of apps as cards.""" + + return div( + {"class_name": "filtered-cards"}, + django_css("conreq/app_store_filtered.css"), + django_css("conreq/app_store_card.css"), + [card(app, key=app.uuid) for app in apps] if apps else "Nothing found!", + ) diff --git a/conreq/_core/app_store/components/manage_apps.py b/conreq/_core/app_store/components/manage_apps.py new file mode 100644 index 00000000..1dad7b42 --- /dev/null +++ b/conreq/_core/app_store/components/manage_apps.py @@ -0,0 +1,204 @@ +import subprocess +import threading +from logging import getLogger +from typing import cast + +from reactpy import component, hooks, html +from reactpy_django.components import django_css + +from conreq.utils.environment import get_env, set_env +from conreq.utils.packages import find_packages + +_logger = getLogger(__name__) + +# TODO: Need two modal abstractions. Termninal Caller Modal and Confirmation Modal + + +@component +def manage_apps(): + """Bootstrap table for managing apps.""" + + installed_packages = find_packages(show_disabled=True) + + return html.div( + {"class_name": "manage-apps"}, + django_css("conreq/manage_apps.css"), + django_css("conreq/app_store_card.css"), + django_css("conreq/table.css"), + html.table( + {"class_name": "table table-striped table-hover"}, + html.thead( + html.tr( + html.th("Name"), + html.th("Installed"), + html.th("Latest"), + html.th("Disabled"), + html.th({"style": {"text-align": "center"}}, "Actions"), + ) + ), + html.tbody([app_row(app, key=app) for app in installed_packages]), + ), + ) + + +@component +def app_row(pkg_name: str): + error_msg, set_error_msg = hooks.use_state("") + current_version, set_current_version = hooks.use_state("") + latest_version, set_latest_version = hooks.use_state("") + available_versions, set_available_versions = hooks.use_state(cast(list[str], [])) + disabled_packages, set_disabled_packages = hooks.use_state( + sorted(set(get_env("DISABLED_PACKAGES", [], return_type=list))) + ) + + @hooks.use_effect(dependencies=[]) + async def get_status(): + def thread_func(): + """Runs `pip index versions {app.pkg_name}` and parses the latest version.""" + proc = subprocess.Popen( + [ + "pip", + "index", + "versions", + pkg_name, + "--no-input", + ], + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + proc.wait() + + # Check if output is broken + if not proc.stderr or not proc.stdout: + set_error_msg("ERROR") + _logger.error( + "Broken stderr or stdout while getting pip index versions for %s", + pkg_name, + ) + return + + # Check if pip index versions failed + stderr = proc.stderr.readlines() + for line in stderr: + if line.strip().startswith(b"ERROR:"): + set_error_msg("ERROR") + _logger.error( + "'pip index versions' failed for %s: %s", + pkg_name, + line.strip().decode()[7:], + ) + return + + # Parse output + stdout = proc.stdout.readlines() + versions: list[str] = [] + installed: str = "" + latest: str = "" + for line in stdout: + if line.strip().startswith(b"Available versions:"): + versions = line.split(b":")[1].strip().decode().split(", ") + latest = versions[0] + if line.strip().startswith(b"INSTALLED:"): + installed = line.split(b":")[1].strip().decode() + if line.strip().startswith(b"LATEST:"): + latest = line.split(b":")[1].strip().decode() + if versions: + set_available_versions(versions) + if installed: + set_current_version(installed) + if latest: + set_latest_version(latest) + + # Output wasn't parsed properly, or package isn't installed + if not installed: + set_error_msg("ERROR") + _logger.error( + "Failed to obtain currently installed version from 'pip index versions' for %s: %s", + pkg_name, + stdout, + ) + if not versions: + _logger.error( + "Failed to obtain versions list from 'pip index versions' for %s: %s", + pkg_name, + stdout, + ) + if not latest: + _logger.error( + "Failed to obtain latest version from 'pip index versions' for %s: %s", + pkg_name, + stdout, + ) + + proc.kill() + + threading.Thread(target=thread_func, daemon=True).start() + + async def disable_click(_): + if pkg_name in disabled_packages: + disabled_packages.remove(pkg_name) + else: + disabled_packages.append(pkg_name) + set_env("DISABLED_PACKAGES", disabled_packages) + set_disabled_packages(sorted(disabled_packages)) + + status = "" + if error_msg: + status = "text-danger" + if latest_version and current_version: + status = "" if latest_version == current_version else "text-warning" + + return html.tr( + html.td(pkg_name), + html.td( + html.div( + {"class_name": status}, error_msg or current_version or "Checking..." + ) + ), + html.td(latest_version or ("N/A" if error_msg else "Checking...")), + html.td("Yes" if pkg_name in disabled_packages else "No"), + html.td( + {"style": {"text-align": "center"}}, + html.div( + {"class_name": "dropdown"}, + html.button( + { + "class_name": "btn btn-sm btn-dark dropdown-toggle", + "type": "button", + "data-bs-toggle": "dropdown", + "aria-expanded": "false", + }, + html.i({"class_name": "fas fa-cog"}), + ), + html.ul( + {"class_name": "dropdown-menu"}, + dropdown_item("Update", lambda _: None) + if latest_version != current_version + else "", + dropdown_item("Uninstall", lambda _: None), + dropdown_item( + "Enable" if pkg_name in disabled_packages else "Disable", + disable_click, + ), + dropdown_item("Change Version »", lambda _: None) + if available_versions + else "", + ), + ), + ), + ) + + +def dropdown_item(option: str, on_click): + return html.li( + {"key": option}, + html.a( + { + "class_name": "dropdown-item", + "href": f"#{option}", + "on_click": on_click, + }, + f"{option}", + ), + ) diff --git a/conreq/_core/app_store/components/modal.py b/conreq/_core/app_store/components/modal.py new file mode 100644 index 00000000..754c3f67 --- /dev/null +++ b/conreq/_core/app_store/components/modal.py @@ -0,0 +1,356 @@ +import subprocess +import threading +from typing import Sequence, Union, cast + +from reactpy import component, hooks, html +from reactpy_django.components import django_css + +from conreq._core.app_store.models import AppPackage, DevelopmentStage, Screenshot +from conreq._core.home.components.modal import ( + modal_body, + modal_content, + modal_dialog, + modal_footer, + modal_head, +) +from conreq.types import ModalStateContext +from conreq.utils.environment import get_env, set_env + + +@component +def package_details_modal(app: AppPackage): + modal_state = hooks.use_context(ModalStateContext) + + async def install_click(_): + modal_state.modal_intent = package_install_modal + modal_state.args = [app] + modal_state.set_state(modal_state) + + package_details = { + "PyPI Package": app.pkg_name, + "Development Stage": dict(DevelopmentStage.choices).get( + app.development_stage, "" + ), + "Subcategories": ", ".join( + [str(subcat.name) for subcat in app.subcategories.all()] + ), + "Author": text_to_link(app.author_url, app.author) + if app.author_url + else app.author, + "Contact Email": text_to_link(f"mailto:{app.contact_email}", app.contact_email) + if app.contact_email + else "", + "Contact Link": text_to_link(app.contact_link), + "PyPI URL": text_to_link(app.pypi_url), + "Repository URL": text_to_link(app.repository_url), + "Homepage URL": text_to_link(app.homepage_url), + "Support URL": text_to_link(app.support_url), + "Donation URL": text_to_link(app.donation_url), + "License Type": app.license_type, + } + compatibility = { + "Supported Platforms": app.sys_platforms, + "Touch Compatible": app.touch_compatible, + "Mobile Compatible": app.mobile_compatible, + "Minimum Package Version": app.min_version, + "Conreq Minimum Version": app.conreq_min_version, + "Conreq Maximum Version": app.conreq_max_version, + "Asynchronous Support": app.asynchronous, + "Required Apps": app.required_apps.all(), + "Incompatible Apps": app.incompatible_apps.all(), + "Related Apps": app.related_apps.all(), + } + + return modal_dialog( + modal_content( + modal_head(title=app.name), + modal_body( + html.div( + {"class_name": "banner"}, "This app has not been developed yet!" + ) + if not app.development_stage + or app.development_stage == DevelopmentStage.PLANNING + else "", + html.div({"class_name": "banner"}, app.banner_message) + if app.banner_message + else "", + screenshot_carousel(app.screenshot_set.all()) + if app.screenshot_set.all() + else "", + html.p( + {"class_name": "description"}, + html.h5("Description"), + app.long_description, + ) + if app.long_description + else "", + info_table("Package Details", package_details), + info_table("Compatibility", compatibility), + ), + modal_footer( + html.button( + { + "class_name": "btn btn-primary", + "on_click": install_click, + "key": "install", + }, + "Install", + ) + if app.compatible and not app.installed + else html.button( + { + "class_name": "btn btn-primary", + "disabled": True, + "key": "installed", + }, + "Installed", + ) + if app.installed + else "" + ), + ), + django_css("conreq/package_details_modal.css"), + ) + + +@component +def info_table(title: str, info: dict): + return html.div( + {"class_name": "info-table-container"}, + html.h5({"class_name": "info-table-title"}, title), + html.table( + {"class_name": "info-table"}, + html.tbody( + [ + html.tr( + {"key": section_name}, + html.th(section_name), + html.td(value), + ) + for section_name, value in info.items() + if value + ] + ), + ), + ) + + +@component +def screenshot_carousel(screenshots: Sequence[Screenshot]): + """Converts a list of screenshots into a Bootstrap 5 carousel with indicators and controls.""" + + return html.div( + { + "id": "screenshot-carousel", + "class_name": "carousel slide carousel-fade", + "data-bs-ride": "carousel", + }, + html.div( + {"class_name": "carousel-indicators"}, + [ + html.button( + { + "type": "button", + "data-bs-target": "#screenshot-carousel", + "data-bs-slide-to": str(i), + "class_name": "active" if i == 0 else "", + "aria-current": "true" if i == 0 else "false", + "aria-label": f"Slide {i + 1}", + "key": i, + }, + ) + for i in range(len(screenshots)) + ], + ), + html.div( + {"class_name": "carousel-inner"}, + [ + html.div( + { + "class_name": "carousel-item active" + if i == 0 + else "carousel-item", + "key": str(screenshot.uuid), + "data-bs-interval": 10000, + }, + html.img( + { + "src": screenshot.image.url, + "class_name": "d-block", + "alt": screenshot.description, + } + ), + html.div( + {"class_name": "carousel-caption d-none d-md-block"}, + html.h5(screenshot.title), + html.p(screenshot.description), + ), + ) + for i, screenshot in enumerate(screenshots) + ], + ), + ) + + +def text_to_link(link_str: str, text_str: str = ""): + """Converts a string into a link if possible, otherwise return None.""" + + return html.a({"href": link_str}, text_str or link_str) if link_str else None + + +@component +def package_install_modal(app: AppPackage): + cmd = [ + "pip", + "install", + app.pkg_name, + "--disable-pip-version-check", + "--upgrade", + "--upgrade-strategy", + "eager", + ] + confirmed, set_confirmed = hooks.use_state(False) + cancelled, set_cancelled = hooks.use_state(False) + proc, set_proc = hooks.use_state(cast(Union[subprocess.Popen, None], None)) + stdout, set_stdout = hooks.use_state(html.p(" ".join(cmd))) + retcode, set_retcode = hooks.use_state(cast(Union[int, None], None)) + modal_state = hooks.use_context(ModalStateContext) + + async def close_modal(_): + modal_state.reset_modal() + modal_state.set_state(modal_state) + + @hooks.use_effect + def install_app(): + if confirmed and not proc: + set_proc( + subprocess.Popen( + cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + ) + + if proc and cancelled: + proc.kill() + + @hooks.use_effect(dependencies=[proc, stdout]) + async def update_stdout(): + """Gives the component visibility on the stdout of the process.""" + if not proc: + return + + def thread_func(): + if not proc: + return + if proc.poll() is None: + if not proc.stdout: + set_stdout( + html.p("An error has occurred. Unable to read output shell.") + ) + return + set_stdout( + html._(stdout, html.p(proc.stdout.readline().decode("utf-8"))) + ) + + threading.Thread(target=thread_func, daemon=True).start() + + @hooks.use_effect(dependencies=[proc]) + async def update_retcode(): + """Gives the component visibility on the return code of the process.""" + if not proc: + return + + def thread_func(): + if not proc: + return + proc.wait() + set_retcode(proc.returncode) + + threading.Thread(target=thread_func, daemon=True).start() + + @hooks.use_effect + async def register_install(): + """Adds the app to the `settings.env` file.""" + if retcode == 0: + # Update the installed packages list + packages = get_env("INSTALLED_PACKAGES", [], return_type=list) + if app.pkg_name not in packages: + packages.append(app.pkg_name) + set_env("INSTALLED_PACKAGES", packages) + + return modal_dialog( + modal_content( + modal_head( + title=f"Installing: {app.name}" + if confirmed + else f"Confirm Install: {app.name}" + ), + modal_body( + html.div( + {"class_name": "terminal", "key": "terminal"}, + stdout, + [ + html.p( + {"class_name": "success", "key": "success"}, + "Success. Restart your application to load this app.", + ) + if retcode == 0 + else html.p( + {"class_name": "error", "key": "failure"}, + "Installation cancelled.", + ) + if cancelled + else html.p( + {"class_name": "error", "key": "failure"}, + "An error occurred during installation.", + ) + ] + if retcode is not None + else "", + ) + if confirmed + else html.div( + {"class_name": "confirm", "key": "confirm"}, + "Are you sure you want to install ", + html.b(app.name), + "?", + ) + ), + modal_footer( + html._( + html.button( + { + "class_name": "btn btn-primary", + "on_click": lambda _: set_confirmed(True), + "key": "yes", + }, + "Yes", + ), + html.button( + { + "class_name": "btn btn-secondary", + "data-bs-dismiss": "modal", + "aria-label": "Close", + "on_click": close_modal, + "key": "no", + }, + "No", + ), + ) + if not confirmed + else html.button( + { + "class_name": "btn btn-danger", + "on_click": lambda _: set_cancelled(True), + "key": "cancel", + }, + "Cancel", + ) + if retcode is None + else "" + ), + ), + django_css("conreq/package_install_modal.css"), + ) diff --git a/conreq/_core/app_store/components/nav.py b/conreq/_core/app_store/components/nav.py new file mode 100644 index 00000000..f60650ec --- /dev/null +++ b/conreq/_core/app_store/components/nav.py @@ -0,0 +1,99 @@ +from typing import Sequence + +from reactpy import component, hooks +from reactpy.html import a, button, div, li, ul + +from conreq._core.app_store.components.event import ( + category_click_event, + manage_apps_click_event, + subcategory_click_event, +) +from conreq._core.app_store.models import Category, Subcategory +from conreq.types import AppStoreStateContext + + +@component +def app_store_nav(categories: Sequence[Category]): + state = hooks.use_context(AppStoreStateContext) + + async def return_click(_): + state.reset_tab() + state.set_state(state) + + return div( + {"class_name": "nav-region"}, + div( + {"class_name": "dropdown"}, + button( + { + "class_name": "nav-btn btn btn-dark dropdown-toggle", + "type": "button", + "data-bs-toggle": "dropdown", + "aria-expanded": "false", + }, + "Categories", + ), + ul( + {"class_name": "dropdown-menu"}, + [dropdown_item(category, key=category.uuid) for category in categories], + ), + ), + button( + { + "class_name": "nav-btn btn btn btn-dark", + "on_click": manage_apps_click_event(state), + }, + "Manage Apps", + ), + button( + {"class_name": "nav-btn btn btn btn-dark return", "on_click": return_click}, + "Return", + ) + if state.tab + else "", + ) + + +@component +def dropdown_item(category: Category): + state = hooks.use_context(AppStoreStateContext) + + return li( + a( + { + "class_name": "dropdown-item", + "href": f"#{category.uuid}", + "on_click": category_click_event(state, category), + }, + f"{category.name} »", + ), + ul( + {"class_name": "dropdown-menu dropdown-submenu"}, + [ + dropdown_sub_item( + subcategory, + key=str(subcategory.uuid), + ) + for subcategory in sorted( + category.subcategory_set.all(), + key=lambda x: x.name, + ) + ], + ), + ) + + +@component +def dropdown_sub_item(subcategory: Subcategory): + state = hooks.use_context(AppStoreStateContext) + + return li( + a( + { + "class_name": "dropdown-item", + "href": f"#{subcategory.uuid}", + "on_click": subcategory_click_event(state, subcategory), + }, + subcategory.name, + ), + ) diff --git a/conreq/_core/app_store/components/query.py b/conreq/_core/app_store/components/query.py new file mode 100644 index 00000000..0edf85e8 --- /dev/null +++ b/conreq/_core/app_store/components/query.py @@ -0,0 +1,29 @@ +from typing import Iterable + +from channels.db import database_sync_to_async +from reactpy_django.utils import django_query_postprocessor + +from conreq._core.app_store.models import AppPackage, Category, Subcategory + + +async def get_category_apps(category: Category) -> Iterable[AppPackage]: + subcategories = await database_sync_to_async(Subcategory.objects.filter)( + category=category.uuid + ) + models = await database_sync_to_async(AppPackage.objects.filter)( + subcategories__uuid__in=subcategories + ) + distinct_models = await database_sync_to_async(models.distinct)() + return await database_sync_to_async(django_query_postprocessor)(distinct_models) + + +async def get_subcategory_apps(subcategory: Subcategory) -> Iterable[AppPackage]: + packages = await database_sync_to_async(AppPackage.objects.filter)( + subcategories=subcategory.uuid + ) + return await database_sync_to_async(django_query_postprocessor)(packages) + + +async def get_author_apps(author: str) -> Iterable[AppPackage]: + models = await database_sync_to_async(AppPackage.objects.filter)(author=author) + return await database_sync_to_async(django_query_postprocessor)(models) diff --git a/conreq/_core/app_store/components/spotlight.py b/conreq/_core/app_store/components/spotlight.py new file mode 100644 index 00000000..4921d859 --- /dev/null +++ b/conreq/_core/app_store/components/spotlight.py @@ -0,0 +1,80 @@ +import asyncio +import random + +from django.db.models.manager import Manager +from reactpy import component, hooks +from reactpy.html import div, h4, p +from reactpy.types import VdomChild +from reactpy_django.components import django_css +from reactpy_django.hooks import use_query + +from conreq._core.app_store.components.card import card +from conreq._core.app_store.models import AppPackage, SpotlightCategory + + +@component +def spotlight(): + spotlight_category_query = use_query(get_spotlight_categories) + + if spotlight_category_query.loading or spotlight_category_query.error: + return + + return div( + {"class_name": "spotlight", "key": "spotlight"}, + django_css("conreq/app_store_spotlight.css"), + django_css("conreq/app_store_card.css"), + [ + spotlight_section( + category.name, + category.description, + apps=category.apps, + key=category.uuid, + ) + for category in spotlight_category_query.data # type: ignore + ], + ) + + +@component +def spotlight_section( + title, + description, + apps: Manager[AppPackage], +): + # FIXME: This shouldn't be needed, but `OrderedManyToManyField` doesn't work with `django_query_postprocessor` + spotlight_apps_query = use_query(get_spotlight_apps, apps) + opacity, set_opacity = hooks.use_state(0) + card_list: list[VdomChild] = ( + [card(app, key=app.uuid) for app in spotlight_apps_query.data] # type: ignore + if spotlight_apps_query.data + else [] + ) + + @hooks.use_effect(dependencies=[]) + async def fade_in_animation(): + await asyncio.sleep(round(random.uniform(0, 0.3), 3)) + set_opacity(1) + + return div( + {"class_name": "spotlight-section fade-in", "style": {"opacity": opacity}}, + div( + {"class_name": "spotlight-head"}, + div( + {"class_name": "spotlight-title"}, + h4({"class_name": "title"}, title), + p({"class_name": "description"}, description), + ), + ), + div( + {"class_name": "card-stage show-more"}, + div({"class_name": "collapse"}, card_list), + ), + ) + + +def get_spotlight_categories(): + return SpotlightCategory.objects.all() + + +def get_spotlight_apps(apps: Manager[AppPackage]): + return apps.all() diff --git a/conreq/_core/app_store/migrations/0001_initial.py b/conreq/_core/app_store/migrations/0001_initial.py new file mode 100644 index 00000000..8f6d65cd --- /dev/null +++ b/conreq/_core/app_store/migrations/0001_initial.py @@ -0,0 +1,285 @@ +# Generated by Django 3.2.9 on 2021-11-25 23:09 + +import uuid + +import django.db.models.deletion +import multiselectfield.db.fields +import versionfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="AppPackage", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ( + "package_name", + models.CharField(help_text="Must be snake_case.", max_length=100), + ), + ("verbose_name", models.CharField(max_length=100)), + ("description", models.CharField(blank=True, max_length=255)), + ("long_description", models.FileField(upload_to="app_store/readme/")), + ( + "long_description_type", + models.CharField( + choices=[ + ("text/plain", "Plain Text (.txt)"), + ("text/x-rst", "reStructuredText (.rst)"), + ("text/markdown", "Markdown (.md)"), + ], + default="text/markdown", + max_length=20, + ), + ), + ( + "development_stage", + models.CharField( + blank=True, + choices=[ + ("1 - Planning", "Planning"), + ("2 - Pre-Alpha", "Pre-Alpha"), + ("3 - Alpha", "Alpha"), + ("4 - Beta", "Beta"), + ("5 - Production/Stable", "Stable"), + ("6 - Mature", "Mature"), + ("7 - Inactive", "Inactive"), + ], + max_length=21, + ), + ), + ("version", versionfield.fields.VersionField()), + ("banner_message", models.TextField(blank=True)), + ("author", models.CharField(max_length=50)), + ("author_email", models.EmailField(blank=True, max_length=254)), + ("repository_url", models.URLField()), + ("homepage_url", models.URLField(blank=True)), + ("support_url", models.URLField(blank=True)), + ("donation_url", models.URLField(blank=True)), + ("pypi_url", models.URLField(blank=True)), + ("license_type", models.CharField(default="GPLv3", max_length=100)), + ( + "sys_platforms", + multiselectfield.db.fields.MultiSelectField( + choices=[ + ("AIX", "Aix"), + ("LINUX", "Linux"), + ("WINDOWS", "Windows"), + ("CYGWIN", "Cygwin"), + ("MACOS", "Darwin"), + ], + max_length=10, + ), + ), + ("touch_compatible", models.BooleanField()), + ("mobile_compatible", models.BooleanField()), + ("minimum_conreq_version", versionfield.fields.VersionField()), + ("tested_conreq_version", versionfield.fields.VersionField()), + ( + "max_conreq_version", + versionfield.fields.VersionField(blank=True, null=True), + ), + ( + "asynchronous", + models.CharField( + choices=[ + ("NONE", "No Async"), + ("SEMI", "Semi Async"), + ("FULL", "Fully Async"), + ], + max_length=20, + ), + ), + ( + "incompatible_apps", + models.ManyToManyField( + blank=True, + related_name="_app_store_apppackage_incompatible_apps_+", + to="app_store.AppPackage", + ), + ), + ], + ), + migrations.CreateModel( + name="Category", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("name", models.CharField(max_length=50)), + ("description", models.TextField(blank=True)), + ], + options={ + "verbose_name_plural": "Categories", + }, + ), + migrations.CreateModel( + name="Subcategory", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("name", models.CharField(max_length=50)), + ("description", models.TextField(blank=True)), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.category", + ), + ), + ], + options={ + "verbose_name": "Subcategory", + "verbose_name_plural": "Subcategories", + }, + ), + migrations.CreateModel( + name="Screenshot", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("title", models.CharField(max_length=100)), + ("description", models.CharField(blank=True, max_length=255)), + ("image", models.ImageField(upload_to="app_store/screenshot/")), + ( + "app_package", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.apppackage", + ), + ), + ], + ), + migrations.CreateModel( + name="NoticeMessage", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("title", models.CharField(max_length=100)), + ("description", models.TextField(blank=True)), + ( + "mark_read", + models.BooleanField(blank=True, default=False, null=True), + ), + ( + "app_package", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.apppackage", + ), + ), + ], + ), + migrations.CreateModel( + name="EnvironmentVariable", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("name", models.CharField(max_length=50)), + ("default", models.CharField(blank=True, max_length=255)), + ("example", models.CharField(blank=True, max_length=255)), + ("required", models.BooleanField(blank=True, default=False, null=True)), + ( + "app_package", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.apppackage", + ), + ), + ], + ), + migrations.AddField( + model_name="apppackage", + name="incompatible_categories", + field=models.ManyToManyField( + blank=True, + related_name="incompatible_categories", + to="app_store.Category", + ), + ), + migrations.AddField( + model_name="apppackage", + name="incompatible_subcategories", + field=models.ManyToManyField( + blank=True, + related_name="incompatible_subcategories", + to="app_store.Subcategory", + ), + ), + migrations.AddField( + model_name="apppackage", + name="optional_apps", + field=models.ManyToManyField( + blank=True, + related_name="_app_store_apppackage_optional_apps_+", + to="app_store.AppPackage", + ), + ), + migrations.AddField( + model_name="apppackage", + name="required_apps", + field=models.ManyToManyField( + blank=True, + related_name="_app_store_apppackage_required_apps_+", + to="app_store.AppPackage", + ), + ), + migrations.AddField( + model_name="apppackage", + name="subcategories", + field=models.ManyToManyField(to="app_store.Subcategory"), + ), + ] diff --git a/conreq/_core/app_store/migrations/0002_alter_apppackage_incompatible_apps_and_more.py b/conreq/_core/app_store/migrations/0002_alter_apppackage_incompatible_apps_and_more.py new file mode 100644 index 00000000..65925507 --- /dev/null +++ b/conreq/_core/app_store/migrations/0002_alter_apppackage_incompatible_apps_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0 on 2021-12-08 17:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="incompatible_apps", + field=models.ManyToManyField(blank=True, to="app_store.AppPackage"), + ), + migrations.AlterField( + model_name="apppackage", + name="optional_apps", + field=models.ManyToManyField(blank=True, to="app_store.AppPackage"), + ), + migrations.AlterField( + model_name="apppackage", + name="required_apps", + field=models.ManyToManyField(blank=True, to="app_store.AppPackage"), + ), + ] diff --git a/conreq/_core/app_store/migrations/0003_rename_description_apppackage_short_description_and_more.py b/conreq/_core/app_store/migrations/0003_rename_description_apppackage_short_description_and_more.py new file mode 100644 index 00000000..667e1ebf --- /dev/null +++ b/conreq/_core/app_store/migrations/0003_rename_description_apppackage_short_description_and_more.py @@ -0,0 +1,61 @@ +# Generated by Django 4.0 on 2021-12-15 19:44 + +import versionfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0002_alter_apppackage_incompatible_apps_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="description", + new_name="short_description", + ), + migrations.RemoveField( + model_name="apppackage", + name="version", + ), + migrations.AddField( + model_name="apppackage", + name="min_version", + field=versionfield.fields.VersionField( + default="0.0.0", + help_text="Minimum PyPI version or Git tag that is compatible with Conreq.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="banner_message", + field=models.TextField( + blank=True, + help_text="Optional text message banner shown this apps details page.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="long_description", + field=models.TextField( + blank=True, + help_text="This will be automatically fetched from PyPI or Git if left empty.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="package_name", + field=models.CharField( + help_text="Must be snake_case. Used for PyPI package installation, or folder naming on Git installations.", + max_length=100, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="repository_url", + field=models.URLField( + blank=True, help_text="Must be a Git repository if not using PyPI." + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0004_rename_max_conreq_version_apppackage_conreq_max_version_and_more.py b/conreq/_core/app_store/migrations/0004_rename_max_conreq_version_apppackage_conreq_max_version_and_more.py new file mode 100644 index 00000000..7d3a8b2b --- /dev/null +++ b/conreq/_core/app_store/migrations/0004_rename_max_conreq_version_apppackage_conreq_max_version_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0 on 2021-12-15 19:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0003_rename_description_apppackage_short_description_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="max_conreq_version", + new_name="conreq_max_version", + ), + migrations.RenameField( + model_name="apppackage", + old_name="minimum_conreq_version", + new_name="conreq_minimum_version", + ), + migrations.RenameField( + model_name="apppackage", + old_name="tested_conreq_version", + new_name="conreq_tested_version", + ), + ] diff --git a/conreq/_core/app_store/migrations/0005_remove_apppackage_incompatible_categories.py b/conreq/_core/app_store/migrations/0005_remove_apppackage_incompatible_categories.py new file mode 100644 index 00000000..52449c2b --- /dev/null +++ b/conreq/_core/app_store/migrations/0005_remove_apppackage_incompatible_categories.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0 on 2021-12-16 20:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ( + "app_store", + "0004_rename_max_conreq_version_apppackage_conreq_max_version_and_more", + ), + ] + + operations = [ + migrations.RemoveField( + model_name="apppackage", + name="incompatible_categories", + ), + ] diff --git a/conreq/_core/app_store/migrations/0006_remove_apppackage_conreq_minimum_version_and_more.py b/conreq/_core/app_store/migrations/0006_remove_apppackage_conreq_minimum_version_and_more.py new file mode 100644 index 00000000..f838dc78 --- /dev/null +++ b/conreq/_core/app_store/migrations/0006_remove_apppackage_conreq_minimum_version_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.0 on 2021-12-20 01:42 + +import versionfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0005_remove_apppackage_incompatible_categories"), + ] + + operations = [ + migrations.RemoveField( + model_name="apppackage", + name="conreq_minimum_version", + ), + migrations.AddField( + model_name="apppackage", + name="conreq_min_version", + field=versionfield.fields.VersionField(default="0.0.0"), + ), + ] diff --git a/conreq/_core/app_store/migrations/0007_apppackage_logo.py b/conreq/_core/app_store/migrations/0007_apppackage_logo.py new file mode 100644 index 00000000..9cf47ff3 --- /dev/null +++ b/conreq/_core/app_store/migrations/0007_apppackage_logo.py @@ -0,0 +1,22 @@ +# Generated by Django 4.0 on 2022-01-02 03:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0006_remove_apppackage_conreq_minimum_version_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="apppackage", + name="logo", + field=models.ImageField( + blank=True, + height_field=250, + upload_to="app_store/logos/", + width_field=250, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0008_apppackage_created_at_apppackage_modified_at.py b/conreq/_core/app_store/migrations/0008_apppackage_created_at_apppackage_modified_at.py new file mode 100644 index 00000000..ddb2b7e2 --- /dev/null +++ b/conreq/_core/app_store/migrations/0008_apppackage_created_at_apppackage_modified_at.py @@ -0,0 +1,26 @@ +# Generated by Django 4.0.1 on 2022-01-05 02:52 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0007_apppackage_logo"), + ] + + operations = [ + migrations.AddField( + model_name="apppackage", + name="created_at", + field=models.DateTimeField( + auto_now_add=True, default=django.utils.timezone.now + ), + preserve_default=False, + ), + migrations.AddField( + model_name="apppackage", + name="modified_at", + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/conreq/_core/app_store/migrations/0009_remove_category_description_and_more.py b/conreq/_core/app_store/migrations/0009_remove_category_description_and_more.py new file mode 100644 index 00000000..cfdedfae --- /dev/null +++ b/conreq/_core/app_store/migrations/0009_remove_category_description_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.1 on 2022-01-07 06:26 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0008_apppackage_created_at_apppackage_modified_at"), + ] + + operations = [ + migrations.RemoveField( + model_name="category", + name="description", + ), + migrations.RemoveField( + model_name="noticemessage", + name="mark_read", + ), + migrations.RemoveField( + model_name="subcategory", + name="description", + ), + migrations.DeleteModel( + name="EnvironmentVariable", + ), + ] diff --git a/conreq/_core/app_store/migrations/0010_alter_category_name_and_more.py b/conreq/_core/app_store/migrations/0010_alter_category_name_and_more.py new file mode 100644 index 00000000..80b449df --- /dev/null +++ b/conreq/_core/app_store/migrations/0010_alter_category_name_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.1 on 2022-01-07 06:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0009_remove_category_description_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="category", + name="name", + field=models.CharField(max_length=50, unique=True), + ), + migrations.AlterUniqueTogether( + name="subcategory", + unique_together={("name", "category")}, + ), + ] diff --git a/conreq/_core/app_store/migrations/0011_alter_apppackage_logo_alter_screenshot_image.py b/conreq/_core/app_store/migrations/0011_alter_apppackage_logo_alter_screenshot_image.py new file mode 100644 index 00000000..4060434a --- /dev/null +++ b/conreq/_core/app_store/migrations/0011_alter_apppackage_logo_alter_screenshot_image.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.1 on 2022-01-08 22:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0010_alter_category_name_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="logo", + field=models.ImageField( + blank=True, + height_field=250, + upload_to="serve/app_store/logos/", + width_field=250, + ), + ), + migrations.AlterField( + model_name="screenshot", + name="image", + field=models.ImageField(upload_to="serve/app_store/screenshot/"), + ), + ] diff --git a/conreq/_core/app_store/migrations/0012_alter_apppackage_logo_alter_screenshot_image.py b/conreq/_core/app_store/migrations/0012_alter_apppackage_logo_alter_screenshot_image.py new file mode 100644 index 00000000..278347aa --- /dev/null +++ b/conreq/_core/app_store/migrations/0012_alter_apppackage_logo_alter_screenshot_image.py @@ -0,0 +1,31 @@ +# Generated by Django 4.0.1 on 2022-01-08 23:19 + +from django.db import migrations, models + +import conreq.utils.models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0011_alter_apppackage_logo_alter_screenshot_image"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="logo", + field=models.ImageField( + blank=True, + upload_to=conreq.utils.models.UUIDFilePath("serve/app_store/logos/"), + ), + ), + migrations.AlterField( + model_name="screenshot", + name="image", + field=models.ImageField( + upload_to=conreq.utils.models.UUIDFilePath( + "serve/app_store/screenshot/" + ) + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0013_packageversion_apppackage_sync_with_pypi_and_more.py b/conreq/_core/app_store/migrations/0013_packageversion_apppackage_sync_with_pypi_and_more.py new file mode 100644 index 00000000..e84baaa0 --- /dev/null +++ b/conreq/_core/app_store/migrations/0013_packageversion_apppackage_sync_with_pypi_and_more.py @@ -0,0 +1,42 @@ +# Generated by Django 4.0.1 on 2022-01-23 02:33 + +import versionfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0012_alter_apppackage_logo_alter_screenshot_image"), + ] + + operations = [ + migrations.CreateModel( + name="PackageVersion", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("version", versionfield.fields.VersionField(unique=True)), + ], + ), + migrations.AddField( + model_name="apppackage", + name="sync_with_pypi", + field=models.BooleanField( + default=False, + help_text="Will automatically sync relevant information with the latest PyPI version.", + verbose_name="Sync with PyPI", + ), + ), + migrations.AddField( + model_name="apppackage", + name="versions", + field=models.ManyToManyField(blank=True, to="app_store.PackageVersion"), + ), + ] diff --git a/conreq/_core/app_store/migrations/0014_alter_apppackage_min_version.py b/conreq/_core/app_store/migrations/0014_alter_apppackage_min_version.py new file mode 100644 index 00000000..cfbfa27a --- /dev/null +++ b/conreq/_core/app_store/migrations/0014_alter_apppackage_min_version.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.1 on 2022-01-24 16:33 + +import versionfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0013_packageversion_apppackage_sync_with_pypi_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="min_version", + field=versionfield.fields.VersionField( + default="0.0.0", + help_text="Minimum PyPI version or Git tag for this package that is compatible with Conreq.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0015_alter_apppackage_asynchronous_and_more.py b/conreq/_core/app_store/migrations/0015_alter_apppackage_asynchronous_and_more.py new file mode 100644 index 00000000..43cbaaf1 --- /dev/null +++ b/conreq/_core/app_store/migrations/0015_alter_apppackage_asynchronous_and_more.py @@ -0,0 +1,67 @@ +# Generated by Django 4.0.2 on 2022-02-12 16:27 + +import multiselectfield.db.fields +import versionfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0014_alter_apppackage_min_version"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="asynchronous", + field=models.CharField( + choices=[ + ("NONE", "No Async"), + ("SEMI", "Semi Async"), + ("FULL", "Fully Async"), + ], + default="NONE", + max_length=20, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="conreq_tested_version", + field=versionfield.fields.VersionField(blank=True, null=True), + ), + migrations.AlterField( + model_name="apppackage", + name="development_stage", + field=models.CharField( + blank=True, + choices=[ + ("1 - Planning", "Planning"), + ("2 - Pre-Alpha", "Pre-Alpha"), + ("3 - Alpha", "Alpha"), + ("4 - Beta", "Beta"), + ("5 - Production/Stable", "Stable"), + ("6 - Mature", "Mature"), + ("7 - Inactive", "Inactive"), + ], + default="1 - Planning", + max_length=21, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="sys_platforms", + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ("ANY", "Any"), + ("AIX", "Aix"), + ("LINUX", "Linux"), + ("WINDOWS", "Windows"), + ("CYGWIN", "Cygwin"), + ("MACOS", "Darwin"), + ], + default="ANY", + max_length=40, + verbose_name="Supported Platforms", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0016_alter_apppackage_banner_message_and_more.py b/conreq/_core/app_store/migrations/0016_alter_apppackage_banner_message_and_more.py new file mode 100644 index 00000000..1fff7787 --- /dev/null +++ b/conreq/_core/app_store/migrations/0016_alter_apppackage_banner_message_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 4.0.2 on 2022-02-12 16:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0015_alter_apppackage_asynchronous_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="banner_message", + field=models.TextField( + blank=True, + help_text="Optional text message banner shown on the app info page.", + max_length=1000, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="long_description_type", + field=models.CharField( + choices=[ + ("text/plain", "Plain Text (.txt)"), + ("text/x-rst", "reStructuredText (.rst)"), + ("text/markdown", "Markdown (.md)"), + ], + default="text/plain", + max_length=20, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0017_rename_verbose_name_apppackage_name_and_more.py b/conreq/_core/app_store/migrations/0017_rename_verbose_name_apppackage_name_and_more.py new file mode 100644 index 00000000..611f0543 --- /dev/null +++ b/conreq/_core/app_store/migrations/0017_rename_verbose_name_apppackage_name_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.2 on 2022-02-15 16:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0016_alter_apppackage_banner_message_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="verbose_name", + new_name="name", + ), + migrations.RenameField( + model_name="apppackage", + old_name="package_name", + new_name="pkg_name", + ), + migrations.AlterField( + model_name="apppackage", + name="long_description", + field=models.TextField(blank=True), + ), + ] diff --git a/conreq/_core/app_store/migrations/0018_alter_apppackage_pkg_name.py b/conreq/_core/app_store/migrations/0018_alter_apppackage_pkg_name.py new file mode 100644 index 00000000..5fadaaaf --- /dev/null +++ b/conreq/_core/app_store/migrations/0018_alter_apppackage_pkg_name.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1 on 2022-09-02 17:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0017_rename_verbose_name_apppackage_name_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="pkg_name", + field=models.CharField( + help_text="Must be snake_case. Used for PyPI package installation, or folder naming on Git installations.", + max_length=100, + unique=True, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0019_spotlightcategory.py b/conreq/_core/app_store/migrations/0019_spotlightcategory.py new file mode 100644 index 00000000..4ceeb87b --- /dev/null +++ b/conreq/_core/app_store/migrations/0019_spotlightcategory.py @@ -0,0 +1,36 @@ +# Generated by Django 4.1.1 on 2022-10-13 15:09 + +import uuid + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0018_alter_apppackage_pkg_name"), + ] + + operations = [ + migrations.CreateModel( + name="SpotlightCategory", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("name", models.CharField(max_length=50, unique=True)), + ("description", models.TextField(blank=True)), + ("apps", models.ManyToManyField(to="app_store.apppackage")), + ], + options={ + "verbose_name": "Spotlight category", + "verbose_name_plural": "Spotlight categories", + }, + ), + ] diff --git a/conreq/_core/app_store/migrations/0020_remove_spotlightcategory_apps_spotlightthroughmodel.py b/conreq/_core/app_store/migrations/0020_remove_spotlightcategory_apps_spotlightthroughmodel.py new file mode 100644 index 00000000..6f4d1d06 --- /dev/null +++ b/conreq/_core/app_store/migrations/0020_remove_spotlightcategory_apps_spotlightthroughmodel.py @@ -0,0 +1,54 @@ +# Generated by Django 4.1.1 on 2022-10-13 17:02 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0019_spotlightcategory"), + ] + + operations = [ + migrations.RemoveField( + model_name="spotlightcategory", + name="apps", + ), + migrations.CreateModel( + name="SpotlightThroughModel", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "order", + models.PositiveIntegerField( + db_index=True, editable=False, verbose_name="order" + ), + ), + ( + "app", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.apppackage", + ), + ), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.spotlightcategory", + ), + ), + ], + options={ + "ordering": ("category", "order"), + }, + ), + ] diff --git a/conreq/_core/app_store/migrations/0021_spotlightcategory_apps.py b/conreq/_core/app_store/migrations/0021_spotlightcategory_apps.py new file mode 100644 index 00000000..81c5804c --- /dev/null +++ b/conreq/_core/app_store/migrations/0021_spotlightcategory_apps.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.1 on 2022-10-13 17:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0020_remove_spotlightcategory_apps_spotlightthroughmodel"), + ] + + operations = [ + migrations.AddField( + model_name="spotlightcategory", + name="apps", + field=models.ManyToManyField( + through="app_store.SpotlightThroughModel", to="app_store.apppackage" + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0022_spotlightcategory_order.py b/conreq/_core/app_store/migrations/0022_spotlightcategory_order.py new file mode 100644 index 00000000..243b08d6 --- /dev/null +++ b/conreq/_core/app_store/migrations/0022_spotlightcategory_order.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.1 on 2022-10-13 17:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0021_spotlightcategory_apps"), + ] + + operations = [ + migrations.AddField( + model_name="spotlightcategory", + name="order", + field=models.PositiveIntegerField( + db_index=True, default=0, editable=False, verbose_name="order" + ), + preserve_default=False, + ), + ] diff --git a/conreq/_core/app_store/migrations/0023_rename_spotlightthroughmodel_spotlightapps.py b/conreq/_core/app_store/migrations/0023_rename_spotlightthroughmodel_spotlightapps.py new file mode 100644 index 00000000..aa38cc21 --- /dev/null +++ b/conreq/_core/app_store/migrations/0023_rename_spotlightthroughmodel_spotlightapps.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.1 on 2022-10-13 17:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0022_spotlightcategory_order"), + ] + + operations = [ + migrations.RenameModel( + old_name="SpotlightThroughModel", + new_name="SpotlightApps", + ), + ] diff --git a/conreq/_core/app_store/migrations/0024_rename_spotlightapps_spotlightapp.py b/conreq/_core/app_store/migrations/0024_rename_spotlightapps_spotlightapp.py new file mode 100644 index 00000000..8e3a5e82 --- /dev/null +++ b/conreq/_core/app_store/migrations/0024_rename_spotlightapps_spotlightapp.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.1 on 2022-10-13 17:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0023_rename_spotlightthroughmodel_spotlightapps"), + ] + + operations = [ + migrations.RenameModel( + old_name="SpotlightApps", + new_name="SpotlightApp", + ), + ] diff --git a/conreq/_core/app_store/migrations/0025_remove_spotlightcategory_apps_delete_spotlightapp_and_more.py b/conreq/_core/app_store/migrations/0025_remove_spotlightcategory_apps_delete_spotlightapp_and_more.py new file mode 100644 index 00000000..ae89d494 --- /dev/null +++ b/conreq/_core/app_store/migrations/0025_remove_spotlightcategory_apps_delete_spotlightapp_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.1 on 2022-10-13 22:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0024_rename_spotlightapps_spotlightapp"), + ] + + operations = [ + migrations.RemoveField( + model_name="spotlightcategory", + name="apps", + ), + migrations.DeleteModel( + name="SpotlightApp", + ), + migrations.DeleteModel( + name="SpotlightCategory", + ), + ] diff --git a/conreq/_core/app_store/migrations/0026_spotlightapp_spotlightcategory_spotlightapp_category.py b/conreq/_core/app_store/migrations/0026_spotlightapp_spotlightcategory_spotlightapp_category.py new file mode 100644 index 00000000..8e85c406 --- /dev/null +++ b/conreq/_core/app_store/migrations/0026_spotlightapp_spotlightcategory_spotlightapp_category.py @@ -0,0 +1,89 @@ +# Generated by Django 4.1.1 on 2022-10-13 22:37 + +import uuid + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ( + "app_store", + "0025_remove_spotlightcategory_apps_delete_spotlightapp_and_more", + ), + ] + + operations = [ + migrations.CreateModel( + name="SpotlightApp", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "order", + models.PositiveIntegerField( + db_index=True, editable=False, verbose_name="order" + ), + ), + ( + "app", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.apppackage", + ), + ), + ], + options={ + "ordering": ("category", "order"), + }, + ), + migrations.CreateModel( + name="SpotlightCategory", + fields=[ + ( + "order", + models.PositiveIntegerField( + db_index=True, editable=False, verbose_name="order" + ), + ), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("name", models.CharField(max_length=50, unique=True)), + ("description", models.TextField(blank=True)), + ( + "apps", + models.ManyToManyField( + through="app_store.SpotlightApp", to="app_store.apppackage" + ), + ), + ], + options={ + "verbose_name": "Spotlight category", + "verbose_name_plural": "Spotlight categories", + }, + ), + migrations.AddField( + model_name="spotlightapp", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="app_store.spotlightcategory", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0027_apppackage_background.py b/conreq/_core/app_store/migrations/0027_apppackage_background.py new file mode 100644 index 00000000..fa89e625 --- /dev/null +++ b/conreq/_core/app_store/migrations/0027_apppackage_background.py @@ -0,0 +1,24 @@ +# Generated by Django 4.1.1 on 2022-10-18 14:49 + +from django.db import migrations, models + +import conreq.utils.models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0026_spotlightapp_spotlightcategory_spotlightapp_category"), + ] + + operations = [ + migrations.AddField( + model_name="apppackage", + name="background", + field=models.ImageField( + blank=True, + upload_to=conreq.utils.models.UUIDFilePath( + "serve/app_store/backgrounds/" + ), + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0028_apppackage_special.py b/conreq/_core/app_store/migrations/0028_apppackage_special.py new file mode 100644 index 00000000..21947641 --- /dev/null +++ b/conreq/_core/app_store/migrations/0028_apppackage_special.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.1 on 2022-10-18 18:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0027_apppackage_background"), + ] + + operations = [ + migrations.AddField( + model_name="apppackage", + name="special", + field=models.BooleanField( + default=False, + help_text="If enabled, this app's cards will be visually highlighted. Reserved for donations.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0029_appnoticemessage_alter_apppackage_banner_message_and_more.py b/conreq/_core/app_store/migrations/0029_appnoticemessage_alter_apppackage_banner_message_and_more.py new file mode 100644 index 00000000..684a2f32 --- /dev/null +++ b/conreq/_core/app_store/migrations/0029_appnoticemessage_alter_apppackage_banner_message_and_more.py @@ -0,0 +1,58 @@ +# Generated by Django 4.1.3 on 2022-12-06 18:40 + +import uuid + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("app_store", "0028_apppackage_special"), + ] + + operations = [ + migrations.CreateModel( + name="AppNoticeMessage", + fields=[ + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("title", models.CharField(max_length=100)), + ("description", models.TextField(blank=True)), + ], + ), + migrations.AlterField( + model_name="apppackage", + name="banner_message", + field=models.TextField( + blank=True, + help_text="Optional text message shown on the app info modal.", + max_length=1000, + ), + ), + migrations.DeleteModel( + name="NoticeMessage", + ), + migrations.AddField( + model_name="appnoticemessage", + name="app_package", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="app_store.apppackage" + ), + ), + migrations.AddField( + model_name="appnoticemessage", + name="read_by", + field=models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/conreq/_core/app_store/migrations/0030_alter_apppackage_sys_platforms.py b/conreq/_core/app_store/migrations/0030_alter_apppackage_sys_platforms.py new file mode 100644 index 00000000..ad63490f --- /dev/null +++ b/conreq/_core/app_store/migrations/0030_alter_apppackage_sys_platforms.py @@ -0,0 +1,29 @@ +# Generated by Django 4.1.4 on 2022-12-08 03:39 + +import multiselectfield.db.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0029_appnoticemessage_alter_apppackage_banner_message_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="sys_platforms", + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ("Any", "Any"), + ("Linux", "Linux"), + ("Windows", "Windows"), + ("Darwin", "MacOS"), + ("FreeBSD", "FreeBSD"), + ], + default="Any", + max_length=40, + verbose_name="Supported Platforms", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0031_rename_author_email_apppackage_contact_email_and_more.py b/conreq/_core/app_store/migrations/0031_rename_author_email_apppackage_contact_email_and_more.py new file mode 100644 index 00000000..9e59f67f --- /dev/null +++ b/conreq/_core/app_store/migrations/0031_rename_author_email_apppackage_contact_email_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.4 on 2022-12-30 00:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0030_alter_apppackage_sys_platforms"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="author_email", + new_name="contact_email", + ), + migrations.AddField( + model_name="apppackage", + name="contact_link", + field=models.URLField( + blank=True, + help_text='Link takes priority of email for the small "Contact" button.', + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0032_category_order.py b/conreq/_core/app_store/migrations/0032_category_order.py new file mode 100644 index 00000000..a8c55e9d --- /dev/null +++ b/conreq/_core/app_store/migrations/0032_category_order.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.4 on 2022-12-30 04:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0031_rename_author_email_apppackage_contact_email_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="category", + name="order", + field=models.PositiveIntegerField( + db_index=True, default=1, editable=False, verbose_name="order" + ), + preserve_default=False, + ), + ] diff --git a/conreq/_core/app_store/migrations/0033_remove_apppackage_conreq_tested_version.py b/conreq/_core/app_store/migrations/0033_remove_apppackage_conreq_tested_version.py new file mode 100644 index 00000000..f8d85f5a --- /dev/null +++ b/conreq/_core/app_store/migrations/0033_remove_apppackage_conreq_tested_version.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.4 on 2023-01-02 00:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0032_category_order"), + ] + + operations = [ + migrations.RemoveField( + model_name="apppackage", + name="conreq_tested_version", + ), + ] diff --git a/conreq/_core/app_store/migrations/0034_rename_optional_apps_apppackage_related_apps.py b/conreq/_core/app_store/migrations/0034_rename_optional_apps_apppackage_related_apps.py new file mode 100644 index 00000000..9f083fd9 --- /dev/null +++ b/conreq/_core/app_store/migrations/0034_rename_optional_apps_apppackage_related_apps.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2023-01-02 00:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0033_remove_apppackage_conreq_tested_version"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="optional_apps", + new_name="related_apps", + ), + ] diff --git a/conreq/_core/app_store/migrations/0035_remove_apppackage_incompatible_subcategories.py b/conreq/_core/app_store/migrations/0035_remove_apppackage_incompatible_subcategories.py new file mode 100644 index 00000000..1999d083 --- /dev/null +++ b/conreq/_core/app_store/migrations/0035_remove_apppackage_incompatible_subcategories.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.4 on 2023-01-02 00:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0034_rename_optional_apps_apppackage_related_apps"), + ] + + operations = [ + migrations.RemoveField( + model_name="apppackage", + name="incompatible_subcategories", + ), + ] diff --git a/conreq/_core/app_store/migrations/0036_alter_apppackage_asynchronous.py b/conreq/_core/app_store/migrations/0036_alter_apppackage_asynchronous.py new file mode 100644 index 00000000..53068784 --- /dev/null +++ b/conreq/_core/app_store/migrations/0036_alter_apppackage_asynchronous.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.4 on 2023-01-02 00:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0035_remove_apppackage_incompatible_subcategories"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="asynchronous", + field=models.CharField( + choices=[ + ("No Async", "No Async"), + ("Semi Async", "Semi Async"), + ("Fully Async", "Fully Async"), + ], + default="No Async", + max_length=20, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0037_apppackage_author_url.py b/conreq/_core/app_store/migrations/0037_apppackage_author_url.py new file mode 100644 index 00000000..ac3520d8 --- /dev/null +++ b/conreq/_core/app_store/migrations/0037_apppackage_author_url.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.4 on 2023-01-02 01:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0036_alter_apppackage_asynchronous"), + ] + + operations = [ + migrations.AddField( + model_name="apppackage", + name="author_url", + field=models.URLField( + blank=True, + help_text="This is typically a link to your GitHub user account or organization.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0038_alter_apppackage_author.py b/conreq/_core/app_store/migrations/0038_alter_apppackage_author.py new file mode 100644 index 00000000..89bf6b18 --- /dev/null +++ b/conreq/_core/app_store/migrations/0038_alter_apppackage_author.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2023-01-02 02:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0037_apppackage_author_url"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="author", + field=models.CharField(blank=True, max_length=50), + ), + ] diff --git a/conreq/_core/app_store/migrations/0039_rename_spotlightapp_spotlightapppackages.py b/conreq/_core/app_store/migrations/0039_rename_spotlightapp_spotlightapppackages.py new file mode 100644 index 00000000..8ca3a48c --- /dev/null +++ b/conreq/_core/app_store/migrations/0039_rename_spotlightapp_spotlightapppackages.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.5 on 2023-03-10 09:48 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0038_alter_apppackage_author"), + ] + + operations = [ + migrations.RenameModel( + old_name="SpotlightApp", + new_name="SpotlightAppPackages", + ), + ] diff --git a/conreq/_core/app_store/migrations/0040_alter_category_options.py b/conreq/_core/app_store/migrations/0040_alter_category_options.py new file mode 100644 index 00000000..bfd6b7bb --- /dev/null +++ b/conreq/_core/app_store/migrations/0040_alter_category_options.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.5 on 2023-03-10 09:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0039_rename_spotlightapp_spotlightapppackages"), + ] + + operations = [ + migrations.AlterModelOptions( + name="category", + options={"ordering": ["order"], "verbose_name_plural": "Categories"}, + ), + ] diff --git a/conreq/_core/app_store/migrations/0041_alter_spotlightcategory_options.py b/conreq/_core/app_store/migrations/0041_alter_spotlightcategory_options.py new file mode 100644 index 00000000..47a8b975 --- /dev/null +++ b/conreq/_core/app_store/migrations/0041_alter_spotlightcategory_options.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.5 on 2023-03-10 09:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0040_alter_category_options"), + ] + + operations = [ + migrations.AlterModelOptions( + name="spotlightcategory", + options={ + "ordering": ["order"], + "verbose_name": "Spotlight category", + "verbose_name_plural": "Spotlight categories", + }, + ), + ] diff --git a/conreq/_core/app_store/migrations/0042_alter_spotlightcategory_apps.py b/conreq/_core/app_store/migrations/0042_alter_spotlightcategory_apps.py new file mode 100644 index 00000000..72a1a7ac --- /dev/null +++ b/conreq/_core/app_store/migrations/0042_alter_spotlightcategory_apps.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.5 on 2023-03-10 09:52 + +from django.db import migrations +import ordered_model.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0041_alter_spotlightcategory_options"), + ] + + operations = [ + migrations.AlterField( + model_name="spotlightcategory", + name="apps", + field=ordered_model.fields.OrderedManyToManyField( + through="app_store.SpotlightAppPackages", to="app_store.apppackage" + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0043_pypidata_remove_apppackage_asynchronous_and_more.py b/conreq/_core/app_store/migrations/0043_pypidata_remove_apppackage_asynchronous_and_more.py new file mode 100644 index 00000000..37f91a6f --- /dev/null +++ b/conreq/_core/app_store/migrations/0043_pypidata_remove_apppackage_asynchronous_and_more.py @@ -0,0 +1,265 @@ +# Generated by Django 4.2.1 on 2023-12-29 00:32 + +import conreq._core.fields +from django.db import migrations, models +import django.db.models.deletion +import versionfield.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0042_alter_spotlightcategory_apps"), + ] + + operations = [ + migrations.CreateModel( + name="PyPiData", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("author", models.CharField(blank=True, max_length=50)), + ("author_email", models.EmailField(blank=True, max_length=254)), + ( + "development_status", + models.CharField( + blank=True, + choices=[ + ("1 - Planning", "Planning"), + ("2 - Pre-Alpha", "Pre-Alpha"), + ("3 - Alpha", "Alpha"), + ("4 - Beta", "Beta"), + ("5 - Production/Stable", "Stable"), + ("6 - Mature", "Mature"), + ("7 - Inactive", "Inactive"), + ], + default="1 - Planning", + max_length=21, + ), + ), + ("description", models.TextField(blank=True)), + ( + "description_content_type", + models.CharField( + blank=True, + choices=[ + ("text/plain", "Plain Text (.txt)"), + ("text/x-rst", "reStructuredText (.rst)"), + ("text/markdown", "Markdown (.md)"), + ], + default="text/plain", + max_length=20, + ), + ), + ("keywords", models.TextField(blank=True)), + ("license", models.CharField(blank=True, max_length=100)), + ("maintainer", models.CharField(blank=True, max_length=50)), + ("maintainer_email", models.EmailField(blank=True, max_length=254)), + ("package_url", models.URLField(blank=True)), + ("requires_python", models.CharField(blank=True, max_length=50)), + ("summary", models.CharField(blank=True, max_length=255)), + ("version", versionfield.fields.VersionField(blank=True)), + ("releases", models.JSONField(blank=True)), + ("loaded", models.BooleanField(default=False)), + ("modified_at", models.DateTimeField(auto_now=True)), + ], + ), + migrations.RemoveField( + model_name="apppackage", + name="asynchronous", + ), + migrations.RemoveField( + model_name="apppackage", + name="author", + ), + migrations.RemoveField( + model_name="apppackage", + name="author_url", + ), + migrations.RemoveField( + model_name="apppackage", + name="contact_email", + ), + migrations.RemoveField( + model_name="apppackage", + name="contact_link", + ), + migrations.RemoveField( + model_name="apppackage", + name="development_stage", + ), + migrations.RemoveField( + model_name="apppackage", + name="homepage_url", + ), + migrations.RemoveField( + model_name="apppackage", + name="license_type", + ), + migrations.RemoveField( + model_name="apppackage", + name="long_description_type", + ), + migrations.RemoveField( + model_name="apppackage", + name="pypi_url", + ), + migrations.RemoveField( + model_name="apppackage", + name="repository_url", + ), + migrations.RemoveField( + model_name="apppackage", + name="short_description", + ), + migrations.RemoveField( + model_name="apppackage", + name="support_url", + ), + migrations.RemoveField( + model_name="apppackage", + name="sync_with_pypi", + ), + migrations.RemoveField( + model_name="apppackage", + name="versions", + ), + migrations.AddField( + model_name="apppackage", + name="app_config_script", + field=conreq._core.fields.PythonTextField( + blank=True, + help_text="Python code that will be run after boot up. This code is run directly within the context of an arbitrary `AppConfig.ready()` method. If you need revision control for this script, create a dedicated `AppConfig` in your package release instead.", + ), + ), + migrations.AddField( + model_name="apppackage", + name="custom_pip_install", + field=models.TextField( + blank=True, + help_text="Custom pip install command. If left blank, the default `pip install ` will be used.", + ), + ), + migrations.AddField( + model_name="apppackage", + name="developed", + field=models.BooleanField( + default=False, + help_text="Whether or not this app has been developed. If not, it is a placeholder app.", + ), + ), + migrations.AddField( + model_name="apppackage", + name="listed_on_pypi", + field=models.BooleanField( + default=False, + help_text="Whether or not this app is listed on PyPI. If not, it is a placeholder app.", + ), + ), + migrations.AddField( + model_name="apppackage", + name="pypi_name", + field=models.CharField( + blank=True, + help_text="Name used for PyPI package installation. Defaults to `pkg_name` if left blank.", + max_length=100, + ), + ), + migrations.AddField( + model_name="apppackage", + name="settings_script", + field=conreq._core.fields.PythonTextField( + blank=True, + help_text="Python code that will be run before boot up. This code is run directly within the context of Conreq's `settings.py`. If you need revision control for this script, create a dedicated `conreq_settings.py` file in your package release instead.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="conreq_max_version", + field=versionfield.fields.VersionField( + blank=True, + help_text="Maximum version Conreq can be to support this package.", + null=True, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="conreq_min_version", + field=versionfield.fields.VersionField( + default="0.0.0", + help_text="Minimum version Conreq needs to be to support this package.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="incompatible_apps", + field=models.ManyToManyField( + blank=True, + help_text="Conreq apps that cannot be installed for this package to function.", + to="app_store.apppackage", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="long_description", + field=models.TextField( + blank=True, + help_text="This description is hidden from the app info modal, but is viewable within the database admin GUI.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="min_version", + field=versionfield.fields.VersionField( + default="0.0.0", + help_text="Minimum version of this package that is compatible with Conreq.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="pkg_name", + field=models.CharField( + help_text="Must be snake_case. Importable name within Python.", + max_length=100, + unique=True, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="related_apps", + field=models.ManyToManyField( + blank=True, + help_text="Conreq apps that are related to this project.", + to="app_store.apppackage", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="required_apps", + field=models.ManyToManyField( + blank=True, + help_text="Conreq apps that must be installed for this package to function.", + to="app_store.apppackage", + ), + ), + migrations.DeleteModel( + name="PackageVersion", + ), + migrations.AddField( + model_name="apppackage", + name="pypi_data", + field=conreq._core.fields.AutoOneToOneField( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="app_store.pypidata", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0044_rename_long_description_apppackage_hidden_description.py b/conreq/_core/app_store/migrations/0044_rename_long_description_apppackage_hidden_description.py new file mode 100644 index 00000000..c3c918fc --- /dev/null +++ b/conreq/_core/app_store/migrations/0044_rename_long_description_apppackage_hidden_description.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0043_pypidata_remove_apppackage_asynchronous_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="long_description", + new_name="hidden_description", + ), + ] diff --git a/conreq/_core/app_store/migrations/0045_rename_custom_pip_install_apppackage_custom_pip_install_command_and_more.py b/conreq/_core/app_store/migrations/0045_rename_custom_pip_install_apppackage_custom_pip_install_command_and_more.py new file mode 100644 index 00000000..09d0360d --- /dev/null +++ b/conreq/_core/app_store/migrations/0045_rename_custom_pip_install_apppackage_custom_pip_install_command_and_more.py @@ -0,0 +1,108 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:15 + +import conreq._core.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0044_rename_long_description_apppackage_hidden_description"), + ] + + operations = [ + migrations.RenameField( + model_name="apppackage", + old_name="custom_pip_install", + new_name="custom_pip_install_command", + ), + migrations.RenameField( + model_name="apppackage", + old_name="min_version", + new_name="package_min_version", + ), + migrations.RemoveField( + model_name="apppackage", + name="app_config_script", + ), + migrations.RemoveField( + model_name="apppackage", + name="developed", + ), + migrations.RemoveField( + model_name="apppackage", + name="pkg_name", + ), + migrations.AddField( + model_name="apppackage", + name="app_ready_script", + field=conreq._core.fields.PythonTextField( + blank=True, + help_text="Python code that will be run after boot up. This code is run directly within the context of Conreq's `AppLoaderConfig.ready()` method. If you need revision control, create a dedicated `AppConfig` in your package release instead. Please note that this script will run once for each webserver worker.", + ), + ), + migrations.AddField( + model_name="apppackage", + name="package_name", + field=models.CharField( + blank=True, + help_text="Must be snake_case. Importable name within Python. If blank, it is a placeholder app.", + max_length=100, + null=True, + unique=True, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="banner_message", + field=models.TextField( + blank=True, + help_text="Optional text message shown on the app's details.", + max_length=1000, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="donation_url", + field=models.URLField( + blank=True, + help_text="Link where users can donate to this app's authors.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="hidden_description", + field=models.TextField( + blank=True, + help_text="This description is only viewable within the database admin GUI.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="listed_on_pypi", + field=models.BooleanField( + default=False, help_text="Whether or not this app is listed on PyPI." + ), + ), + migrations.AlterField( + model_name="apppackage", + name="name", + field=models.CharField(help_text="Human readable name.", max_length=100), + ), + migrations.AlterField( + model_name="apppackage", + name="pypi_name", + field=models.CharField( + blank=True, + help_text="Name used for PyPI package installation. Defaults to `package_name` if left blank.", + max_length=100, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="settings_script", + field=conreq._core.fields.PythonTextField( + blank=True, + help_text="Python code that will be run before boot up. This code is run directly within the context of Conreq's `settings.py`. If you need revision control, create a dedicated `conreq_settings.py` file in your package release instead.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0046_alter_apppackage_custom_pip_install_command.py b/conreq/_core/app_store/migrations/0046_alter_apppackage_custom_pip_install_command.py new file mode 100644 index 00000000..8d8d0afa --- /dev/null +++ b/conreq/_core/app_store/migrations/0046_alter_apppackage_custom_pip_install_command.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ( + "app_store", + "0045_rename_custom_pip_install_apppackage_custom_pip_install_command_and_more", + ), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="custom_pip_install_command", + field=models.TextField( + blank=True, + help_text="Custom pip install command. If left blank, the default `pip install pypi_name` will be used.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0047_alter_apppackage_donation_url_and_more.py b/conreq/_core/app_store/migrations/0047_alter_apppackage_donation_url_and_more.py new file mode 100644 index 00000000..11f41118 --- /dev/null +++ b/conreq/_core/app_store/migrations/0047_alter_apppackage_donation_url_and_more.py @@ -0,0 +1,39 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0046_alter_apppackage_custom_pip_install_command"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="donation_url", + field=models.URLField( + blank=True, + help_text="Link where users can donate to this app's author.", + ), + ), + migrations.AlterField( + model_name="apppackage", + name="package_name", + field=models.CharField( + blank=True, + help_text="Importable name within Python. Must be snake_case.If blank, it is a placeholder app.", + max_length=100, + null=True, + unique=True, + ), + ), + migrations.AlterField( + model_name="apppackage", + name="special", + field=models.BooleanField( + default=False, + help_text="If enabled, this app's cards will be visually highlighted. Typically reserved for unique situations, such as authors who have donated to Conreq.", + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0048_alter_apppackage_package_name.py b/conreq/_core/app_store/migrations/0048_alter_apppackage_package_name.py new file mode 100644 index 00000000..ff72346f --- /dev/null +++ b/conreq/_core/app_store/migrations/0048_alter_apppackage_package_name.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0047_alter_apppackage_donation_url_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="apppackage", + name="package_name", + field=models.CharField( + blank=True, + help_text="Importable name within Python. Must be snake_case. If blank, it is a placeholder app.", + max_length=100, + null=True, + unique=True, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0049_remove_apppackage_listed_on_pypi_and_more.py b/conreq/_core/app_store/migrations/0049_remove_apppackage_listed_on_pypi_and_more.py new file mode 100644 index 00000000..bbb57205 --- /dev/null +++ b/conreq/_core/app_store/migrations/0049_remove_apppackage_listed_on_pypi_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0048_alter_apppackage_package_name"), + ] + + operations = [ + migrations.RemoveField( + model_name="apppackage", + name="listed_on_pypi", + ), + migrations.AlterField( + model_name="apppackage", + name="pypi_name", + field=models.CharField( + blank=True, + help_text="Name used for PyPI package installation. Defaults to `package_name` if left blank. You can set this to N/A to indicate that this app is not listed on PyPI.", + max_length=100, + ), + ), + ] diff --git a/conreq/_core/app_store/migrations/0050_alter_pypidata_options.py b/conreq/_core/app_store/migrations/0050_alter_pypidata_options.py new file mode 100644 index 00000000..bc6e957c --- /dev/null +++ b/conreq/_core/app_store/migrations/0050_alter_pypidata_options.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("app_store", "0049_remove_apppackage_listed_on_pypi_and_more"), + ] + + operations = [ + migrations.AlterModelOptions( + name="pypidata", + options={ + "verbose_name": "App PyPI data", + "verbose_name_plural": "App PyPI data", + }, + ), + ] diff --git a/conreq/core/api/migrations/__init__.py b/conreq/_core/app_store/migrations/__init__.py similarity index 100% rename from conreq/core/api/migrations/__init__.py rename to conreq/_core/app_store/migrations/__init__.py diff --git a/conreq/_core/app_store/models.py b/conreq/_core/app_store/models.py new file mode 100644 index 00000000..b25ce1bc --- /dev/null +++ b/conreq/_core/app_store/models.py @@ -0,0 +1,370 @@ +import importlib +import platform +import uuid + +from django.contrib.auth import get_user_model +from django.db import models +from multiselectfield import MultiSelectField +from ordered_model.fields import OrderedManyToManyField +from ordered_model.models import OrderedModel +from packaging import version +from versionfield import VersionField + +from conreq._core.fields import AutoOneToOneField, PythonTextField +from conreq.utils.environment import get_env +from conreq.utils.models import UUIDFilePath + + +class DevelopmentStage(models.TextChoices): + PLANNING = "1 - Planning", "Planning" + PREALPHA = "2 - Pre-Alpha", "Pre-Alpha" + ALPHA = "3 - Alpha", "Alpha" + BETA = "4 - Beta", "Beta" + STABLE = "5 - Production/Stable", "Stable" + MATURE = "6 - Mature", "Mature" + INACTIVE = "7 - Inactive", "Inactive" + + +class AsyncCompatibility(models.TextChoices): + NONE = "No Async", "No Async" + SEMI = "Semi Async", "Semi Async" + FULL = "Fully Async", "Fully Async" + + +class SysPlatform(models.TextChoices): + ANY = "Any", "Any" + LINUX = "Linux", "Linux" + WINDOWS = "Windows", "Windows" + MACOS = "Darwin", "MacOS" + FREEBSD = "FreeBSD", "FreeBSD" + + +class DescriptionType(models.TextChoices): + TXT = "text/plain", "Plain Text (.txt)" + RST = "text/x-rst", "reStructuredText (.rst)" + MD = "text/markdown", "Markdown (.md)" + + +class Category(OrderedModel): + def __str__(self): + return str(self.name) + + class Meta: + verbose_name_plural = "Categories" + ordering = ["order"] + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + # Basic Info + name = models.CharField(max_length=50, unique=True) + + +class Subcategory(models.Model): + def __str__(self): + return str(self.name) + + class Meta: + verbose_name = "Subcategory" + verbose_name_plural = "Subcategories" + unique_together = ["name", "category"] + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + # Basic Info + name = models.CharField(max_length=50) + category = models.ForeignKey(Category, on_delete=models.CASCADE) + + +class PyPiData(models.Model): + class Meta: + verbose_name = "App PyPI data" + verbose_name_plural = "App PyPI data" + + author = models.CharField(blank=True, max_length=50) + author_email = models.EmailField(blank=True) + development_status = models.CharField( + blank=True, + max_length=21, + choices=DevelopmentStage.choices, + default=DevelopmentStage.PLANNING, + ) + description = models.TextField(blank=True) + description_content_type = models.CharField( + blank=True, + max_length=20, + choices=DescriptionType.choices, + default=DescriptionType.TXT, + ) + keywords = models.TextField(blank=True) + license = models.CharField(blank=True, max_length=100) + maintainer = models.CharField(blank=True, max_length=50) + maintainer_email = models.EmailField(blank=True) + package_url = models.URLField(blank=True) + requires_python = models.CharField(blank=True, max_length=50) + summary = models.CharField(blank=True, max_length=255) + version = VersionField(blank=True) + releases = models.JSONField(blank=True) + + # State tracking + loaded = models.BooleanField(default=False) + modified_at = models.DateTimeField(auto_now=True, editable=False) + + def load(self): + """Loads the PyPiData from PyPi.""" + if not self.app_package.package_name or self.app_package.pypi_name == "N/A": + return + + # pylint: disable=import-outside-toplevel + import requests + + # Get PyPi data + response = requests.get( + f"https://pypi.org/pypi/{self.app_package.pypi_name or self.app_package.pkg_name}/json" + ) + data = response.json() + + # Update fields + self.author = data["info"]["author"] + self.author_email = data["info"]["author_email"] + self.development_status = data["info"]["development_status"] + self.description = data["info"]["description"] + self.description_content_type = data["info"]["description_content_type"] + self.keywords = data["info"]["keywords"] + self.license = data["info"]["license"] + self.maintainer = data["info"]["maintainer"] + self.maintainer_email = data["info"]["maintainer_email"] + self.package_url = data["info"]["package_url"] + self.requires_python = data["info"]["requires_python"] + self.summary = data["info"]["summary"] + self.version = data["info"]["version"] + self.releases = data["releases"] or {} + + # Mark as loaded + self.loaded = True + + # Save + self.save() + + +class AppPackage(models.Model): + def __str__(self): + return str(self.name) + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + # General Info + name = models.CharField(max_length=100, help_text="Human readable name.") + logo = models.ImageField( + upload_to=UUIDFilePath("serve/app_store/logos/"), + blank=True, + ) + background = models.ImageField( + upload_to=UUIDFilePath("serve/app_store/backgrounds/"), + blank=True, + ) + package_name = models.CharField( + max_length=100, + help_text="Importable name within Python. Must be snake_case. " + "If blank, it is a placeholder app.", + unique=True, + blank=True, + null=True, + ) + pypi_name = models.CharField( + max_length=100, + help_text="Name used for PyPI package installation. Defaults to `package_name` if left blank. " + "You can set this to N/A to indicate that this app is not listed on PyPI.", + blank=True, + ) + custom_pip_install_command = models.TextField( + help_text="Custom pip install command. " + "If left blank, the default `pip install pypi_name` will be used.", + blank=True, + ) + special = models.BooleanField( + default=False, + help_text="If enabled, this app's cards will be visually highlighted. " + "Typically reserved for unique situations, such as authors who have donated to Conreq.", + ) + + banner_message = models.TextField( + blank=True, + help_text="Optional text message shown on the app's details.", + max_length=1000, + ) + hidden_description = models.TextField( + blank=True, + help_text="This description is only viewable within the database admin GUI.", + ) + donation_url = models.URLField( + blank=True, help_text="Link where users can donate to this app's author." + ) + subcategories = models.ManyToManyField(Subcategory) + + # Compatibility + sys_platforms = MultiSelectField( + choices=SysPlatform.choices, + max_length=40, + verbose_name="Supported Platforms", + default=SysPlatform.ANY, + ) + touch_compatible = models.BooleanField() + mobile_compatible = models.BooleanField() + package_min_version = VersionField( + default="0.0.0", + help_text="Minimum version of this package that is compatible with Conreq.", + ) + conreq_min_version = VersionField( + default="0.0.0", + help_text="Minimum version Conreq needs to be to support this package.", + ) + conreq_max_version = VersionField( + help_text="Maximum version Conreq can be to support this package.", + blank=True, + null=True, + ) + required_apps = models.ManyToManyField( + "self", + help_text="Conreq apps that must be installed for this package to function.", + blank=True, + ) + incompatible_apps = models.ManyToManyField( + "self", + help_text="Conreq apps that cannot be installed for this package to function.", + blank=True, + ) + related_apps = models.ManyToManyField( + "self", + help_text="Conreq apps that are related to this project.", + blank=True, + ) + + # Start Up + settings_script = PythonTextField( + blank=True, + help_text="Python code that will be run before boot up. " + "This code is run directly within the context of Conreq's `settings.py`. " + "If you need revision control, create a dedicated `conreq_settings.py` file in your package release instead.", + ) + app_ready_script = PythonTextField( + blank=True, + help_text="Python code that will be run after boot up. " + "This code is run directly within the context of Conreq's `AppLoaderConfig.ready()` method. " + "If you need revision control, create a dedicated `AppConfig` in your package release instead. " + "Please note that this script will run once for each webserver worker.", + ) + + # Metadata + created_at = models.DateTimeField(auto_now_add=True, editable=False) + modified_at = models.DateTimeField(auto_now=True, editable=False) + pypi_data = AutoOneToOneField( + PyPiData, blank=True, null=True, on_delete=models.CASCADE, editable=False + ) + + @property + def installed(self): + """Checks if the app is already installed on the current system.""" + return self.package_name in get_env("INSTALLED_PACKAGES", [], return_type=list) + + @property + def compatible(self): + """Checks if the app is installable on the current system.""" + # pylint: disable=import-outside-toplevel + from django.conf import settings + + # Invalid development stage + if self.pypi_data and ( + not self.pypi_data.development_status + or self.pypi_data.development_status == DevelopmentStage.PLANNING + ): + return False + + # Incorrect system platform + if ( + SysPlatform.ANY not in self.sys_platforms + and platform.system() not in self.sys_platforms + ): + return False + + # Incompatible Conreq version + if version.parse(str(self.conreq_min_version)) > version.parse( + str(settings.CONREQ_VERSION) + ) or ( + self.conreq_max_version + and version.parse(str(self.conreq_max_version)) + < version.parse(str(settings.CONREQ_VERSION)) + ): + return False + + # Incompatible app is installed + return not any( + importlib.util.find_spec(app.package_name) + for app in self.incompatible_apps.all() # pylint: disable=no-member + ) + + +class SpotlightCategory(OrderedModel): + def __str__(self): + return str(self.name) + + class Meta: + verbose_name = "Spotlight category" + verbose_name_plural = "Spotlight categories" + ordering = ["order"] + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + name = models.CharField(max_length=50, unique=True) + description = models.TextField(blank=True) + apps = OrderedManyToManyField(AppPackage, through="SpotlightAppPackages") + + +class SpotlightAppPackages(OrderedModel): + """This model is a `through` model used to create a many-to-many relationship + between SpotlightCategory and AppPackage. + This allows for the ordering of apps within a spotlight category.""" + + category = models.ForeignKey(SpotlightCategory, on_delete=models.CASCADE) + app = models.ForeignKey(AppPackage, on_delete=models.CASCADE) + order_with_respect_to = "category" + + class Meta: + ordering = ("category", "order") + + +class Screenshot(models.Model): + def __str__(self): + return str(self.title) + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + title = models.CharField(max_length=100) + description = models.CharField(max_length=255, blank=True) + image = models.ImageField(upload_to=UUIDFilePath("serve/app_store/screenshot/")) + app_package = models.ForeignKey(AppPackage, on_delete=models.CASCADE) + + +class AppNoticeMessage(models.Model): + """Message that needs to be delivered to admins that currently have the app installed.""" + + def __str__(self): + return str(self.title) + + uuid = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True + ) + + title = models.CharField(max_length=100) + description = models.TextField(blank=True) + app_package = models.ForeignKey(AppPackage, on_delete=models.CASCADE) + read_by = models.ManyToManyField(get_user_model(), blank=True) diff --git a/conreq/_core/app_store/static/conreq/app_store.css b/conreq/_core/app_store/static/conreq/app_store.css new file mode 100644 index 00000000..05b1a696 --- /dev/null +++ b/conreq/_core/app_store/static/conreq/app_store.css @@ -0,0 +1,45 @@ +.viewport-container.app-store { + display: flex; + flex-direction: column; +} + +/* Nav Region */ + +.nav-btn { + border: 1px #ffffff61 solid !important; + border-radius: 80px; +} + +.nav-region { + margin-top: 30px; + padding: 0 var(--viewport-padding); + display: flex; +} + +.nav-region .btn { + margin-right: 15px; +} + +.nav-region .btn.return { + margin-left: auto; +} + +.dropdown-menu li { + position: relative; +} + +.dropdown-menu .dropdown-submenu { + display: none; + position: absolute; + left: 100%; + top: -7px; +} + +.dropdown-menu .dropdown-submenu-left { + right: 100%; + left: auto; +} + +.dropdown-menu > li:hover > .dropdown-submenu { + display: block; +} diff --git a/conreq/_core/app_store/static/conreq/app_store_card.css b/conreq/_core/app_store/static/conreq/app_store_card.css new file mode 100644 index 00000000..af0699c5 --- /dev/null +++ b/conreq/_core/app_store/static/conreq/app_store_card.css @@ -0,0 +1,125 @@ +.card { + --border-radius: 8px; + --border-size: 1px; + --border-color: #27464a; + --card-bg: #161616; + color: #fff; + background: var(--card-bg); + border-radius: var(--border-radius); + border: var(--border-size) solid var(--border-color); + height: 225px; + width: 380px; + padding: 20px; + margin-right: 20px; + margin-bottom: 20px; + display: inline-block; + z-index: 1; +} + +.card.fade-in { + transition: opacity 1.25s ease; +} + +.card .background { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-size: cover; + background-position: center; + opacity: 0.2; + z-index: -1; + overflow: hidden; + border-radius: var(--border-radius); + -webkit-filter: blur(3px); + filter: blur(3px); +} + +.card > .top { + display: grid; + grid-template-columns: auto 80px; +} + +.card > .top > .text-region { + margin-right: 5px; +} + +.card > .top > .text-region > * { + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + display: -webkit-box; + overflow: hidden; + padding-bottom: 2px; +} + +.card > .top > .text-region > .card-title { + margin-bottom: 5px; +} + +.card > .top > .logo { + display: inline-block; + position: relative; + height: 80px; + width: 80px; + background: #1c1c1c; + background-size: cover; +} + +.card > .btn-container { + margin-bottom: 10px; +} + +.card > .btn-container > .btn { + margin-right: 5px; +} + +.card > .description { + padding-bottom: 2px; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + display: -webkit-box; + overflow: hidden; + line-height: 1.2; +} + +/* Spinny Colors */ +/* Credits: https://codepen.io/MauriciAbad/pen/WNrpmPr */ +@-webkit-keyframes spin { + from { + transform: translate(-50%, -50%) rotate(0); + } + + to { + transform: translate(-50%, -50%) rotate(360deg); + } +} +@keyframes spin { + from { + transform: translate(-50%, -50%) rotate(0); + } + + to { + transform: translate(-50%, -50%) rotate(360deg); + } +} + +.card.special { + --animation-speed: 10s; + --card-bg-animation: conic-gradient(#000000ab, #00000036); + --border-color: #8b7234; + overflow: hidden; +} + +.card.special::before { + content: ""; + background: var(--card-bg-animation); + width: calc(100% * 1.41421356237); + padding-bottom: calc(100% * 1.41421356237); + position: absolute; + left: 50%; + top: 50%; + z-index: -2; + -webkit-animation: spin var(--animation-speed) linear infinite; + animation: spin var(--animation-speed) linear infinite; +} diff --git a/conreq/_core/app_store/static/conreq/app_store_filtered.css b/conreq/_core/app_store/static/conreq/app_store_filtered.css new file mode 100644 index 00000000..e160304a --- /dev/null +++ b/conreq/_core/app_store/static/conreq/app_store_filtered.css @@ -0,0 +1,9 @@ +/* Filtered Card View */ +.filtered-cards { + padding: var(--viewport-padding); + overflow-y: auto; + overflow-y: overlay; + width: 100%; + display: flex; + flex-wrap: wrap; +} diff --git a/conreq/_core/app_store/static/conreq/app_store_spotlight.css b/conreq/_core/app_store/static/conreq/app_store_spotlight.css new file mode 100644 index 00000000..d58ae360 --- /dev/null +++ b/conreq/_core/app_store/static/conreq/app_store_spotlight.css @@ -0,0 +1,55 @@ +/* Spotlight Region */ + +.spotlight { + padding-top: var(--viewport-padding); + width: 100%; +} + +.spotlight-section { + margin-bottom: 35px; + background: linear-gradient(90deg, #0000004d, #0000000d); + padding-top: 35px; + padding-bottom: 5px; + padding-left: var(--viewport-padding); +} + +.spotlight-head { + margin-bottom: 7px; + display: flex; + justify-content: space-between; + align-items: center; + color: #fff; + padding-right: calc(var(--viewport-padding) - 7px); +} + +.collapse-controls { + font-size: 25px; +} + +.collapse-controls > i { + padding: 0 6px; + margin: 0 2px; +} + +.spotlight .card-stage { + overflow: hidden; + height: 225px; + margin-bottom: 20px; +} + +.spotlight .card-stage.show-more { + height: auto; +} + +.spotlight .card-stage .collapse { + display: flex; + flex-flow: row; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + +.spotlight .card-stage.show-more .collapse { + flex-flow: wrap; + width: auto; +} diff --git a/conreq/_core/app_store/static/conreq/manage_apps.css b/conreq/_core/app_store/static/conreq/manage_apps.css new file mode 100644 index 00000000..44125d7b --- /dev/null +++ b/conreq/_core/app_store/static/conreq/manage_apps.css @@ -0,0 +1,3 @@ +.manage-apps { + padding: var(--viewport-padding); +} diff --git a/conreq/_core/app_store/static/conreq/package_details_modal.css b/conreq/_core/app_store/static/conreq/package_details_modal.css new file mode 100644 index 00000000..e924eefb --- /dev/null +++ b/conreq/_core/app_store/static/conreq/package_details_modal.css @@ -0,0 +1,41 @@ +.modal .banner { + background: #995f00; + text-align: center; + padding: 5px; + margin: 15px; + margin-bottom: 0; + border-radius: 4px; +} + +.modal .carousel { + margin: 15px 0; + background: rgb(0 0 0 / 25%); +} + +.modal .carousel-item { + height: 300px; +} + +.modal .carousel-item img { + height: 100%; + margin: auto; +} + +.modal .description { + margin: 30px 15px 15px 15px; + background: rgb(0 0 0 / 25%); + border-radius: 8px; + padding: 15px; +} + +.modal .info-table-container { + margin: 15px; + padding: 15px; + background: rgb(0 0 0 / 25%); + border-radius: 8px; + display: inline-block; +} + +.modal .info-table th { + padding-right: 25px; +} diff --git a/conreq/_core/app_store/static/conreq/package_install_modal.css b/conreq/_core/app_store/static/conreq/package_install_modal.css new file mode 100644 index 00000000..d5bbe6c9 --- /dev/null +++ b/conreq/_core/app_store/static/conreq/package_install_modal.css @@ -0,0 +1,35 @@ +.confirm { + margin: 15px; +} + +.terminal { + font-family: monospace; + margin: 15px; + padding: 15px; + border-radius: 8px; + background: black; + min-height: 300px; + height: 300px; + max-height: 300px; + line-height: 1.35; + white-space: nowrap; + overflow: scroll; + -ms-scroll-snap-type: y proximity; + scroll-snap-type: y proximity; +} + +.terminal p { + margin-bottom: 0; +} + +.terminal p:last-child { + scroll-snap-align: end; +} + +.terminal p.success { + color: #00ff00; +} + +.terminal p.error { + color: #ff0000; +} diff --git a/conreq/core/arrs/__init__.py b/conreq/_core/backup/__init__.py similarity index 100% rename from conreq/core/arrs/__init__.py rename to conreq/_core/backup/__init__.py diff --git a/conreq/_core/backup/apps.py b/conreq/_core/backup/apps.py new file mode 100644 index 00000000..67a8bf42 --- /dev/null +++ b/conreq/_core/backup/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BackupConfig(AppConfig): + name = "conreq._core.backup" diff --git a/conreq/_core/backup/tasks.py b/conreq/_core/backup/tasks.py new file mode 100644 index 00000000..78351f23 --- /dev/null +++ b/conreq/_core/backup/tasks.py @@ -0,0 +1,18 @@ +from huey.contrib.djhuey import db_periodic_task, db_task + +from conreq.types import Seconds +from conreq.utils.backup import backup_needed, backup_now + + +@db_periodic_task(Seconds.day) +def backup_check(): + """Backup the database on a schedule.""" + if backup_needed(): + backup_now() + + +@db_task() +def backup_if_needed(): + """Performs a backup if the last backup was longer than the threshold.""" + if backup_needed(): + backup_now() diff --git a/conreq/core/base/__init__.py b/conreq/_core/base/__init__.py similarity index 100% rename from conreq/core/base/__init__.py rename to conreq/_core/base/__init__.py diff --git a/conreq/_core/base/apps.py b/conreq/_core/base/apps.py new file mode 100644 index 00000000..eafeeb0b --- /dev/null +++ b/conreq/_core/base/apps.py @@ -0,0 +1,47 @@ +from sqlite3 import Connection + +from django.apps import AppConfig +from django.db.backends.signals import connection_created +from reactpy.html import i + +from conreq import config +from conreq.types import NavGroup +from conreq.utils.modules import import_module + + +class BaseConfig(AppConfig): + name = "conreq._core.base" + + def ready(self): + # pylint: disable=import-outside-toplevel + from reactpy_django import REACTPY_WEBSOCKET_ROUTE + + config.asgi.websockets.append(REACTPY_WEBSOCKET_ROUTE) + config.homepage.sidebar_tabs.add( + NavGroup(name="User", icon=i({"class_name": "fas fa-users icon-left"})) + ) + config.homepage.sidebar_tabs.add( + NavGroup(name="Admin", icon=i({"class_name": "fas fa-cogs icon-left"})) + ) + import_module("conreq.config.wrappers.components") + + +# pylint: disable=unused-argument +@connection_created.connect +def sqlite_connect(sender, connection: Connection, **kwargs): + """Enable integrity constraint with sqlite.""" + if getattr(connection, "vendor", None) == "sqlite": + cursor = connection.cursor() + cursor.execute("PRAGMA journal_mode = WAL;") + cursor.execute("PRAGMA synchronous = NORMAL;") + cursor.execute("PRAGMA temp_store = MEMORY;") + cursor.execute("PRAGMA foreign_keys = ON;") + + +@connection_created.disconnect +def sqlite_disconnect(sender, connection: Connection, **kwargs): + """Enable integrity constraint with sqlite.""" + if getattr(connection, "vendor", None) == "sqlite": + cursor = connection.cursor() + cursor.execute("PRAGMA analysis_limit = 400;") + cursor.execute("PRAGMA optimize;") diff --git a/conreq/core/base/management/__init__.py b/conreq/_core/base/management/__init__.py similarity index 100% rename from conreq/core/base/management/__init__.py rename to conreq/_core/base/management/__init__.py diff --git a/conreq/core/base/management/commands/__init__.py b/conreq/_core/base/management/commands/__init__.py similarity index 100% rename from conreq/core/base/management/commands/__init__.py rename to conreq/_core/base/management/commands/__init__.py diff --git a/conreq/_core/base/management/commands/build_docs.py b/conreq/_core/base/management/commands/build_docs.py new file mode 100644 index 00000000..41963a4b --- /dev/null +++ b/conreq/_core/base/management/commands/build_docs.py @@ -0,0 +1,17 @@ +from subprocess import run + +from django.conf import settings +from django.core.management.base import BaseCommand + +DOCS_DIR = getattr(settings, "ROOT_DIR") / "docs" + + +class Command(BaseCommand): + help = "Builds the docs using MkDocs." + + def handle(self, *args, **options): + run( + ["mkdocs", "build", "-d", DOCS_DIR / "output"], + cwd=DOCS_DIR / "source", + check=True, + ) diff --git a/conreq/_core/base/management/commands/preconfig_conreq.py b/conreq/_core/base/management/commands/preconfig_conreq.py new file mode 100644 index 00000000..26704d62 --- /dev/null +++ b/conreq/_core/base/management/commands/preconfig_conreq.py @@ -0,0 +1,128 @@ +import logging +import os +import shutil +import sqlite3 +import sys + +from django.conf import settings +from django.core.management.base import BaseCommand + +from conreq.utils.environment import get_database_engine, get_debug_mode + +_logger = logging.getLogger(__name__) + +DEBUG = get_debug_mode() +ROOT_DIR = getattr(settings, "ROOT_DIR") +DATA_DIR = getattr(settings, "DATA_DIR") +TEMP_DIR = getattr(settings, "TEMP_DIR") +DATABASES = getattr(settings, "DATABASES") +HUEY_FILENAME = getattr(settings, "HUEY_FILENAME") + + +def vprint(message, verbosity): + if verbosity != 0: + _logger.info(message) + + +class Command(BaseCommand): + """Executes functions that may require admin privileges, + since it is expected that run_conreq is executed as a user.""" + + help = "Runs code that may be required prior to run_conreq Conreq." + + def handle(self, *args, **options): + uid = options["uid"] + gid = options["gid"] + no_perms = options["no_perms"] + verbosity = options["verbosity"] + + # Delete temp files + if TEMP_DIR.exists(): + shutil.rmtree(TEMP_DIR) + os.makedirs(TEMP_DIR) + + # Django database + if get_database_engine() == "SQLITE3": + database = DATABASES["default"]["NAME"] + self.setup_sqlite_database( + database, "Conreq", uid, gid, no_perms, verbosity + ) + + # Background task database + if HUEY_FILENAME: + self.setup_sqlite_database( + HUEY_FILENAME, "Background Task", uid, gid, no_perms, verbosity + ) + + if not no_perms and sys.platform == "linux": + # Conreq data dir + self.recursive_chown(DATA_DIR, uid, gid, verbosity) + + # Conreq core dir + self.recursive_chown(ROOT_DIR, uid, gid, verbosity) + + def add_arguments(self, parser): + parser.add_argument( + "uid", + nargs="?", + help="User ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", + type=int, + default=0, + ) + parser.add_argument( + "gid", + nargs="?", + help="Group ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", + type=int, + default=0, + ) + parser.add_argument( + "--no-perms", + action="store_true", + help="Prevent Conreq from setting permissions.", + ) + + @staticmethod + def setup_sqlite_database(path, name, uid, gid, no_perms, verbosity): + vprint("Preconfiguring " + name.rstrip(" ") + " Database", verbosity) + if not path.exists(): + vprint("[X] Creating database", verbosity) + with sqlite3.connect(path) as cursor: + vprint("[X] Vacuuming database", verbosity) + cursor.execute("VACUUM;") + vprint("[X] Configuring database", verbosity) + cursor.execute("PRAGMA journal_mode = WAL;") + if not no_perms and (uid != -1 or gid != -1) and sys.platform == "linux": + # pylint: disable=no-member + print("[X] Applying permissions") + new_uid = uid or os.getuid() # type: ignore + new_gid = gid or os.getgid() # type: ignore + os.chown(path, new_uid, new_gid) # type: ignore + + @staticmethod + def recursive_chown(path, uid, gid, verbosity): + vprint(f'[X] Recursively applying permissions to "{path}"', verbosity) + new_uid = uid if uid != -1 else None + new_gid = gid if gid != -1 else None + if uid != -1 or gid != -1: + # pylint: disable=unused-variable + for dirpath, dirnames, filenames in os.walk(path): + try: + shutil.chown(dirpath, new_uid, new_gid) + try: + for filename in filenames: + shutil.chown( + os.path.join(dirpath, filename), new_uid, new_gid + ) + except FileNotFoundError: + print( + 'Unable to apply permissions to "' + + os.path.join(dirpath, filename) + + '". File not found.' + ) + except PermissionError: + print( + 'Unable to apply permissions to "' + + dirpath + + '". Permission denied.' + ) diff --git a/conreq/_core/base/management/commands/run_conreq.py b/conreq/_core/base/management/commands/run_conreq.py new file mode 100644 index 00000000..34ecdd28 --- /dev/null +++ b/conreq/_core/base/management/commands/run_conreq.py @@ -0,0 +1,183 @@ +import contextlib +import os +import signal +import subprocess +import sys + +import uvicorn +from django.conf import settings +from django.core.cache import cache +from django.core.management import call_command +from django.core.management.base import BaseCommand +from django.core.management.utils import get_random_secret_key +from uvicorn.config import LOGGING_CONFIG as UVICORN_LOGGING_CONFIG + +from conreq import config +from conreq.utils.backup import backup_needed, backup_now +from conreq.utils.environment import get_debug_mode, get_env, set_env + +HUEY_PID_FILE = getattr(settings, "PID_DIR") / "huey.pid" +DEBUG = get_debug_mode() + + +class Command(BaseCommand): + help = "Runs all commands needed to safely start Conreq." + + def handle(self, *args, **options): + # pylint: disable=attribute-defined-outside-init + self.bind = ( + options["bind"] + or f"{get_env('HOST_IP', '0.0.0.0')}:{get_env('HOST_PORT', '7575')}" + ) + self.host = self.bind.split(":")[0] + self.port = int(self.bind.split(":")[1]) + verbosity = "-v 1" if DEBUG else "-v 0" + + # Run any preconfiguration tasks + if not options["disable_preconfig"]: + preconfig_args = [ + "preconfig_conreq", + options["uid"], + options["gid"], + ] + if not options["set_perms"]: + preconfig_args.append("--no-perms") + call_command(*preconfig_args, verbosity) + + # Execute tests to ensure Conreq is healthy before starting + if not options["skip_checks"]: + call_command("check") + if options["test"]: + call_command("test", "--noinput", "--parallel", "--failfast") + + # Queue a task to backup the database if needed + if backup_needed(): + backup_now() + + # Perform any debug related clean-up + if DEBUG: + print("Conreq is in DEBUG mode.") + print("Clearing cache...") + cache.clear() + + # Migrate the database + for database in settings.DATABASES.keys(): + call_command( + "migrate", + "--database", + database, + "--noinput", + verbosity, + ) + + if not DEBUG: + # Collect static files + call_command("collectstatic", "--link", "--clear", "--noinput", verbosity) + call_command("compress", "--force", verbosity) + + # Rotate the secret key if needed + if get_env("ROTATE_SECRET_KEY", return_type=bool): + set_env("WEB_ENCRYPTION_KEY", get_random_secret_key()) + + # Run background task management + self.stop_huey() + proc = self.start_huey() + if proc.pid: + with open(HUEY_PID_FILE, "w", encoding="utf-8") as huey_pid: + huey_pid.write(str(proc.pid)) + + # Run pre-run functions before starting the webserver + for script in config.startup.functions: + script() + + # Run background processes before starting the webserver + for process in config.startup.processes: + process.start() + + # Run the webserver + self._run_webserver() + + def _run_webserver(self): + # pylint: disable=import-outside-toplevel + from conreq._core.server_settings.models import WebserverSettings + + # TODO: Add in Uvicorn's reverse proxy stuff + db_conf: WebserverSettings = WebserverSettings.get_solo() + debug = get_env("WEBSERVER_DEBUG", return_type=bool) + config_kwargs = { + "host": self.host, + "port": self.port, + "ssl_certfile": self._f_path(db_conf.ssl_certificate), + "ssl_keyfile": self._f_path(db_conf.ssl_key), + "ssl_ca_certs": self._f_path(db_conf.ssl_ca_certificate), + "log_config": UVICORN_LOGGING_CONFIG if debug else {"version": 1}, + "log_level": "debug" if debug else None, + "server_header": False, + "workers": settings.WEBSERVER_WORKERS, + "reload": debug, + "reload_dirs": [settings.ROOT_DIR], + } + + # Run the webserver + uvicorn.run("conreq.asgi:application", **config_kwargs) + + def add_arguments(self, parser): + parser.add_argument( + "-b", + "--bind", + help="Set the 'host_address:port' for Conreq to run on.", + default="0.0.0.0:7575", + type=str, + ) + parser.add_argument( + "--disable-preconfig", + action="store_true", + help="Disables Conreq's preconfiguration prior to startup.", + ) + parser.add_argument( + "--uid", + help="User ID for files and sockets (Linux only). Defaults to the current user. Use -1 to remain unchanged.", + type=int, + default=0, + ) + parser.add_argument( + "--gid", + help="Group ID for files and sockets (Linux only). Defaults to the current user. Use -1 to remain unchanged.", + type=int, + default=0, + ) + parser.add_argument( + "--set-perms", + action="store_true", + help="Have Conreq set file permissions during preconfig.", + ) + parser.add_argument( + "--test", + action="store_true", + help="Run tests before starting Conreq.", + ) + + @staticmethod + def start_huey(): + """Starts the Huey background task manager.""" + start_command = f"{sys.executable} manage.py run_huey --quiet" + return subprocess.Popen(start_command.split(" ")) + + @staticmethod + def stop_huey(): + """Stops the Huey background task manager. + Required to prevent duplicate Huey instances if using live reloading.""" + if not HUEY_PID_FILE.exists(): + return + + with open(HUEY_PID_FILE, encoding="utf-8") as huey_pid: + pid = int(huey_pid.read()) + if not pid: + return + with contextlib.suppress(OSError): + os.kill(pid, signal.SIGTERM) + + @staticmethod + def _f_path(model_obj): + if model_obj: + return model_obj.path diff --git a/conreq/_core/base/management/commands/serve_docs.py b/conreq/_core/base/management/commands/serve_docs.py new file mode 100644 index 00000000..eabb65aa --- /dev/null +++ b/conreq/_core/base/management/commands/serve_docs.py @@ -0,0 +1,13 @@ +from subprocess import run + +from django.conf import settings +from django.core.management.base import BaseCommand + +DOCS_SOURCE_DIR = getattr(settings, "ROOT_DIR") / "docs" / "source" + + +class Command(BaseCommand): + help = "Starts up the MkDocs preview webserver." + + def handle(self, *args, **options): + run(["mkdocs", "serve"], cwd=DOCS_SOURCE_DIR, check=True) diff --git a/conreq/_core/base/management/commands/start_app.py b/conreq/_core/base/management/commands/start_app.py new file mode 100644 index 00000000..52a8ae5b --- /dev/null +++ b/conreq/_core/base/management/commands/start_app.py @@ -0,0 +1,44 @@ +from pathlib import Path + +from django.conf import settings +from django.core.management.templates import TemplateCommand + +DEV_PACKAGES_DIR = getattr(settings, "DEV_PACKAGES_DIR") +APP_TEMPLATE = getattr(settings, "APP_TEMPLATE") +APP_SLIM_TEMPLATE = getattr(settings, "APP_SLIM_TEMPLATE") + + +class Command(TemplateCommand): + help = "Creates a Conreq app structure within a package." + + # pylint: disable=arguments-differ + def handle(self, app_name: str, **options): # type: ignore + package_name = options.get("package") or input( + "Name of the package this app will belong to: " + ).replace(" ", "_") + + name = app_name + app_or_project = "app" + target = str(DEV_PACKAGES_DIR / package_name / "apps" / "") + options["template"] = str( + APP_SLIM_TEMPLATE if options.get("slim") else APP_TEMPLATE + ) + options["extensions"] = ["py"] + options["files"] = [] + options["package_name"] = package_name + options["verbose_name"] = app_name.replace("_", " ").title() + super().handle(app_or_project, name, target, **options) + print( + f"Successfully created new app {app_name} in '{Path(target) / app_name}'." + ) + + def add_arguments(self, parser): + parser.add_argument("app_name", help="Name of the sub application.") + parser.add_argument( + "-p", "--package", help="Name of the application or project." + ) + parser.add_argument( + "--slim", + action="store_true", + help="Creates the bare minimum structure required.", + ) diff --git a/conreq/_core/base/management/commands/start_package.py b/conreq/_core/base/management/commands/start_package.py new file mode 100644 index 00000000..502ff401 --- /dev/null +++ b/conreq/_core/base/management/commands/start_package.py @@ -0,0 +1,41 @@ +from pathlib import Path +from typing import Any + +from django.conf import settings +from django.core.management.templates import TemplateCommand + +DEV_PACKAGES_DIR: Path = getattr(settings, "DEV_PACKAGES_DIR") +PACKAGE_TEMPLATE: Path = getattr(settings, "PACKAGE_TEMPLATE") +PACKAGE_SLIM_TEMPLATE: Path = getattr(settings, "PACKAGE_SLIM_TEMPLATE") + + +class Command(TemplateCommand): + help = "Creates a Conreq package structure with given name." + + # pylint: disable=arguments-differ + def handle(self, package_name: str, **options: dict[str, Any]): # type: ignore + name = package_name + app_or_project = "app" + target = str(DEV_PACKAGES_DIR / "") + options["template"] = str( + PACKAGE_SLIM_TEMPLATE if options.get("slim") else PACKAGE_TEMPLATE + ) # type: ignore + options["extensions"] = ["py", "txt"] # type: ignore + options["files"] = [] # type: ignore + options["package_name"] = package_name # type: ignore + options["verbose_name"] = package_name.replace("_", " ").title() # type: ignore + super().handle(app_or_project, name, target, **options) + print( + f"Successfully created new app package in '{DEV_PACKAGES_DIR / package_name}'." + ) + + def add_arguments(self, parser): + parser.add_argument( + "package_name", + help="Name of the new app.", + ) + parser.add_argument( + "--slim", + action="store_true", + help="Creates the bare minimum structure required.", + ) diff --git a/conreq/core/base/migrations/__init__.py b/conreq/_core/base/migrations/__init__.py similarity index 100% rename from conreq/core/base/migrations/__init__.py rename to conreq/_core/base/migrations/__init__.py diff --git a/conreq/_core/base/static/conreq/icons/android-chrome-192x192.png b/conreq/_core/base/static/conreq/icons/android-chrome-192x192.png new file mode 100644 index 00000000..146d27ea Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/android-chrome-192x192.png differ diff --git a/conreq/_core/base/static/conreq/icons/android-chrome-512x512.png b/conreq/_core/base/static/conreq/icons/android-chrome-512x512.png new file mode 100644 index 00000000..5a889359 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/android-chrome-512x512.png differ diff --git a/conreq/_core/base/static/conreq/icons/apple-touch-icon.png b/conreq/_core/base/static/conreq/icons/apple-touch-icon.png new file mode 100644 index 00000000..fb953f6c Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/apple-touch-icon.png differ diff --git a/conreq/_core/base/static/conreq/icons/browserconfig.xml b/conreq/_core/base/static/conreq/icons/browserconfig.xml new file mode 100644 index 00000000..3a99aa72 --- /dev/null +++ b/conreq/_core/base/static/conreq/icons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #171618 + + + diff --git a/conreq/_core/base/static/conreq/icons/favicon-16x16.png b/conreq/_core/base/static/conreq/icons/favicon-16x16.png new file mode 100644 index 00000000..d0a67c54 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/favicon-16x16.png differ diff --git a/conreq/_core/base/static/conreq/icons/favicon-32x32.png b/conreq/_core/base/static/conreq/icons/favicon-32x32.png new file mode 100644 index 00000000..da0129c7 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/favicon-32x32.png differ diff --git a/conreq/_core/base/static/conreq/icons/favicon.ico b/conreq/_core/base/static/conreq/icons/favicon.ico new file mode 100644 index 00000000..37609763 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/favicon.ico differ diff --git a/conreq/_core/base/static/conreq/icons/maskable.png b/conreq/_core/base/static/conreq/icons/maskable.png new file mode 100644 index 00000000..958dff73 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/maskable.png differ diff --git a/conreq/_core/base/static/conreq/icons/mstile-150x150.png b/conreq/_core/base/static/conreq/icons/mstile-150x150.png new file mode 100644 index 00000000..0033eca7 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/mstile-150x150.png differ diff --git a/conreq/_core/base/static/conreq/icons/safari-pinned-tab.svg b/conreq/_core/base/static/conreq/icons/safari-pinned-tab.svg new file mode 100644 index 00000000..5cd2b308 --- /dev/null +++ b/conreq/_core/base/static/conreq/icons/safari-pinned-tab.svg @@ -0,0 +1,28 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/conreq/_core/base/static/conreq/icons/standard.png b/conreq/_core/base/static/conreq/icons/standard.png new file mode 100644 index 00000000..c1108d31 Binary files /dev/null and b/conreq/_core/base/static/conreq/icons/standard.png differ diff --git a/conreq/core/base/static/images/conreq_logo.png b/conreq/_core/base/static/conreq/images/logo.png similarity index 100% rename from conreq/core/base/static/images/conreq_logo.png rename to conreq/_core/base/static/conreq/images/logo.png diff --git a/conreq/core/base/static/images/conreq_logo_dark.png b/conreq/_core/base/static/conreq/images/logo_dark.png similarity index 100% rename from conreq/core/base/static/images/conreq_logo_dark.png rename to conreq/_core/base/static/conreq/images/logo_dark.png diff --git a/conreq/core/base/static/images/transparent.png b/conreq/_core/base/static/conreq/images/transparent.png similarity index 100% rename from conreq/core/base/static/images/transparent.png rename to conreq/_core/base/static/conreq/images/transparent.png diff --git a/conreq/core/base/static/css/main_slim.css b/conreq/_core/base/static/conreq/main_slim.css similarity index 94% rename from conreq/core/base/static/css/main_slim.css rename to conreq/_core/base/static/conreq/main_slim.css index a607cc2f..a866fe9d 100644 --- a/conreq/core/base/static/css/main_slim.css +++ b/conreq/_core/base/static/conreq/main_slim.css @@ -56,6 +56,37 @@ body, -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); z-index: 1; + -webkit-animation: zoom-in 1s ease; + animation: zoom-in 1s ease; +} + +@-webkit-keyframes zoom-in { + 0% { + opacity: 0; + transform: scale(0.5); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +@keyframes zoom-in { + 0% { + opacity: 0; + transform: scale(0.5); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +.default-box .centered { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; } .logo { @@ -149,13 +180,13 @@ a { /* Info text */ h1 { font-size: 16px; - font-weight: 300; + font-weight: 700; } h2 { margin: 0; margin-bottom: 35px; - font-weight: 700; + font-weight: 300; } /* Error lists */ @@ -185,11 +216,6 @@ ul.errorlist > li { } } -.offline p { - font-size: 16px; - text-align: center; -} - @media only screen and (max-width: 800px) { :root { --font-size: 16px; @@ -319,31 +345,3 @@ ul.errorlist > li { filter: hue-rotate(0deg) brightness(150%) saturate(300%); } } - -.default-box .centered { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; -} - -.forgot-password { - display: flex; - justify-content: flex-end; - width: 100%; -} - -.forgot-password a { - transition: color 0.3s ease; -} - -.forgot-password a:hover { - color: #fff; -} - -@media only screen and (max-width: 800px) { - .forgot-password { - margin-top: 20px; - justify-content: center; - } -} diff --git a/conreq/_core/base/static/conreq/sign_in.css b/conreq/_core/base/static/conreq/sign_in.css new file mode 100644 index 00000000..844c731f --- /dev/null +++ b/conreq/_core/base/static/conreq/sign_in.css @@ -0,0 +1,24 @@ +.sign-in-form { + margin-top: 35px; +} + +.forgot-password { + display: flex; + justify-content: flex-end; + width: 100%; +} + +.forgot-password a { + transition: color 0.3s ease; +} + +.forgot-password a:hover { + color: #fff; +} + +@media only screen and (max-width: 800px) { + .forgot-password { + margin-top: 20px; + justify-content: center; + } +} diff --git a/conreq/_core/base/templates/conreq/centered_box.html b/conreq/_core/base/templates/conreq/centered_box.html new file mode 100644 index 00000000..2c296a7c --- /dev/null +++ b/conreq/_core/base/templates/conreq/centered_box.html @@ -0,0 +1,35 @@ +{% load static compress %} +{% load static %} +{% load solo_tags %} +{% get_solo 'server_settings.GeneralSettings' as GeneralSettings %} + + + + + {% block title %} + {{ GeneralSettings.server_name }} + {% endblock title %} + {% block description %} + + {% endblock description %} + {% block head %}{% include "conreq/minimal_head.html" %}{% endblock head %} + {% block extend_head %}{% endblock extend_head %} + + + + + {% block body %} +
+
+
+
+ +
+
+ {% block content %}{% endblock %} +
+
+ {% endblock %} + + + diff --git a/conreq/_core/base/templates/conreq/delete_confirm.html b/conreq/_core/base/templates/conreq/delete_confirm.html new file mode 100644 index 00000000..bec136fd --- /dev/null +++ b/conreq/_core/base/templates/conreq/delete_confirm.html @@ -0,0 +1,52 @@ +{% load crispy_forms_tags %} +{% load static %} + + + + + + + + + + + + +
+
+
+ {% block form_title %} +

+ {% if form_title %} + {{ form_title }} + {% else %} + Are you sure you want to delete "{% firstof object_name object %}"? + {% endif %} +

+ {% endblock %} + + {% block form_subtitle %} +
+ {% if form_subtitle %} + {{ form_subtitle }} + {% else %} + This action can not be reversed. + {% endif %} +
+ {% endblock %} + +
+ +
+ {% csrf_token %} + + +
+ +
+
+
+ + + diff --git a/conreq/_core/base/templates/conreq/form.html b/conreq/_core/base/templates/conreq/form.html new file mode 100644 index 00000000..57e12b2b --- /dev/null +++ b/conreq/_core/base/templates/conreq/form.html @@ -0,0 +1,52 @@ +{% load crispy_forms_tags %} +{% load static %} +{% load bootstrap %} + + + + + {% block head %} + + + + {% bootstrap_5 %} + + + + {% endblock %} + + + +
+
+
+ {% block form_title %} +
+

{{ form_title }}

+
{{ form_subtitle}}
+
+ {% endblock %} + + {% block form_top %}{% endblock %} + {% block form_content %}{% crispy form %}{% endblock %} + {% block form_bottom %}{% endblock %} +
+
+
+
+ + {% if request.GET.success %} + + {% endif %} + + + diff --git a/conreq/_core/base/templates/conreq/minimal_head.html b/conreq/_core/base/templates/conreq/minimal_head.html new file mode 100644 index 00000000..a6a2a38e --- /dev/null +++ b/conreq/_core/base/templates/conreq/minimal_head.html @@ -0,0 +1,26 @@ +{% load static compress %} +{% load static %} +{% load pwa %} + + + + + + + +{% include "conreq/icons.html" %} +{% pwa_head_content %} + + + + + + + + +{% compress css %} + +{% endcompress %} diff --git a/conreq/_core/base/templates/conreq/refresh_parent_frame.html b/conreq/_core/base/templates/conreq/refresh_parent_frame.html new file mode 100644 index 00000000..d4e19f4c --- /dev/null +++ b/conreq/_core/base/templates/conreq/refresh_parent_frame.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/conreq/_core/base/templates/conreq/table.html b/conreq/_core/base/templates/conreq/table.html new file mode 100644 index 00000000..1d71e4e1 --- /dev/null +++ b/conreq/_core/base/templates/conreq/table.html @@ -0,0 +1,44 @@ +{% load static %} +{% load render_table from django_tables2 %} +{% load solo_tags %} +{% get_solo 'server_settings.StylingSettings' as StylingSettings %} + + + + + + + + + + + + + + + + {% render_table table %} + Show items + + + + diff --git a/conreq/_core/base/urls.py b/conreq/_core/base/urls.py new file mode 100644 index 00000000..353c10e0 --- /dev/null +++ b/conreq/_core/base/urls.py @@ -0,0 +1,31 @@ +from django.conf import settings +from django.contrib.auth import views as auth_views +from django.core.files.storage import FileSystemStorage +from django.urls import include, path +from django_downloadview import StorageDownloadView + +from conreq.config.wrappers import views +from conreq.utils.environment import get_base_url, get_home_url + +BASE_URL = get_base_url(prepend_slash=False, empty_if_unset=True) +HOME_URL = get_home_url(prepend_slash=False) + +app_name = "base" +urlpatterns = [ + path("", include("conreq._core.pwa.urls")), + path("", views.landing, name="landing"), + path(HOME_URL, views.home, name="home"), + path( + "files/serve/", + StorageDownloadView.as_view( + storage=FileSystemStorage(settings.MEDIA_SERVE_DIR) + ), + name="media", + ), + path("api/", include("conreq._core.api.urls")), + path("sign-in/", views.sign_in, name="sign_in"), + path("sign-up/", include("conreq._core.sign_up.urls")), + path("sign-out/", auth_views.logout_then_login, name="sign_out"), + path("user-management/", include("conreq._core.user_management.urls")), + path("password-reset/", include("conreq._core.password_reset.urls")), +] diff --git a/conreq/_core/components.py b/conreq/_core/components.py new file mode 100644 index 00000000..e7999298 --- /dev/null +++ b/conreq/_core/components.py @@ -0,0 +1,121 @@ +from copy import copy +from inspect import iscoroutinefunction +from uuid import uuid4 + +from reactpy import component, hooks +from reactpy.html import _, div, li, ul +from reactpy_django.hooks import use_connection + +from conreq.types import ( + HomepageState, + HomepageStateContext, + SubTab, + SubTabEvent, + TabbedViewportState, + TabbedViewportStateContext, +) + + +@component +def tabbed_viewport( + tabs: list[SubTab], + top_tabs: list[SubTab] | None = None, + bottom_tabs: list[SubTab] | None = None, + default_tab: SubTab | None = None, +): + """Generates a viewport with the provided tabs.""" + tab_state, _set_tab_state = hooks.use_state( + TabbedViewportState( + _default_tab( + top_tabs or [], tabs, bottom_tabs or [], default_tab=default_tab + ) + ) + ) + + def _set_tab_state_copy(obj): + new_obj = copy(obj) + _set_tab_state(new_obj) + + tab_state.set_state = _set_tab_state_copy + + if not tab_state or not tab_state.tab: + return + + html_class = tab_state.tab.html_class + + return TabbedViewportStateContext( + div( + { + "class_name": "tabbed-viewport-container" + + (f" {html_class}" if html_class else "") + }, + div({"class_name": "tabbed-viewport"}, tab_state.tab.component()), + ul( + {"class_name": "tabbed-viewport-selector list-group"}, + _subtabs(top_tabs), + _subtabs(tabs), + _subtabs(bottom_tabs), + ), + ), + value=tab_state, + ) + + +def _default_tab( + *tab_groups: list[SubTab], default_tab: SubTab | None = None +) -> SubTab | None: + return default_tab or next((tabs[0] for tabs in tab_groups if tabs), None) + + +@component +def _subtabs( + tabs: list[SubTab] | None, +): + # sourcery skip: assign-if-exp + state = hooks.use_context(HomepageStateContext) + tab_state = hooks.use_context(TabbedViewportStateContext) + connection = use_connection() + + if not tabs: + return None + + return _( + [ + li( + {"key": str(uuid4())} + | _subtab_attributes(state, tab_state, tab, connection), + tab.name, + ) + for tab in tabs + ] + ) + + +def _subtab_attributes( + state: HomepageState, + tab_state: TabbedViewportState, + tab: SubTab, + connection, +) -> dict: + async def on_click(event): + if tab.on_click: + click_event = SubTabEvent( + event=event, + tab=tab, + connection=connection, + homepage_state=state, + tabbed_viewport_state=tab_state, + ) + if iscoroutinefunction(tab.on_click): + await tab.on_click(click_event) + else: + tab.on_click(click_event) + return + + tab_state.tab = tab + tab_state.set_state(tab_state) + + return { + "class_name": f"list-group-item clickable{' active' if tab_state.tab is tab else ''}", + "on_click": on_click, + } diff --git a/conreq/_core/database/__init__.py b/conreq/_core/database/__init__.py new file mode 100644 index 00000000..3f88dbe6 --- /dev/null +++ b/conreq/_core/database/__init__.py @@ -0,0 +1,3 @@ +from conreq._core.database.api import SqliteHuey, crontab + +__all__ = ["SqliteHuey", "crontab"] diff --git a/conreq/_core/database/api.py b/conreq/_core/database/api.py new file mode 100644 index 00000000..a8ca6eb3 --- /dev/null +++ b/conreq/_core/database/api.py @@ -0,0 +1,95 @@ +from functools import partial +from time import time + +import huey +from huey import Huey +from huey import crontab as _crontab +from huey.api import PeriodicTask, TaskWrapper +from huey.storage import SqliteStorage + +from conreq._core.database.consumer import FasterConsumer + +# Ensure strict Huey crontabs +crontab = partial(_crontab, strict=True) +crontab.__doc__ = _crontab.__doc__ +huey.crontab = crontab + +# The time a task last ran +seconds_tasks_last_run: dict[str, float] = {} +crontab_tasks_last_run: dict[str, float] = {} + + +def seconds_validator(crontab_or_seconds): + def method_validate(self, timestamp): + function_name = str(self).split(": ", maxsplit=1)[0] + seconds = crontab_or_seconds + + if not seconds_tasks_last_run.get(function_name): + seconds_tasks_last_run[function_name] = time() + + if round(time() - seconds_tasks_last_run[function_name]) >= seconds: + seconds_tasks_last_run[function_name] = time() + return True + + return False + + return method_validate + + +def crontab_validator(crontab_or_seconds): + def method_validate(self, timestamp): + function_name = str(self).split(": ", maxsplit=1)[0] + + if not crontab_tasks_last_run.get(function_name): + crontab_tasks_last_run[function_name] = time() + + if round(time() - crontab_tasks_last_run[function_name]) >= 60: + crontab_tasks_last_run[function_name] = time() + return crontab_or_seconds(timestamp) + + return False + + return method_validate + + +class SqliteHuey(Huey): + storage_class = SqliteStorage + + def create_consumer(self, **options): + return FasterConsumer(self, **options) + + def periodic_task( + self, + validate_datetime, + retries=0, + retry_delay=0, + priority=None, + context=False, + name=None, + expires=None, + **kwargs, + ): + def decorator(func): + # Seconds + if isinstance(validate_datetime, int): + validation_method = seconds_validator(validate_datetime) + + # Crontab + else: + validation_method = crontab_validator(validate_datetime) + + return TaskWrapper( + self, + func.func if isinstance(func, TaskWrapper) else func, + context=context, + name=name, + default_retries=retries, + default_retry_delay=retry_delay, + default_priority=priority, + default_expires=expires, + validate_datetime=validation_method, + task_base=PeriodicTask, + **kwargs, + ) + + return decorator diff --git a/conreq/_core/database/apps.py b/conreq/_core/database/apps.py new file mode 100644 index 00000000..91a53a07 --- /dev/null +++ b/conreq/_core/database/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DatabaseConfig(AppConfig): + name = "conreq._core.database" diff --git a/conreq/_core/database/consumer.py b/conreq/_core/database/consumer.py new file mode 100644 index 00000000..f66a9caf --- /dev/null +++ b/conreq/_core/database/consumer.py @@ -0,0 +1,9 @@ +from huey.consumer import Consumer, Scheduler + + +class FasterScheduler(Scheduler): + periodic_task_seconds = 1 + + +class FasterConsumer(Consumer): + scheduler_class = FasterScheduler diff --git a/conreq/_core/database/router.py b/conreq/_core/database/router.py new file mode 100644 index 00000000..3bd2f26f --- /dev/null +++ b/conreq/_core/database/router.py @@ -0,0 +1,43 @@ +from typing import Type + +from django.apps import apps +from django.db.models import Model + + +class DatabaseRouter: + """A router to control all database operations on models.""" + + # pylint: disable=protected-access,unused-argument + def db_for_read(self, model: Type[Model], **hints) -> None | str: + return getattr(model._meta, "db_for_read", "default") + + def db_for_write(self, model: Type[Model], **hints) -> None | str: + return getattr(model._meta, "db_for_write", "default") + + def allow_relation( + self, model_1: Type[Model], model_2: Type[Model], **hints + ) -> None | bool: + """Allow all relationships, unless either model has `allowed_relations`.""" + rel_1: list[str] = getattr(model_1._meta, "allowed_relations", []) + rel_2: list[str] = getattr(model_2._meta, "allowed_relations", []) + + if not rel_1 or rel_2: + return True + + return model_2._meta.app_label in rel_1 or model_1._meta.app_label in rel_2 + + def allow_migrate( + self, db_name: str, app_label: str, model_name: str | None = None, **hints + ) -> None | bool: + """ + Migrations only run on the `db_for_read` or `db_for_write` databases, + unless a list of `migration_databases` is specified. + """ + if model_name is None: + return None + model = apps.get_registered_model(app_label, model_name) + + if hasattr(model._meta, "migration_databases"): + return db_name in model._meta.migration_databases + + return db_name in (self.db_for_read(model), self.db_for_write(model)) diff --git a/conreq/_core/database/tasks.py b/conreq/_core/database/tasks.py new file mode 100644 index 00000000..a33727e6 --- /dev/null +++ b/conreq/_core/database/tasks.py @@ -0,0 +1,49 @@ +import sqlite3 + +from django.conf import settings +from django.core.management import call_command +from django.db import connection +from huey import crontab +from huey.contrib.djhuey import db_periodic_task + +from conreq.utils.environment import get_database_engine + +DB_ENGINE = get_database_engine() +HUEY_FILENAME = getattr(settings, "HUEY_FILENAME") + + +@db_periodic_task(crontab(minute="0", hour="0", day_of_week="1")) +def clean_huey_db(): + """Periodically performs a SQLITE vacuum on the background task database weekly.""" + with sqlite3.connect(HUEY_FILENAME) as cursor: + cursor.execute( + # Only keep the 1000 latest tasks + """DELETE FROM task + WHERE id NOT IN ( + SELECT id + FROM ( + SELECT id + FROM task + ORDER BY id DESC + LIMIT 1000 + ) foo + ); + """ + ) + with sqlite3.connect(HUEY_FILENAME) as cursor: + cursor.execute("VACUUM") + + +if DB_ENGINE == "SQLITE3": + + @db_periodic_task(crontab(minute="0", hour="0", day_of_week="1")) + def clean_conreq_db(): + """Periodically performs any cleanup tasks needed for the default database weekly.""" + with connection.cursor() as cursor: + cursor.execute("VACUUM") + + +@db_periodic_task(crontab(minute="0", hour="0", day="1")) +def clean_sessions(): + """Periodically deletes expired sessions from the database monthly.""" + call_command("clearsessions") diff --git a/conreq/core/base/templatetags/__init__.py b/conreq/_core/debug/__init__.py similarity index 100% rename from conreq/core/base/templatetags/__init__.py rename to conreq/_core/debug/__init__.py diff --git a/conreq/_core/debug/apps.py b/conreq/_core/debug/apps.py new file mode 100644 index 00000000..b674e201 --- /dev/null +++ b/conreq/_core/debug/apps.py @@ -0,0 +1,49 @@ +from django.apps import AppConfig +from django.urls import include, path +from reactpy.html import i + +from conreq import config +from conreq._core.debug import views +from conreq.types import NavGroup +from conreq.utils.environment import get_debug_mode +from conreq.utils.modules import load + +DEBUG = get_debug_mode() + + +class DebugConfig(AppConfig): + name = "conreq._core.debug" + + def ready(self): + if not DEBUG: + return + + # pylint: disable=import-outside-toplevel + from django.contrib import admin + from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView + + from conreq.urls import external_urls + + external_urls.extend( + [ + path("silk/", include("silk.urls", namespace="silk"), name="silk"), + path( + "admin/docs/", + include("django.contrib.admindocs.urls"), + ), + path("admin/", include("massadmin.urls")), + path("admin/", admin.site.urls, name="admin"), + path("api/schema/", SpectacularAPIView.as_view(), name="schema"), + path( + "api/schema/swagger-ui/", + SpectacularSwaggerView.as_view(), + name="swagger_ui", + ), + path("health-check/", views.HealthCheck.as_view(), name="health_check"), + ] + ) + + config.homepage.sidebar_tabs.add( + NavGroup(name="Debug", icon=i({"class_name": "fas fa-spider icon-left"})) + ) + load("components") diff --git a/conreq/_core/debug/components.py b/conreq/_core/debug/components.py new file mode 100644 index 00000000..b0cef245 --- /dev/null +++ b/conreq/_core/debug/components.py @@ -0,0 +1,43 @@ +from django.urls.base import reverse +from reactpy.html import iframe + +from conreq import config +from conreq.config.utils import tab_constructor + + +def performance(*_): + return iframe({"src": reverse("silk:summary")}) + + +def health_check(*_): + return iframe({"src": reverse("health_check")}) + + +def database(*_): + return iframe({"src": reverse("admin:index")}) + + +def code_outline(*_): + return iframe({"src": reverse("django-admindocs-docroot")}) + + +def api_docs(*_): + return iframe({"src": reverse("swagger_ui")}) + + +# pylint: disable=protected-access +config._homepage.debug_sidebar_tabs.append( + tab_constructor("Performance", performance, padding=False) +) +config._homepage.debug_sidebar_tabs.append( + tab_constructor("Health Check", health_check) +) +config._homepage.debug_sidebar_tabs.append( + tab_constructor("Database", database, padding=False) +) +config._homepage.debug_sidebar_tabs.append( + tab_constructor("Code Outline", code_outline, padding=False) +) +config._homepage.debug_sidebar_tabs.append( + tab_constructor("API Docs", api_docs, padding=False) +) diff --git a/conreq/_core/debug/static/conreq/health_check.css b/conreq/_core/debug/static/conreq/health_check.css new file mode 100644 index 00000000..b7b3dbfe --- /dev/null +++ b/conreq/_core/debug/static/conreq/health_check.css @@ -0,0 +1,24 @@ +:root { + --accent-color: #258a6d; +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + color: rgba(255, 255, 255, 0.75); +} + +table { + border-radius: 10px 10px 0 0; + color: #333; + margin-bottom: 20px; + overflow: hidden; +} + +table > thead th { + padding-top: 13px !important; + padding-bottom: 13px !important; + padding-right: 13px !important; + font-size: 14px; + padding: 15px 15px; +} diff --git a/conreq/_core/debug/static/conreq/jazzmin.css b/conreq/_core/debug/static/conreq/jazzmin.css new file mode 100644 index 00000000..08a1a0ff --- /dev/null +++ b/conreq/_core/debug/static/conreq/jazzmin.css @@ -0,0 +1,41 @@ +aside#jazzy-sidebar { + display: none; +} + +body:not(.sidebar-mini-md):not(.sidebar-mini-xs):not(.layout-top-nav) + .content-wrapper, +body:not(.sidebar-mini-md):not(.sidebar-mini-xs):not(.layout-top-nav) + .main-footer, +body:not(.sidebar-mini-md):not(.sidebar-mini-xs):not(.layout-top-nav) + .main-header, +.wrapper .content-wrapper { + margin-left: 0 !important; +} + +.select2-container--default + .select2-selection--multiple + .select2-selection__choice { + background: #787474 !important; +} + +.select2-container--default + .select2-selection--multiple + .select2-selection__choice__remove { + border: none !important; + color: rgb(218, 218, 218) !important; + transition: color 0.3s ease; +} + +.select2-container--default + .select2-selection--multiple + .select2-selection__choice__remove:hover, +.select2-container--default + .select2-selection--multiple + .select2-selection__choice__remove:focus { + background: transparent !important; + color: #fff !important; +} + +.select2-container--default .select2-results > .select2-results__options { + max-height: 400px !important; +} diff --git a/conreq/_core/debug/templates/conreq/health_check.html b/conreq/_core/debug/templates/conreq/health_check.html new file mode 100644 index 00000000..10e87b2a --- /dev/null +++ b/conreq/_core/debug/templates/conreq/health_check.html @@ -0,0 +1,12 @@ +{% extends "health_check/index.html" %} + +{% block extra_head %} +{% load static %} +{% load solo_tags %} +{% get_solo 'server_settings.StylingSettings' as StylingSettings %} + + + +{% endblock extra_head %} diff --git a/conreq/_core/debug/views.py b/conreq/_core/debug/views.py new file mode 100644 index 00000000..304548d0 --- /dev/null +++ b/conreq/_core/debug/views.py @@ -0,0 +1,5 @@ +from health_check.views import MainView as HealthCheckView + + +class HealthCheck(HealthCheckView): + template_name = "conreq/health_check.html" diff --git a/conreq/core/discover/__init__.py b/conreq/_core/email/__init__.py similarity index 100% rename from conreq/core/discover/__init__.py rename to conreq/_core/email/__init__.py diff --git a/conreq/_core/email/admin.py b/conreq/_core/email/admin.py new file mode 100644 index 00000000..11017add --- /dev/null +++ b/conreq/_core/email/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from conreq._core.email.models import EmailSettings + + +@admin.register(EmailSettings) +class AdminEmailSettings(admin.ModelAdmin): + pass diff --git a/conreq/_core/email/apps.py b/conreq/_core/email/apps.py new file mode 100644 index 00000000..7dc68015 --- /dev/null +++ b/conreq/_core/email/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EmailConfig(AppConfig): + name = "conreq._core.email" + verbose_name = "Email" diff --git a/conreq/_core/email/migrations/0001_initial.py b/conreq/_core/email/migrations/0001_initial.py new file mode 100644 index 00000000..96946676 --- /dev/null +++ b/conreq/_core/email/migrations/0001_initial.py @@ -0,0 +1,68 @@ +# Generated by Django 3.2.7 on 2021-09-19 07:52 + +import encrypted_fields.fields +from django.db import migrations, models + +import conreq._core.fields + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="EmailConfig", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "smtp_server", + conreq._core.fields.HostnameOrURLField( + default="smtp.gmail.com", max_length=255 + ), + ), + ("smtp_port", models.PositiveIntegerField(default=587)), + ( + "auth_encryption", + models.CharField( + choices=[ + ("TLS", "TLS (Default)"), + ("SSL", "SSL"), + ("OFF", "Off"), + ], + default="TLS", + max_length=3, + ), + ), + ( + "username", + encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=255 + ), + ), + ( + "password", + encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=255 + ), + ), + ( + "sender_name", + models.CharField(blank=True, default="", max_length=50), + ), + ], + options={ + "verbose_name": "Email Settings", + "verbose_name_plural": "Email Settings", + }, + ), + ] diff --git a/conreq/_core/email/migrations/0002_alter_emailconfig_smtp_server.py b/conreq/_core/email/migrations/0002_alter_emailconfig_smtp_server.py new file mode 100644 index 00000000..bda7664a --- /dev/null +++ b/conreq/_core/email/migrations/0002_alter_emailconfig_smtp_server.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.7 on 2021-09-19 08:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="emailconfig", + name="smtp_server", + field=models.CharField(default="smtp.gmail.com", max_length=255), + ), + ] diff --git a/conreq/_core/email/migrations/0003_auto_20211119_0312.py b/conreq/_core/email/migrations/0003_auto_20211119_0312.py new file mode 100644 index 00000000..15a2fa25 --- /dev/null +++ b/conreq/_core/email/migrations/0003_auto_20211119_0312.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2.9 on 2021-11-19 11:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0002_alter_emailconfig_smtp_server"), + ] + + operations = [ + migrations.RenameField( + model_name="emailconfig", + old_name="smtp_port", + new_name="port", + ), + migrations.RenameField( + model_name="emailconfig", + old_name="smtp_server", + new_name="server", + ), + ] diff --git a/conreq/_core/email/migrations/0004_emailconfig_timeout.py b/conreq/_core/email/migrations/0004_emailconfig_timeout.py new file mode 100644 index 00000000..52e8c047 --- /dev/null +++ b/conreq/_core/email/migrations/0004_emailconfig_timeout.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.9 on 2021-11-19 11:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0003_auto_20211119_0312"), + ] + + operations = [ + migrations.AddField( + model_name="emailconfig", + name="timeout", + field=models.PositiveIntegerField(default=60), + ), + ] diff --git a/conreq/_core/email/migrations/0005_emailconfig_enabled.py b/conreq/_core/email/migrations/0005_emailconfig_enabled.py new file mode 100644 index 00000000..8a95884d --- /dev/null +++ b/conreq/_core/email/migrations/0005_emailconfig_enabled.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.9 on 2021-11-21 21:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0004_emailconfig_timeout"), + ] + + operations = [ + migrations.AddField( + model_name="emailconfig", + name="enabled", + field=models.BooleanField(default=False), + ), + ] diff --git a/conreq/_core/email/migrations/0006_alter_emailconfig_options.py b/conreq/_core/email/migrations/0006_alter_emailconfig_options.py new file mode 100644 index 00000000..5bc7a81b --- /dev/null +++ b/conreq/_core/email/migrations/0006_alter_emailconfig_options.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.9 on 2021-11-23 23:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0005_emailconfig_enabled"), + ] + + operations = [ + migrations.AlterModelOptions( + name="emailconfig", + options={ + "verbose_name": "Email settings", + "verbose_name_plural": "Email settings", + }, + ), + ] diff --git a/conreq/_core/email/migrations/0007_alter_emailconfig_password.py b/conreq/_core/email/migrations/0007_alter_emailconfig_password.py new file mode 100644 index 00000000..1442485a --- /dev/null +++ b/conreq/_core/email/migrations/0007_alter_emailconfig_password.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0 on 2021-12-18 17:07 + +from django.db import migrations + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0006_alter_emailconfig_options"), + ] + + operations = [ + migrations.AlterField( + model_name="emailconfig", + name="password", + field=conreq._core.fields.PasswordField( + blank=True, default="", max_length=255 + ), + ), + ] diff --git a/conreq/_core/email/migrations/0008_rename_emailconfig_emailsettings.py b/conreq/_core/email/migrations/0008_rename_emailconfig_emailsettings.py new file mode 100644 index 00000000..545b2cdb --- /dev/null +++ b/conreq/_core/email/migrations/0008_rename_emailconfig_emailsettings.py @@ -0,0 +1,16 @@ +# Generated by Django 4.0 on 2021-12-28 20:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("email", "0007_alter_emailconfig_password"), + ] + + operations = [ + migrations.RenameModel( + old_name="EmailConfig", + new_name="EmailSettings", + ), + ] diff --git a/conreq/core/discover/migrations/__init__.py b/conreq/_core/email/migrations/__init__.py similarity index 100% rename from conreq/core/discover/migrations/__init__.py rename to conreq/_core/email/migrations/__init__.py diff --git a/conreq/_core/email/models.py b/conreq/_core/email/models.py new file mode 100644 index 00000000..97fe9541 --- /dev/null +++ b/conreq/_core/email/models.py @@ -0,0 +1,33 @@ +from django.db import models +from encrypted_fields.fields import EncryptedCharField +from solo.models import SingletonModel + +from conreq._core.fields import PasswordField + + +class AuthEncryption(models.TextChoices): + TLS = "TLS", "TLS (Default)" + SSL = "SSL", "SSL" + OFF = "OFF", "Off" + + +class EmailSettings(SingletonModel): + def __str__(self): + return "Email Settings" + + class Meta: + verbose_name = "Email settings" + verbose_name_plural = verbose_name + + server = models.CharField(max_length=255, default="smtp.gmail.com") + port = models.PositiveIntegerField(default=587) + auth_encryption = models.CharField( + max_length=3, + choices=AuthEncryption.choices, + default=AuthEncryption.TLS, + ) + timeout = models.PositiveIntegerField(default=60) + username = EncryptedCharField(max_length=255, default="", blank=True) + password = PasswordField(max_length=255, default="", blank=True) + sender_name = models.CharField(max_length=50, default="", blank=True) + enabled = models.BooleanField(default=False) diff --git a/conreq/_core/email/tasks.py b/conreq/_core/email/tasks.py new file mode 100644 index 00000000..8013bafa --- /dev/null +++ b/conreq/_core/email/tasks.py @@ -0,0 +1,41 @@ +from typing import Sequence + +from django.core.mail import send_mail as django_send_email +from django.core.mail.backends import smtp +from huey.contrib.djhuey import db_task + +from conreq._core.email import utils +from conreq._core.email.types import Email +from conreq.app.models import EmailSettings + + +@db_task() +def send_email( + subject, + message, + from_email, + recipient_list, + fail_silently=False, + auth_user=None, + auth_password=None, + connection=None, + html_message=None, +): + django_send_email( + subject, + message, + from_email, + recipient_list, + fail_silently=fail_silently, + auth_user=auth_user, + auth_password=auth_password, + connection=connection, + html_message=html_message, + ) + + +@db_task() +def send_mass_email( + connection: smtp.EmailBackend, emails: Sequence[Email], email_config: EmailSettings +): + return utils.send_mass_email(connection, emails, email_config) diff --git a/conreq/_core/email/types.py b/conreq/_core/email/types.py new file mode 100644 index 00000000..00250b93 --- /dev/null +++ b/conreq/_core/email/types.py @@ -0,0 +1,43 @@ +from dataclasses import dataclass +from typing import Sequence + +from django.core.mail.backends import smtp +from django.core.mail.message import EmailMessage + +from conreq.app.models import AuthEncryption, EmailSettings + + +@dataclass +class Email: + subject: str + """Email title""" + + message: str + """Message rendered if HTML is not supported""" + + recipient_list: list[str] + """List of email addresses""" + + html_message: str | None = None + """Emails can be rendered as HTML, if supported by the client""" + + +class EmailBackend(smtp.EmailBackend): + """Email backend to be used for Django reverse compatibility.""" + + def configure(self, email_config: EmailSettings | None = None): + config: EmailSettings = email_config or EmailSettings.get_solo() + self.host = config.server + self.port = config.port + self.username = config.username + self.password = config.password + self.use_tls = config.auth_encryption == AuthEncryption.TLS + self.use_ssl = config.auth_encryption == AuthEncryption.SSL + self.timeout = config.timeout + + def send_messages(self, email_messages: Sequence[EmailMessage]) -> int: + config: EmailSettings = EmailSettings.get_solo() + if config.enabled: + self.configure(config) + return super().send_messages(email_messages) + return 0 diff --git a/conreq/_core/email/utils.py b/conreq/_core/email/utils.py new file mode 100644 index 00000000..173f4e4b --- /dev/null +++ b/conreq/_core/email/utils.py @@ -0,0 +1,34 @@ +from typing import Sequence + +from django.core.mail import EmailMultiAlternatives +from django.core.mail.backends import smtp + +from conreq._core.email.types import Email +from conreq.app.models import EmailSettings + + +def get_from_name(email_config: EmailSettings | None = None): + config: EmailSettings = email_config or EmailSettings.get_solo() + + return ( + f"{config.sender_name} <{config.username}>" + if config.sender_name + else config.username + ) + + +def send_mass_email( + connection: smtp.EmailBackend, emails: Sequence[Email], email_config: EmailSettings +): + messages = [] + for email in emails: + message = EmailMultiAlternatives( + email.subject, + email.message, + get_from_name(email_config), + email.recipient_list, + ) + if email.html_message: + message.attach_alternative(email.html_message, "text/html") + messages.append(message) + return connection.send_messages(messages) diff --git a/conreq/_core/fields.py b/conreq/_core/fields.py new file mode 100644 index 00000000..b8687928 --- /dev/null +++ b/conreq/_core/fields.py @@ -0,0 +1,163 @@ +import contextlib + +from django.db.models import FileField, OneToOneField, TextField, URLField +from django.db.models.fields.related_descriptors import ReverseOneToOneDescriptor +from django.db.transaction import atomic +from django.forms import PasswordInput, ValidationError +from django.template.defaultfilters import filesizeformat +from django.utils.translation import gettext_lazy +from django_ace import AceWidget +from encrypted_fields.fields import EncryptedCharField + +from conreq._core import forms, validators + + +class PythonTextField(TextField): + """A regular TextField, but this one displays itself with a Python text editor.""" + + def formfield(self, **kwargs): + kwargs["widget"] = AceWidget( + mode="python", + width="100%", + toolbar=False, + showprintmargin=False, + ) + return super().formfield(**kwargs) + + +class PasswordField(EncryptedCharField): + """Encrypted character field that hides the user's input within the browser.""" + + def formfield(self, **kwargs): + if kwargs.get("widget"): + kwargs["widget"] = kwargs["widget"](attrs={"type": "password"}) + else: + kwargs["widget"] = PasswordInput(render_value=True) + return super().formfield(**kwargs) + + +class HostnameOrURLField(URLField): + """URL field that supports hostnames (ex. https://sonarr:8000)""" + + default_validators = [validators.HostnameOrURLValidator()] + + def formfield(self, **kwargs): + # As with CharField, this will cause URL validation to be performed twice. + return super().formfield( + **{ + "form_class": forms.HostnameOrURLField, + **kwargs, + } + ) + + +class URLOrRelativeURLField(URLField): + """URL field that supports relative or absolute URLs + (ex. /my/url/path or https://mydomain.com)""" + + default_validators = [validators.url_or_relative_url_validator] + + def formfield(self, **kwargs): + # As with CharField, this will cause URL validation to be performed twice. + return super().formfield( + **{ + "form_class": forms.URLOrRelativeURLField, + **kwargs, + } + ) + + +class AutoOneToOneField(OneToOneField): + """ + A OneToOneField that automatically creates itself if it doesnt exist yet. + Drop in replacement for a regular OneToOne field. + + Be mindful that the model that you use with this field must have default + values for all required fields. + + Example: + + ```python + class MyProfile(models.Model): + user = AutoOneToOneField(User, primary_key=True) + home_page = models.URLField(max_length=255, blank=True) + icq = models.IntegerField(max_length=255, null=True) + ``` + """ + + def contribute_to_related_class(self, cls, related): + setattr( + cls, + related.get_accessor_name(), + _AutoSingleRelatedObjectDescriptor(related), + ) + + +class RestrictedFileField(FileField): + """ + A FileField that allows certain restrictions. + + * content_types - List containing allowed content_types. Example: `['application/pdf', 'image/jpeg']`. + See https://www.geeksforgeeks.org/http-headers-content-type/ for all content types. + + * max_upload_size - Number indicating the maximum bytes allowed for upload. + 2.5MB (2621440) + 5MB (5242880) + 10MB (10485760) + 20MB (20971520) + 50MB (5242880) + 100M (104857600) + 250MB (214958080) + 500MB (429916160) + """ + + def __init__( + self, + *args, + content_types: list[str] | None = None, + max_upload_size: int = 0, + **kwargs, + ): + self.content_types = content_types + self.max_upload_size = max_upload_size + super().__init__(*args, **kwargs) + + def clean(self, *args, **kwargs): + data = super().clean(*args, **kwargs) + file = data.file + + with contextlib.suppress(AttributeError): + if self.content_types and file.content_type not in self.content_types: + raise ValidationError( + gettext_lazy("Filetype not supported. Allowed filetypes: %s") + % ", ".join(map(str, self.content_types)) + ) + # pylint: disable=protected-access + if self.max_upload_size and file._size > self.max_upload_size: + raise ValidationError( + gettext_lazy("File size %s is larger than the maximum %s.") + % (filesizeformat(file._size), filesizeformat(self.max_upload_size)) + ) + return data + + +class _AutoSingleRelatedObjectDescriptor(ReverseOneToOneDescriptor): + """ + The descriptor that handles the object creation for an AutoOneToOneField. + """ + + @atomic + def __get__(self, instance, instance_type=None): + model = getattr(self.related, "related_model", self.related.model) + + try: + return super().__get__(instance, instance_type) + except model.DoesNotExist: + # Using get_or_create instead() of save() or create() as it better handles race conditions + obj, _ = model.objects.get_or_create(**{self.related.field.name: instance}) + + # Update Django's cache, otherwise first 2 calls to obj.relobj + # will return 2 different in-memory objects + self.related.set_cached_value(instance, obj) + self.related.field.set_cached_value(obj, instance) + return obj diff --git a/conreq/_core/forms.py b/conreq/_core/forms.py new file mode 100644 index 00000000..199142fe --- /dev/null +++ b/conreq/_core/forms.py @@ -0,0 +1,105 @@ +from django.forms import BooleanField, CharField, ChoiceField, IntegerField, URLField + +from conreq._core import validators, widgets +from conreq.utils.environment import get_env, set_env +from conreq.utils.forms import EnvFieldMixin + + +class HostnameOrURLField(URLField): + """URL field that supports hostnames (ex. https://sonarr:8000)""" + + default_validators = [validators.HostnameOrURLValidator()] + + +class URLOrRelativeURLField(URLField): + """URL field that supports relative or absolute URLs + (ex. /my/url/path or https://mydomain.com)""" + + widget = widgets.URLOrRelativeURLInput + default_validators = [validators.url_or_relative_url_validator] + + def to_python(self, value): + value = super().to_python(value) + if value and value.startswith("http:///"): + # If value starts with ``http:///`` (followed by 3 slashes) + # that means user provided a relative url and a parent ``URLField`` class + # has appended a ``http://`` to it. + # We need to strip it out and convert to correct relative url + # before we pass it down the line. + value = value[7:] + return value + + +class EnvCharField(EnvFieldMixin, CharField): + """A character field that utilizes the env file, instead of the database.""" + + def __init__(self, env_name, *, required=False, **kwargs) -> None: + super().__init__(env_name, required=required, **kwargs) + if self.initial is None: + self.initial = get_env(self.env_name, default_value="") + + +class EnvChoiceField(EnvFieldMixin, ChoiceField): + """A choice field that utilizes the env file, instead of the database.""" + + def __init__(self, env_name, *, required=False, **kwargs) -> None: + super().__init__(env_name, required=required, **kwargs) + if self.initial is None: + raise ValueError( + f"`initial=...` parameter is required for EnvChoiceField {self.env_name}" + ) + + +class EnvBooleanField(EnvFieldMixin, BooleanField): + """A boolean field that utilizes the env file, instead of the database.""" + + def __init__(self, env_name, *, required=False, **kwargs) -> None: + super().__init__(env_name, required=required, **kwargs) + if self.initial is None: + self.initial = get_env(self.env_name, default_value=False, return_type=bool) + + env_type = bool + + +class EnvIntegerField(EnvFieldMixin, IntegerField): + """An integer field that utilizes the env file, instead of the database.""" + + def __init__(self, env_name, *, required=False, **kwargs) -> None: + super().__init__(env_name, required=required, **kwargs) + if self.initial is None: + raise ValueError( + f"`initial=...` parameter is required for EnvIntegerField {self.env_name}" + ) + + env_type = int + + +class EnvFormMixin: + """Allows custom EnvFields for any `ModelForm` or `Form`. + + `Form` will require calling `is_valid()` then `save()` to commit changes. This is + done automatically if using `SaveFormViewMixin`.""" + + # pylint: disable=too-few-public-methods + + def save(self, commit: bool = True): + super_class = super() + saved = ( + super().save(commit=commit) if getattr(super_class, "save", None) else None # type: ignore + ) + if not commit: + return saved + + for name, field in self.base_fields.items(): # type: ignore + if isinstance(field, EnvFieldMixin) and self._env_changed(name, field): + set_env(field.env_name or name, self.cleaned_data.get(name)) # type: ignore + + return saved + + def _env_changed(self, name, field): + """Check if a new value was provided that is different from either the + initial or stored value.""" + initial_value = str(field.initial) + current_value = get_env(field.env_name, default_value=initial_value) + new_value = str(self.cleaned_data.get(name, "")) # type: ignore + return current_value != new_value diff --git a/conreq/core/issue_reporting/__init__.py b/conreq/_core/home/__init__.py similarity index 100% rename from conreq/core/issue_reporting/__init__.py rename to conreq/_core/home/__init__.py diff --git a/conreq/_core/home/apps.py b/conreq/_core/home/apps.py new file mode 100644 index 00000000..7d2bce39 --- /dev/null +++ b/conreq/_core/home/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class HomeConfig(AppConfig): + name = "conreq._core.home" diff --git a/conreq/_core/home/components/__init__.py b/conreq/_core/home/components/__init__.py new file mode 100644 index 00000000..e8a39a33 --- /dev/null +++ b/conreq/_core/home/components/__init__.py @@ -0,0 +1,64 @@ +from copy import copy + +from django.urls import reverse_lazy +from reactpy import component, hooks +from reactpy.html import script +from reactpy_django.decorators import user_passes_test + +from conreq._core.home.components.backdrop import backdrop +from conreq._core.home.components.modal import modal +from conreq._core.home.components.navbar import navbar +from conreq._core.home.components.sidebar import sidebar +from conreq._core.home.components.viewport import viewport, viewport_loading_animation +from conreq.types import ( + HomepageState, + HomepageStateContext, + ModalState, + ModalStateContext, +) + +# pylint: disable=protected-access +# TODO: Add react components: SimpleBar, Pretty-Checkbox, IziToast, Bootstrap + + +@user_passes_test( + lambda user: user.is_active, + fallback=script( + f"window.location.href = '{reverse_lazy('conreq:sign_in')}" + + "?next=' + window.location.pathname", + ), +) +@component +def homepage(): + state, set_state = hooks.use_state(HomepageState()) + state.set_state = lambda obj: set_state(copy(obj)) + modal_state, set_modal_state = hooks.use_state(ModalState()) + modal_state.set_state = lambda obj: set_modal_state(copy(obj)) + + @hooks.use_effect(dependencies=[state.viewport_intent]) + def set_viewport(): + """Set the viewport based on intent.""" + if not state.viewport_intent: + return + + # Replace the selected viewport + state._viewport = state.viewport_intent + state.viewport_intent = None + + # Reset the modal + modal_state.reset_modal() + + state.set_state(state) + + return HomepageStateContext( + ModalStateContext( + navbar(), + modal(), + sidebar(), + viewport_loading_animation(), + viewport(), + backdrop(), + value=modal_state, + ), + value=state, + ) diff --git a/conreq/_core/home/components/backdrop.py b/conreq/_core/home/components/backdrop.py new file mode 100644 index 00000000..4be59a29 --- /dev/null +++ b/conreq/_core/home/components/backdrop.py @@ -0,0 +1,43 @@ +from random import randint + +from django.templatetags.static import static +from reactpy import component, hooks, html + + +@component +def backdrop(): + # TODO: Jump between two images tags for rotating images + + default_backdrop, set_default_backdrop = hooks.use_state( + f"conreq/backdrop-({randint(1, 200)}).jpg" + ) + backdrop_selector, set_backdrop_selector = hooks.use_state(1) + prev_backdrop, set_prev_backdrop = hooks.use_state(None) + + # bg_num, set_bg_num = hooks.use_state(randint(1, 210)) + # async def on_click(_event): + # val = bg_num + 1 + # if val > 210: + # val = 1 + # set_bg_num(val) + # print(f"bg_num: {val}") + + # "on_click": on_click, + # html.img( + # { + # "class_name": f"backdrop {'opacity-0' if backdrop_selector == 2 else ''}", + # "src": prev_backdrop, + # "loading": "lazy", + # } + # ), + return html.div( + {"class_name": "backdrop-container"}, + html.div({"class_name": "backdrop-tint"}), + html.img( + { + "class_name": f"backdrop {('opacity-0' if backdrop_selector != 1 else '')}", + "src": static(default_backdrop), + "loading": "lazy", + } + ), + ) diff --git a/conreq/_core/home/components/modal.py b/conreq/_core/home/components/modal.py new file mode 100644 index 00000000..28bd8a3a --- /dev/null +++ b/conreq/_core/home/components/modal.py @@ -0,0 +1,148 @@ +from typing import Callable + +from reactpy import component, hooks +from reactpy.html import _, div, i, script + +from conreq import config +from conreq.types import ModalStateContext + +# pylint: disable=protected-access + +MODAL_CONTAINER = { + "id": "modal-container", + "class_name": "modal fade", + "tab_index": "-1", + "aria-hidden": "true", +} +MODAL_DIALOG = {"class_name": "modal-dialog modal-dialog-centered modal-lg"} +MODAL_CONTENT = {"class_name": "modal-content"} +MODAL_HEADER = {"class_name": "modal-header"} +MODAL_HEADER_BTN_CONTAINER = {"class_name": "modal-header-btns"} +MODAL_TITLE = {"class_name": "title"} +MODAL_BODY = {"class_name": "modal-body loading"} +MODAL_FOOTER = {"class_name": "modal-footer"} + + +def _fragment_if_iterable(children): + """Return a fragment if children is iterable.""" + return _(*children) if hasattr(children, "__iter__") else children + + +@component +def modal(): + modal_state = hooks.use_context(ModalStateContext) + + @hooks.use_effect(dependencies=[modal_state.modal_intent]) + async def set_modal(): + """Set the modal based on intent.""" + if not modal_state.modal_intent: + return + + modal_state._modal = modal_state.modal_intent + modal_state.modal_intent = None + modal_state.set_state(modal_state) + + return div( + MODAL_CONTAINER, + modal_state._modal( + *modal_state.args, + **modal_state.kwargs, + key=f"{modal_state._modal.__module__}.{modal_state._modal.__name__}.{modal_state.args}.{modal_state.kwargs}", + ) + if modal_state._modal + else modal_dialog(), + script( + "let body = document.querySelector('body');" + "let modal = document.querySelector('#modal-container');" + "body.classList.add('modal-open');" + "body.style.paddingRight = '0px';" + "body.style.overflow = 'hidden';" + "body.setAttribute('data-bs-overflow', 'hidden');" + "body.setAttribute('data-bs-padding-right', '0px');" + "modal.classList.add('show');" + "modal.style.display = 'block';" + "modal.setAttribute('aria-modal', 'true');" + "modal.setAttribute('role', 'dialog');" + "modal.removeAttribute('aria-hidden');" + "if (!document.querySelector('.modal-backdrop.show'))" + "{let backdrop = document.createElement('div');" + "backdrop.classList.add('modal-backdrop', 'show');" + "document.querySelector('body').appendChild(backdrop);}" + if modal_state.show + else "let body = document.querySelector('body');" + "let modal = document.querySelector('#modal-container');" + "body.removeAttribute('style');" + "body.removeAttribute('class');" + "body.removeAttribute('data-bs-overflow');" + "body.removeAttribute('data-bs-padding-right');" + "modal.classList.remove('show');" + "modal.removeAttribute('aria-modal');" + "modal.removeAttribute('role');" + "modal.setAttribute('aria-hidden', 'true');" + "modal.style.display = 'none';" + "if (document.querySelector('.modal-backdrop.show'))" + "{document.querySelector('.modal-backdrop.show').remove();}" + ), + ) + + +@component +def modal_dialog(*content): + if content: + return div(MODAL_DIALOG, _fragment_if_iterable(content)) + + return div(MODAL_DIALOG, modal_content()) + + +@component +def modal_content(*content): + if content: + return div(MODAL_CONTENT, _fragment_if_iterable(content)) + + return div( + MODAL_CONTENT, + modal_head(key="default-modal-head"), + modal_body(key="default-modal-body"), + modal_footer(key="default-modal-footer"), + ) + + +@component +def modal_head(*content, title="Loading...", close_action: Callable | None = None): + modal_state = hooks.use_context(ModalStateContext) + + async def close_modal(_): + modal_state.reset_modal() + modal_state.set_state(modal_state) + + return div( + MODAL_HEADER, + div( + MODAL_HEADER_BTN_CONTAINER, + _fragment_if_iterable(content), + i( + { + "title": "Close", + "class_name": "fas fa-window-close clickable", + "on_click": close_action or close_modal, + } + ), + ), + div(MODAL_TITLE, title), + ) + + +@component +def modal_body(*content): + if content: + return div(MODAL_BODY, _fragment_if_iterable(content)) + + return div( + MODAL_BODY, + div({"class_name": "loading"}, config.components.loading_animation.small), + ) + + +@component +def modal_footer(*content): + return div(MODAL_FOOTER, _fragment_if_iterable(content)) diff --git a/conreq/_core/home/components/navbar.py b/conreq/_core/home/components/navbar.py new file mode 100644 index 00000000..0b886c13 --- /dev/null +++ b/conreq/_core/home/components/navbar.py @@ -0,0 +1,52 @@ +from channels.db import database_sync_to_async +from reactpy import component, hooks +from reactpy.html import button, div, script, span +from reactpy_django.components import django_js + +from conreq._core.server_settings.models import GeneralSettings +from conreq.types import HomepageState, HomepageStateContext + +# pylint: disable=protected-access + +NAVBAR = {"class_name": "navbar navbar-expand-md navbar-dark blur"} +NAVBAR_TOGGLER = { + "class_name": "navbar-toggler", + "type": "button", + "aria-label": "Toggle sidebar", + "title": "Toggle sidebar", +} +NAVBAR_TOGGLER_ICON = {"class_name": "navbar-toggler-icon"} +NAVBAR_BRAND = {"class_name": "navbar-brand ellipsis"} + + +@component +def navbar(): + state = hooks.use_context(HomepageStateContext) + page_title, set_page_title = hooks.use_state("") + + @hooks.use_effect(dependencies=[state]) + @database_sync_to_async + def _update_page_title(): + new_page_title = _get_page_title(state) + + if new_page_title != page_title: + set_page_title(_get_page_title(state)) + + return div( + NAVBAR, + button( + NAVBAR_TOGGLER, + span(NAVBAR_TOGGLER_ICON), + ), + div(NAVBAR_BRAND), # TODO: Add logo support + django_js("conreq/navbar.js"), + script(f"if('{page_title}'){{document.title = '{page_title}'}}"), + ) + + +def _get_page_title(state: HomepageState): + return getattr(state._viewport, "page_title", None) or _default_page_title() + + +def _default_page_title(): + return GeneralSettings.get_solo().server_name diff --git a/conreq/_core/home/components/sidebar.py b/conreq/_core/home/components/sidebar.py new file mode 100644 index 00000000..25e57791 --- /dev/null +++ b/conreq/_core/home/components/sidebar.py @@ -0,0 +1,245 @@ +from inspect import iscoroutinefunction + +from reactpy import component, hooks +from reactpy.html import _, div, i, nav +from reactpy_django.hooks import use_connection, use_scope + +from conreq import config +from conreq._core.home.components.welcome import welcome +from conreq.types import ( + HomepageState, + HomepageStateContext, + NavGroup, + SidebarTab, + SidebarTabEvent, + Viewport, +) +from conreq.utils.environment import get_debug_mode, get_safe_mode +from conreq.utils.generic import clean_string + +# pylint: disable=protected-access + +DEBUG = get_debug_mode() +SAFE_MODE = get_safe_mode() +SIDEBAR = {"id": "sidebar", "class_name": "sidebar no-hightlighting blur collapsed"} +SIDEBAR_USER = {"class_name": "sidebar-user clickable"} +USER_PIC = {"class_name": "sidebar-profile-pic"} +USER_PIC_PLACEHOLDER = {"class_name": "fas fa-user"} +USERNAME_CONTAINER = {"class_name": "username-container"} +USERNAME = {"class_name": "username ellipsis"} +NAVIGATION = {"id": "navigation"} +NAV_GROUP = { + "class_name": "nav-group clickable", + "data-bs-toggle": "collapse", + "aria-expanded": "true", +} +GROUP_NAME = {"class_name": "group-name ellipsis"} +GROUP_ICON = {"class_name": "group-icon"} +EXAMPLE_GROUP_ICON = {"class_name": "fas fa-user icon-left"} +GROUP_CARET = {"class_name": "fas fa-caret-up icon-right"} +TABS_COLLAPSE = { + "class_name": "tabs-collapse collapse show", +} +TABS_INDICATOR = {"class_name": "tabs-indicator"} +TABS = {"class_name": "tabs"} +NAV_TAB = {"class_name": "nav-tab clickable"} +NAV_TAB_ACTIVE = {"class_name": "nav-tab clickable active"} +TAB_NAME = {"class_name": "tab-name ellipsis"} +DEFAULT_NAV_GROUP_ICON = i({"class_name": "far fa-circle"}) +SIDEBAR_SAFE_MODE = div( + { + "style": { + "display": "flex", + "align-items": "center", + "justify-content": "center", + "padding": "10px", + "background": "red", + "color": "#FFF", + "font-weight": "700", + } + }, + "SAFE MODE", +) +USER_ADMIN_DEBUG = ("User", "Admin", "Debug") + + +# TODO: Add event history tab. Admin group. Database backed. +# TODO: Add DB backup, media backup, and clear cache somewhere in the admin group +@component +def sidebar(): + state = hooks.use_context(HomepageStateContext) + scope = use_scope() + if not scope["user"].is_authenticated: + return None + + sidebar_tabs = config.homepage.sidebar_tabs + + @hooks.use_effect(dependencies=[]) + async def set_initial_tab(): + # The initial tab has already been set + if state._viewport or state.viewport_intent: + return None + + # Use the configured default tab, if it exists + if config.homepage.default_sidebar_tab: + state.viewport_intent = config.homepage.default_sidebar_tab.viewport + state.set_state(state) + return None + + # Select the top most tab, if it exists + for group in sidebar_tabs: + if not group.tabs or group in USER_ADMIN_DEBUG: + continue + tab: SidebarTab = group.tabs[0] + state.viewport_intent = tab.viewport + state.set_state(state) + return None + + # Tell the user to install some apps, if they don't have any + state.viewport_intent = Viewport(welcome) + state.set_state(state) + + async def username_on_click(_): + if not config.tabs.user_settings.main: + return + state.viewport_intent = config.tabs.user_settings.main.viewport + state.set_state(state) + + return nav( + SIDEBAR, + SIDEBAR_SAFE_MODE if SAFE_MODE else "", + div( + SIDEBAR_USER | {"on_click": username_on_click}, + div(USER_PIC, i(USER_PIC_PLACEHOLDER)), + div( + USERNAME_CONTAINER, + div(USERNAME, scope["user"].get_username()), + ), + ), + div( + # pylint: disable=protected-access + NAVIGATION, # TODO: Change these keys to be database IDs + [ # App tabs + sidebar_group(group, key=group.name) + for group in sidebar_tabs + if group not in USER_ADMIN_DEBUG + ], + [ # User tabs + sidebar_group( + group, + bottom_tabs=config._homepage.user_sidebar_tabs, + key=group.name, + ) + for group in sidebar_tabs + if group == "User" + ], + [ # Admin tabs + sidebar_group( + group, + bottom_tabs=config._homepage.admin_sidebar_tabs, + key=group.name, + ) + for group in sidebar_tabs + if group == "Admin" and scope["user"].is_staff + ], + [ # Debug tabs + sidebar_group( + group, top_tabs=config._homepage.debug_sidebar_tabs, key=group.name + ) + for group in sidebar_tabs + if group == "Debug" and scope["user"].is_staff and DEBUG + ], + ), + ) + + +def _sidebar_tab_class(state: HomepageState, tab: SidebarTab): + if state._viewport and getattr(tab.viewport, "component", None) is getattr( + state._viewport, "component", None + ): + return NAV_TAB_ACTIVE + return NAV_TAB + + +@component +def sidebar_tab(tab: SidebarTab): + state = hooks.use_context(HomepageStateContext) + connection = use_connection() + + async def on_click(event): + if tab.on_click: + click_event = SidebarTabEvent( + event=event, + tab=tab, + connection=connection, + homepage_state=state, + ) + if iscoroutinefunction(tab.on_click): + await tab.on_click(click_event) + else: + tab.on_click(click_event) + return + + # Don't reload if clicking the current tab + if getattr(tab.viewport, "component", None) is getattr( + state._viewport, "component", None + ): + return + + # Switch tabs + if tab.viewport: + # Reset loading state (only set by user defined viewports) + state.viewport_loading = False + + state.viewport_intent = tab.viewport + state.set_state(state) + + return div( + {"on_click": on_click, "key": tab.name} | _sidebar_tab_class(state, tab), + div(TAB_NAME, tab.name), + ) + + +@component +def sidebar_group( + group: NavGroup, + top_tabs: list[SidebarTab] | None = None, + bottom_tabs: list[SidebarTab] | None = None, +): + _top_tabs = top_tabs or [] + _bottom_tabs = bottom_tabs or [] + group_name_clean = clean_string(group.name, lowercase=False) + group_id = f"{group_name_clean}-group" + tabs_id = f"{group_name_clean}-tabs" + + return _( + {"key": group_id}, + div( + NAV_GROUP + | { + "id": group_id, + "data-bs-target": f"#{tabs_id}", + "aria-controls": tabs_id, + "title": group.name, + }, + div( + GROUP_NAME, + div(GROUP_ICON, group.icon or DEFAULT_NAV_GROUP_ICON), + group.name, + ), + i(GROUP_CARET | {"title": f'Collapse the "{group.name}" group.'}), + ), + div( + TABS_COLLAPSE + | { + "id": tabs_id, + }, + div(TABS_INDICATOR), + div( + TABS, # TODO: Change these keys to be database IDs + [sidebar_tab(tab, key=tab.name) for tab in _top_tabs], + [sidebar_tab(tab, key=tab.name) for tab in group.tabs], + [sidebar_tab(tab, key=tab.name) for tab in _bottom_tabs], + ), + ), + ) diff --git a/conreq/_core/home/components/viewport.py b/conreq/_core/home/components/viewport.py new file mode 100644 index 00000000..be2746b8 --- /dev/null +++ b/conreq/_core/home/components/viewport.py @@ -0,0 +1,71 @@ +from reactpy import component, hooks +from reactpy.html import div + +from conreq import config +from conreq.types import HomepageState, HomepageStateContext, Viewport + +# pylint: disable=protected-access + +VIEWPORT_CONTAINER_LOADING = {"class_name": "viewport-container loading"} +HIDDEN = {"hidden": "hidden"} + + +@component +def viewport_loading_animation(): + state = hooks.use_context(HomepageStateContext) + return div( + ( + VIEWPORT_CONTAINER_LOADING + | ( + {} + if state.viewport_intent or state.viewport_loading + else { + "class_name": VIEWPORT_CONTAINER_LOADING["class_name"] + " hidden" + } + ) + ), + config.components.loading_animation.large, + ) + + +@component +def viewport(): + # sourcery skip: assign-if-exp + state = hooks.use_context(HomepageStateContext) + this_viewport = state._viewport + + if not this_viewport: + return div( + { + "class_name": "viewport-container", + "key": "hidden-viewport", + } + | HIDDEN + ) + + return div( + viewport_attrs( + { + "class_name": "viewport-container", + "key": f"{this_viewport.component.__module__}.{this_viewport.component.__name__}", + }, + state, + this_viewport, + ), + this_viewport.component(*this_viewport.args) if this_viewport else "", + ) + + +def viewport_attrs(base_attrs, state: HomepageState, _viewport: Viewport): + # Ensure we are constructing a new class with the pipe operator + new_attrs = base_attrs + new_attrs = ( + new_attrs | HIDDEN + if state.viewport_intent or state.viewport_loading + else new_attrs | {} + ) + if not _viewport.padding: + new_attrs["class_name"] += " no-padding" + if _viewport.html_class: + new_attrs["class_name"] += f" {_viewport.html_class}" + return new_attrs diff --git a/conreq/_core/home/components/welcome.py b/conreq/_core/home/components/welcome.py new file mode 100644 index 00000000..47b2ba6f --- /dev/null +++ b/conreq/_core/home/components/welcome.py @@ -0,0 +1,28 @@ +from reactpy import component, hooks, html +from reactpy_django.components import django_css + +from conreq import config +from conreq.types import HomepageStateContext + + +@component +def welcome(): + state = hooks.use_context(HomepageStateContext) + + async def on_click(_): + # pylint: disable=protected-access + state.viewport_intent = config._homepage.admin_sidebar_tabs[1].viewport + state.set_state(state) + + return html.div( + {"class_name": "welcome"}, + django_css("conreq/welcome.css"), + html.h1("Welcome to Conreq"), + html.p("Looks like you don't have any custom tabs yet."), + html.p("Head over to the App Store and install some!"), + html.button( + {"class_name": "btn btn-primary", "on_click": on_click}, + "Go to App Store ", + html.i({"class_name": "fas fa-arrow-right"}), + ), + ) diff --git a/conreq/core/issue_reporting/migrations/__init__.py b/conreq/_core/home/migrations/__init__.py similarity index 100% rename from conreq/core/issue_reporting/migrations/__init__.py rename to conreq/_core/home/migrations/__init__.py diff --git a/conreq/_core/home/static/conreq/backdrop-(1).jpg b/conreq/_core/home/static/conreq/backdrop-(1).jpg new file mode 100644 index 00000000..ade15b02 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(1).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(10).jpg b/conreq/_core/home/static/conreq/backdrop-(10).jpg new file mode 100644 index 00000000..08fb1335 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(10).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(100).jpg b/conreq/_core/home/static/conreq/backdrop-(100).jpg new file mode 100644 index 00000000..3bd3311d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(100).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(101).jpg b/conreq/_core/home/static/conreq/backdrop-(101).jpg new file mode 100644 index 00000000..3de047f7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(101).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(102).jpg b/conreq/_core/home/static/conreq/backdrop-(102).jpg new file mode 100644 index 00000000..cb356360 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(102).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(103).jpg b/conreq/_core/home/static/conreq/backdrop-(103).jpg new file mode 100644 index 00000000..ad93118d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(103).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(104).jpg b/conreq/_core/home/static/conreq/backdrop-(104).jpg new file mode 100644 index 00000000..a22b40bb Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(104).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(105).jpg b/conreq/_core/home/static/conreq/backdrop-(105).jpg new file mode 100644 index 00000000..4224756e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(105).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(106).jpg b/conreq/_core/home/static/conreq/backdrop-(106).jpg new file mode 100644 index 00000000..10a81efc Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(106).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(107).jpg b/conreq/_core/home/static/conreq/backdrop-(107).jpg new file mode 100644 index 00000000..90faf7a1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(107).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(108).jpg b/conreq/_core/home/static/conreq/backdrop-(108).jpg new file mode 100644 index 00000000..4216859f Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(108).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(109).jpg b/conreq/_core/home/static/conreq/backdrop-(109).jpg new file mode 100644 index 00000000..b89c1027 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(109).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(11).jpg b/conreq/_core/home/static/conreq/backdrop-(11).jpg new file mode 100644 index 00000000..08ea63f2 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(11).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(110).jpg b/conreq/_core/home/static/conreq/backdrop-(110).jpg new file mode 100644 index 00000000..40490131 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(110).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(111).jpg b/conreq/_core/home/static/conreq/backdrop-(111).jpg new file mode 100644 index 00000000..48e36879 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(111).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(112).jpg b/conreq/_core/home/static/conreq/backdrop-(112).jpg new file mode 100644 index 00000000..a7c5c9d1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(112).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(113).jpg b/conreq/_core/home/static/conreq/backdrop-(113).jpg new file mode 100644 index 00000000..964bef65 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(113).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(114).jpg b/conreq/_core/home/static/conreq/backdrop-(114).jpg new file mode 100644 index 00000000..b4f3a3f4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(114).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(115).jpg b/conreq/_core/home/static/conreq/backdrop-(115).jpg new file mode 100644 index 00000000..ba30fc29 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(115).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(116).jpg b/conreq/_core/home/static/conreq/backdrop-(116).jpg new file mode 100644 index 00000000..7e53d818 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(116).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(117).jpg b/conreq/_core/home/static/conreq/backdrop-(117).jpg new file mode 100644 index 00000000..3ca1c572 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(117).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(118).jpg b/conreq/_core/home/static/conreq/backdrop-(118).jpg new file mode 100644 index 00000000..66e0aa84 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(118).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(119).jpg b/conreq/_core/home/static/conreq/backdrop-(119).jpg new file mode 100644 index 00000000..7540b74b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(119).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(12).jpg b/conreq/_core/home/static/conreq/backdrop-(12).jpg new file mode 100644 index 00000000..5e6a07c3 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(12).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(120).jpg b/conreq/_core/home/static/conreq/backdrop-(120).jpg new file mode 100644 index 00000000..aab1c35a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(120).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(121).jpg b/conreq/_core/home/static/conreq/backdrop-(121).jpg new file mode 100644 index 00000000..df9cde2d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(121).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(122).jpg b/conreq/_core/home/static/conreq/backdrop-(122).jpg new file mode 100644 index 00000000..d1c2d6c0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(122).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(123).jpg b/conreq/_core/home/static/conreq/backdrop-(123).jpg new file mode 100644 index 00000000..46f6574c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(123).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(124).jpg b/conreq/_core/home/static/conreq/backdrop-(124).jpg new file mode 100644 index 00000000..d6fb6fd4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(124).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(125).jpg b/conreq/_core/home/static/conreq/backdrop-(125).jpg new file mode 100644 index 00000000..9c567bf1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(125).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(126).jpg b/conreq/_core/home/static/conreq/backdrop-(126).jpg new file mode 100644 index 00000000..f5732002 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(126).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(127).jpg b/conreq/_core/home/static/conreq/backdrop-(127).jpg new file mode 100644 index 00000000..30bf2cf9 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(127).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(128).jpg b/conreq/_core/home/static/conreq/backdrop-(128).jpg new file mode 100644 index 00000000..82438ca5 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(128).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(129).jpg b/conreq/_core/home/static/conreq/backdrop-(129).jpg new file mode 100644 index 00000000..5d98b8ca Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(129).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(13).jpg b/conreq/_core/home/static/conreq/backdrop-(13).jpg new file mode 100644 index 00000000..77117728 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(13).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(130).jpg b/conreq/_core/home/static/conreq/backdrop-(130).jpg new file mode 100644 index 00000000..25698d83 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(130).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(131).jpg b/conreq/_core/home/static/conreq/backdrop-(131).jpg new file mode 100644 index 00000000..76610567 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(131).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(132).jpg b/conreq/_core/home/static/conreq/backdrop-(132).jpg new file mode 100644 index 00000000..b5345031 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(132).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(133).jpg b/conreq/_core/home/static/conreq/backdrop-(133).jpg new file mode 100644 index 00000000..cc7b6d22 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(133).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(134).jpg b/conreq/_core/home/static/conreq/backdrop-(134).jpg new file mode 100644 index 00000000..79ae9561 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(134).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(135).jpg b/conreq/_core/home/static/conreq/backdrop-(135).jpg new file mode 100644 index 00000000..bd1abfb6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(135).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(136).jpg b/conreq/_core/home/static/conreq/backdrop-(136).jpg new file mode 100644 index 00000000..f801d421 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(136).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(137).jpg b/conreq/_core/home/static/conreq/backdrop-(137).jpg new file mode 100644 index 00000000..93e5639b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(137).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(138).jpg b/conreq/_core/home/static/conreq/backdrop-(138).jpg new file mode 100644 index 00000000..e838baf6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(138).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(139).jpg b/conreq/_core/home/static/conreq/backdrop-(139).jpg new file mode 100644 index 00000000..cd6b4234 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(139).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(14).jpg b/conreq/_core/home/static/conreq/backdrop-(14).jpg new file mode 100644 index 00000000..018c25a0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(14).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(140).jpg b/conreq/_core/home/static/conreq/backdrop-(140).jpg new file mode 100644 index 00000000..4ca56eac Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(140).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(141).jpg b/conreq/_core/home/static/conreq/backdrop-(141).jpg new file mode 100644 index 00000000..a65d9a31 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(141).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(142).jpg b/conreq/_core/home/static/conreq/backdrop-(142).jpg new file mode 100644 index 00000000..b948c4e6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(142).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(143).jpg b/conreq/_core/home/static/conreq/backdrop-(143).jpg new file mode 100644 index 00000000..7a6e8b8a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(143).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(144).jpg b/conreq/_core/home/static/conreq/backdrop-(144).jpg new file mode 100644 index 00000000..ad336a66 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(144).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(145).jpg b/conreq/_core/home/static/conreq/backdrop-(145).jpg new file mode 100644 index 00000000..a2105a87 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(145).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(146).jpg b/conreq/_core/home/static/conreq/backdrop-(146).jpg new file mode 100644 index 00000000..f39cb1ca Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(146).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(147).jpg b/conreq/_core/home/static/conreq/backdrop-(147).jpg new file mode 100644 index 00000000..01fd4d58 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(147).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(148).jpg b/conreq/_core/home/static/conreq/backdrop-(148).jpg new file mode 100644 index 00000000..72aa9b14 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(148).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(149).jpg b/conreq/_core/home/static/conreq/backdrop-(149).jpg new file mode 100644 index 00000000..113308c1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(149).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(15).jpg b/conreq/_core/home/static/conreq/backdrop-(15).jpg new file mode 100644 index 00000000..5af378da Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(15).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(150).jpg b/conreq/_core/home/static/conreq/backdrop-(150).jpg new file mode 100644 index 00000000..c680fb1c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(150).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(151).jpg b/conreq/_core/home/static/conreq/backdrop-(151).jpg new file mode 100644 index 00000000..1dbf26bb Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(151).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(152).jpg b/conreq/_core/home/static/conreq/backdrop-(152).jpg new file mode 100644 index 00000000..571062d0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(152).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(153).jpg b/conreq/_core/home/static/conreq/backdrop-(153).jpg new file mode 100644 index 00000000..c8f86002 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(153).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(154).jpg b/conreq/_core/home/static/conreq/backdrop-(154).jpg new file mode 100644 index 00000000..6a5a0c8d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(154).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(155).jpg b/conreq/_core/home/static/conreq/backdrop-(155).jpg new file mode 100644 index 00000000..a1d6b8a2 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(155).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(156).jpg b/conreq/_core/home/static/conreq/backdrop-(156).jpg new file mode 100644 index 00000000..454c5dd8 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(156).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(157).jpg b/conreq/_core/home/static/conreq/backdrop-(157).jpg new file mode 100644 index 00000000..a0f94a26 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(157).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(158).jpg b/conreq/_core/home/static/conreq/backdrop-(158).jpg new file mode 100644 index 00000000..4f69be22 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(158).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(159).jpg b/conreq/_core/home/static/conreq/backdrop-(159).jpg new file mode 100644 index 00000000..bf2b429e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(159).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(16).jpg b/conreq/_core/home/static/conreq/backdrop-(16).jpg new file mode 100644 index 00000000..fd1da31c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(16).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(160).jpg b/conreq/_core/home/static/conreq/backdrop-(160).jpg new file mode 100644 index 00000000..89d73196 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(160).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(161).jpg b/conreq/_core/home/static/conreq/backdrop-(161).jpg new file mode 100644 index 00000000..e7845c86 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(161).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(162).jpg b/conreq/_core/home/static/conreq/backdrop-(162).jpg new file mode 100644 index 00000000..d7c28465 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(162).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(163).jpg b/conreq/_core/home/static/conreq/backdrop-(163).jpg new file mode 100644 index 00000000..23121a5b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(163).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(164).jpg b/conreq/_core/home/static/conreq/backdrop-(164).jpg new file mode 100644 index 00000000..fb6b724e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(164).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(165).jpg b/conreq/_core/home/static/conreq/backdrop-(165).jpg new file mode 100644 index 00000000..357796f0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(165).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(166).jpg b/conreq/_core/home/static/conreq/backdrop-(166).jpg new file mode 100644 index 00000000..c874263e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(166).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(167).jpg b/conreq/_core/home/static/conreq/backdrop-(167).jpg new file mode 100644 index 00000000..a6114f6e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(167).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(168).jpg b/conreq/_core/home/static/conreq/backdrop-(168).jpg new file mode 100644 index 00000000..58675c98 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(168).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(169).jpg b/conreq/_core/home/static/conreq/backdrop-(169).jpg new file mode 100644 index 00000000..30433b72 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(169).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(17).jpg b/conreq/_core/home/static/conreq/backdrop-(17).jpg new file mode 100644 index 00000000..1cd83f52 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(17).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(170).jpg b/conreq/_core/home/static/conreq/backdrop-(170).jpg new file mode 100644 index 00000000..e411e2d0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(170).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(171).jpg b/conreq/_core/home/static/conreq/backdrop-(171).jpg new file mode 100644 index 00000000..c19eaa87 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(171).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(172).jpg b/conreq/_core/home/static/conreq/backdrop-(172).jpg new file mode 100644 index 00000000..f1240cbf Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(172).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(173).jpg b/conreq/_core/home/static/conreq/backdrop-(173).jpg new file mode 100644 index 00000000..b722c0d6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(173).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(174).jpg b/conreq/_core/home/static/conreq/backdrop-(174).jpg new file mode 100644 index 00000000..c1ecaf5b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(174).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(175).jpg b/conreq/_core/home/static/conreq/backdrop-(175).jpg new file mode 100644 index 00000000..72ee8712 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(175).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(176).jpg b/conreq/_core/home/static/conreq/backdrop-(176).jpg new file mode 100644 index 00000000..dd4d4314 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(176).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(177).jpg b/conreq/_core/home/static/conreq/backdrop-(177).jpg new file mode 100644 index 00000000..7d9dd628 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(177).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(178).jpg b/conreq/_core/home/static/conreq/backdrop-(178).jpg new file mode 100644 index 00000000..78c85be3 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(178).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(179).jpg b/conreq/_core/home/static/conreq/backdrop-(179).jpg new file mode 100644 index 00000000..fddc0941 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(179).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(18).jpg b/conreq/_core/home/static/conreq/backdrop-(18).jpg new file mode 100644 index 00000000..0b6afa93 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(18).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(180).jpg b/conreq/_core/home/static/conreq/backdrop-(180).jpg new file mode 100644 index 00000000..87de1f55 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(180).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(181).jpg b/conreq/_core/home/static/conreq/backdrop-(181).jpg new file mode 100644 index 00000000..f0a4b273 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(181).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(182).jpg b/conreq/_core/home/static/conreq/backdrop-(182).jpg new file mode 100644 index 00000000..db677426 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(182).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(183).jpg b/conreq/_core/home/static/conreq/backdrop-(183).jpg new file mode 100644 index 00000000..a837f0d7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(183).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(184).jpg b/conreq/_core/home/static/conreq/backdrop-(184).jpg new file mode 100644 index 00000000..64d92b09 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(184).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(185).jpg b/conreq/_core/home/static/conreq/backdrop-(185).jpg new file mode 100644 index 00000000..a230a158 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(185).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(186).jpg b/conreq/_core/home/static/conreq/backdrop-(186).jpg new file mode 100644 index 00000000..348dd60e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(186).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(187).jpg b/conreq/_core/home/static/conreq/backdrop-(187).jpg new file mode 100644 index 00000000..c65d97b0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(187).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(188).jpg b/conreq/_core/home/static/conreq/backdrop-(188).jpg new file mode 100644 index 00000000..cbf99d57 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(188).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(189).jpg b/conreq/_core/home/static/conreq/backdrop-(189).jpg new file mode 100644 index 00000000..9c881ef7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(189).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(19).jpg b/conreq/_core/home/static/conreq/backdrop-(19).jpg new file mode 100644 index 00000000..bae13b13 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(19).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(190).jpg b/conreq/_core/home/static/conreq/backdrop-(190).jpg new file mode 100644 index 00000000..8b6b85ed Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(190).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(191).jpg b/conreq/_core/home/static/conreq/backdrop-(191).jpg new file mode 100644 index 00000000..93c4a0e6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(191).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(192).jpg b/conreq/_core/home/static/conreq/backdrop-(192).jpg new file mode 100644 index 00000000..f8a67a6e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(192).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(193).jpg b/conreq/_core/home/static/conreq/backdrop-(193).jpg new file mode 100644 index 00000000..89bf0096 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(193).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(194).jpg b/conreq/_core/home/static/conreq/backdrop-(194).jpg new file mode 100644 index 00000000..53cda6e8 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(194).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(195).jpg b/conreq/_core/home/static/conreq/backdrop-(195).jpg new file mode 100644 index 00000000..1734358d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(195).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(196).jpg b/conreq/_core/home/static/conreq/backdrop-(196).jpg new file mode 100644 index 00000000..6084fd3b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(196).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(197).jpg b/conreq/_core/home/static/conreq/backdrop-(197).jpg new file mode 100644 index 00000000..ed80fe9e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(197).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(198).jpg b/conreq/_core/home/static/conreq/backdrop-(198).jpg new file mode 100644 index 00000000..0042af36 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(198).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(199).jpg b/conreq/_core/home/static/conreq/backdrop-(199).jpg new file mode 100644 index 00000000..a00b3668 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(199).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(2).jpg b/conreq/_core/home/static/conreq/backdrop-(2).jpg new file mode 100644 index 00000000..40490131 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(2).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(20).jpg b/conreq/_core/home/static/conreq/backdrop-(20).jpg new file mode 100644 index 00000000..65cd6c3b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(20).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(200).jpg b/conreq/_core/home/static/conreq/backdrop-(200).jpg new file mode 100644 index 00000000..564a01ba Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(200).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(21).jpg b/conreq/_core/home/static/conreq/backdrop-(21).jpg new file mode 100644 index 00000000..027b0863 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(21).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(22).jpg b/conreq/_core/home/static/conreq/backdrop-(22).jpg new file mode 100644 index 00000000..c3398e37 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(22).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(23).jpg b/conreq/_core/home/static/conreq/backdrop-(23).jpg new file mode 100644 index 00000000..c555772a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(23).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(24).jpg b/conreq/_core/home/static/conreq/backdrop-(24).jpg new file mode 100644 index 00000000..44730ab6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(24).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(25).jpg b/conreq/_core/home/static/conreq/backdrop-(25).jpg new file mode 100644 index 00000000..6bfa6269 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(25).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(26).jpg b/conreq/_core/home/static/conreq/backdrop-(26).jpg new file mode 100644 index 00000000..1cf9b3f0 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(26).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(27).jpg b/conreq/_core/home/static/conreq/backdrop-(27).jpg new file mode 100644 index 00000000..cd579b66 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(27).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(28).jpg b/conreq/_core/home/static/conreq/backdrop-(28).jpg new file mode 100644 index 00000000..3170358c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(28).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(29).jpg b/conreq/_core/home/static/conreq/backdrop-(29).jpg new file mode 100644 index 00000000..a8b9cb73 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(29).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(3).jpg b/conreq/_core/home/static/conreq/backdrop-(3).jpg new file mode 100644 index 00000000..1f0e6d5e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(3).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(30).jpg b/conreq/_core/home/static/conreq/backdrop-(30).jpg new file mode 100644 index 00000000..2b5a0f55 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(30).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(31).jpg b/conreq/_core/home/static/conreq/backdrop-(31).jpg new file mode 100644 index 00000000..2f821ea1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(31).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(32).jpg b/conreq/_core/home/static/conreq/backdrop-(32).jpg new file mode 100644 index 00000000..59167948 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(32).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(33).jpg b/conreq/_core/home/static/conreq/backdrop-(33).jpg new file mode 100644 index 00000000..7e5cf6e1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(33).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(34).jpg b/conreq/_core/home/static/conreq/backdrop-(34).jpg new file mode 100644 index 00000000..18a0ccd4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(34).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(35).jpg b/conreq/_core/home/static/conreq/backdrop-(35).jpg new file mode 100644 index 00000000..46c335a9 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(35).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(36).jpg b/conreq/_core/home/static/conreq/backdrop-(36).jpg new file mode 100644 index 00000000..8afe2647 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(36).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(37).jpg b/conreq/_core/home/static/conreq/backdrop-(37).jpg new file mode 100644 index 00000000..c8880ad8 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(37).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(38).jpg b/conreq/_core/home/static/conreq/backdrop-(38).jpg new file mode 100644 index 00000000..9aa304c7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(38).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(39).jpg b/conreq/_core/home/static/conreq/backdrop-(39).jpg new file mode 100644 index 00000000..346040fa Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(39).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(4).jpg b/conreq/_core/home/static/conreq/backdrop-(4).jpg new file mode 100644 index 00000000..76611729 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(4).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(40).jpg b/conreq/_core/home/static/conreq/backdrop-(40).jpg new file mode 100644 index 00000000..3fd61be1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(40).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(41).jpg b/conreq/_core/home/static/conreq/backdrop-(41).jpg new file mode 100644 index 00000000..234e7301 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(41).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(42).jpg b/conreq/_core/home/static/conreq/backdrop-(42).jpg new file mode 100644 index 00000000..08ba26d9 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(42).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(43).jpg b/conreq/_core/home/static/conreq/backdrop-(43).jpg new file mode 100644 index 00000000..5ed84757 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(43).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(44).jpg b/conreq/_core/home/static/conreq/backdrop-(44).jpg new file mode 100644 index 00000000..6725ce21 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(44).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(45).jpg b/conreq/_core/home/static/conreq/backdrop-(45).jpg new file mode 100644 index 00000000..da3453b4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(45).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(46).jpg b/conreq/_core/home/static/conreq/backdrop-(46).jpg new file mode 100644 index 00000000..cdd7e1d6 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(46).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(47).jpg b/conreq/_core/home/static/conreq/backdrop-(47).jpg new file mode 100644 index 00000000..fb3f3c94 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(47).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(48).jpg b/conreq/_core/home/static/conreq/backdrop-(48).jpg new file mode 100644 index 00000000..1f1cc3c7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(48).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(49).jpg b/conreq/_core/home/static/conreq/backdrop-(49).jpg new file mode 100644 index 00000000..a19d9d57 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(49).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(5).jpg b/conreq/_core/home/static/conreq/backdrop-(5).jpg new file mode 100644 index 00000000..9e37728c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(5).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(50).jpg b/conreq/_core/home/static/conreq/backdrop-(50).jpg new file mode 100644 index 00000000..9592f008 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(50).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(51).jpg b/conreq/_core/home/static/conreq/backdrop-(51).jpg new file mode 100644 index 00000000..94b9c43a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(51).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(52).jpg b/conreq/_core/home/static/conreq/backdrop-(52).jpg new file mode 100644 index 00000000..4f32fc68 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(52).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(53).jpg b/conreq/_core/home/static/conreq/backdrop-(53).jpg new file mode 100644 index 00000000..ef548d8b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(53).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(54).jpg b/conreq/_core/home/static/conreq/backdrop-(54).jpg new file mode 100644 index 00000000..8cff929a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(54).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(55).jpg b/conreq/_core/home/static/conreq/backdrop-(55).jpg new file mode 100644 index 00000000..3229c0d1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(55).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(56).jpg b/conreq/_core/home/static/conreq/backdrop-(56).jpg new file mode 100644 index 00000000..f76e1b1b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(56).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(57).jpg b/conreq/_core/home/static/conreq/backdrop-(57).jpg new file mode 100644 index 00000000..47333bed Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(57).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(58).jpg b/conreq/_core/home/static/conreq/backdrop-(58).jpg new file mode 100644 index 00000000..5b4527f4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(58).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(59).jpg b/conreq/_core/home/static/conreq/backdrop-(59).jpg new file mode 100644 index 00000000..27183a67 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(59).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(6).jpg b/conreq/_core/home/static/conreq/backdrop-(6).jpg new file mode 100644 index 00000000..e8dc0f0c Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(6).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(60).jpg b/conreq/_core/home/static/conreq/backdrop-(60).jpg new file mode 100644 index 00000000..103440d5 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(60).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(61).jpg b/conreq/_core/home/static/conreq/backdrop-(61).jpg new file mode 100644 index 00000000..cc036819 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(61).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(62).jpg b/conreq/_core/home/static/conreq/backdrop-(62).jpg new file mode 100644 index 00000000..5e006021 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(62).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(63).jpg b/conreq/_core/home/static/conreq/backdrop-(63).jpg new file mode 100644 index 00000000..41592be7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(63).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(64).jpg b/conreq/_core/home/static/conreq/backdrop-(64).jpg new file mode 100644 index 00000000..a80137be Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(64).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(65).jpg b/conreq/_core/home/static/conreq/backdrop-(65).jpg new file mode 100644 index 00000000..06aae694 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(65).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(66).jpg b/conreq/_core/home/static/conreq/backdrop-(66).jpg new file mode 100644 index 00000000..b4e3704d Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(66).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(67).jpg b/conreq/_core/home/static/conreq/backdrop-(67).jpg new file mode 100644 index 00000000..86279be4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(67).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(68).jpg b/conreq/_core/home/static/conreq/backdrop-(68).jpg new file mode 100644 index 00000000..c6f249c4 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(68).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(69).jpg b/conreq/_core/home/static/conreq/backdrop-(69).jpg new file mode 100644 index 00000000..06cd1697 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(69).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(7).jpg b/conreq/_core/home/static/conreq/backdrop-(7).jpg new file mode 100644 index 00000000..8091f17a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(7).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(70).jpg b/conreq/_core/home/static/conreq/backdrop-(70).jpg new file mode 100644 index 00000000..e3572698 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(70).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(71).jpg b/conreq/_core/home/static/conreq/backdrop-(71).jpg new file mode 100644 index 00000000..321da1fe Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(71).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(72).jpg b/conreq/_core/home/static/conreq/backdrop-(72).jpg new file mode 100644 index 00000000..c6a3d972 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(72).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(73).jpg b/conreq/_core/home/static/conreq/backdrop-(73).jpg new file mode 100644 index 00000000..3024b97a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(73).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(74).jpg b/conreq/_core/home/static/conreq/backdrop-(74).jpg new file mode 100644 index 00000000..a684aa5f Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(74).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(75).jpg b/conreq/_core/home/static/conreq/backdrop-(75).jpg new file mode 100644 index 00000000..2fb20447 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(75).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(76).jpg b/conreq/_core/home/static/conreq/backdrop-(76).jpg new file mode 100644 index 00000000..6e3c1b4b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(76).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(77).jpg b/conreq/_core/home/static/conreq/backdrop-(77).jpg new file mode 100644 index 00000000..730d15fb Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(77).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(78).jpg b/conreq/_core/home/static/conreq/backdrop-(78).jpg new file mode 100644 index 00000000..c898b59a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(78).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(79).jpg b/conreq/_core/home/static/conreq/backdrop-(79).jpg new file mode 100644 index 00000000..8141d25a Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(79).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(8).jpg b/conreq/_core/home/static/conreq/backdrop-(8).jpg new file mode 100644 index 00000000..ffbad8af Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(8).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(80).jpg b/conreq/_core/home/static/conreq/backdrop-(80).jpg new file mode 100644 index 00000000..a1e1a1f9 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(80).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(81).jpg b/conreq/_core/home/static/conreq/backdrop-(81).jpg new file mode 100644 index 00000000..90d82875 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(81).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(82).jpg b/conreq/_core/home/static/conreq/backdrop-(82).jpg new file mode 100644 index 00000000..4f2797a1 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(82).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(83).jpg b/conreq/_core/home/static/conreq/backdrop-(83).jpg new file mode 100644 index 00000000..d29e7e2b Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(83).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(84).jpg b/conreq/_core/home/static/conreq/backdrop-(84).jpg new file mode 100644 index 00000000..ccf81a9f Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(84).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(85).jpg b/conreq/_core/home/static/conreq/backdrop-(85).jpg new file mode 100644 index 00000000..77d329ed Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(85).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(86).jpg b/conreq/_core/home/static/conreq/backdrop-(86).jpg new file mode 100644 index 00000000..9d6be849 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(86).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(87).jpg b/conreq/_core/home/static/conreq/backdrop-(87).jpg new file mode 100644 index 00000000..3cb3701e Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(87).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(88).jpg b/conreq/_core/home/static/conreq/backdrop-(88).jpg new file mode 100644 index 00000000..6a8d9431 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(88).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(89).jpg b/conreq/_core/home/static/conreq/backdrop-(89).jpg new file mode 100644 index 00000000..cacf9956 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(89).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(9).jpg b/conreq/_core/home/static/conreq/backdrop-(9).jpg new file mode 100644 index 00000000..4dbe90e5 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(9).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(90).jpg b/conreq/_core/home/static/conreq/backdrop-(90).jpg new file mode 100644 index 00000000..22667518 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(90).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(91).jpg b/conreq/_core/home/static/conreq/backdrop-(91).jpg new file mode 100644 index 00000000..228bc947 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(91).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(92).jpg b/conreq/_core/home/static/conreq/backdrop-(92).jpg new file mode 100644 index 00000000..98041fcd Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(92).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(93).jpg b/conreq/_core/home/static/conreq/backdrop-(93).jpg new file mode 100644 index 00000000..70877d60 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(93).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(94).jpg b/conreq/_core/home/static/conreq/backdrop-(94).jpg new file mode 100644 index 00000000..d73354da Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(94).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(95).jpg b/conreq/_core/home/static/conreq/backdrop-(95).jpg new file mode 100644 index 00000000..6e22cc46 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(95).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(96).jpg b/conreq/_core/home/static/conreq/backdrop-(96).jpg new file mode 100644 index 00000000..bb2e1bc7 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(96).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(97).jpg b/conreq/_core/home/static/conreq/backdrop-(97).jpg new file mode 100644 index 00000000..52a9bc56 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(97).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(98).jpg b/conreq/_core/home/static/conreq/backdrop-(98).jpg new file mode 100644 index 00000000..0227e2e9 Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(98).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop-(99).jpg b/conreq/_core/home/static/conreq/backdrop-(99).jpg new file mode 100644 index 00000000..b93a41bd Binary files /dev/null and b/conreq/_core/home/static/conreq/backdrop-(99).jpg differ diff --git a/conreq/_core/home/static/conreq/backdrop.css b/conreq/_core/home/static/conreq/backdrop.css new file mode 100644 index 00000000..4b50ac44 --- /dev/null +++ b/conreq/_core/home/static/conreq/backdrop.css @@ -0,0 +1,64 @@ +:root { + --backdrop-opacity: 0.3; +} + +.backdrop-container { + position: absolute; + left: 0px; + top: 0px; + width: 100%; + --backdrop-height: 100vh; + opacity: var(--backdrop-opacity); + -webkit-animation: backdrop-fadein 4s; + animation: backdrop-fadein 4s; + -webkit-filter: brightness(60%); + filter: brightness(60%); +} + +.backdrop-container > * { + -webkit-mask-image: linear-gradient( + to bottom, + rgba(0, 0, 0, 1), + rgba(0, 0, 0, 0.35), + rgba(0, 0, 0, 0.1), + rgba(0, 0, 0, 0) + ); + mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); +} + +.backdrop-container > .backdrop { + width: 100%; + height: var(--backdrop-height); + -o-object-fit: cover; + object-fit: cover; + position: absolute; + transition: all 2s ease; + z-index: 49; +} + +.backdrop-container > .backdrop-tint { + background: black; + width: 100%; + height: var(--backdrop-height); + position: absolute; + opacity: 0.25; + z-index: 50; +} + +@-webkit-keyframes backdrop-fadein { + from { + opacity: 0; + } + to { + opacity: var(--backdrop-opacity); + } +} + +@keyframes backdrop-fadein { + from { + opacity: 0; + } + to { + opacity: var(--backdrop-opacity); + } +} diff --git a/conreq/_core/home/static/conreq/buttons.css b/conreq/_core/home/static/conreq/buttons.css new file mode 100644 index 00000000..719fdd19 --- /dev/null +++ b/conreq/_core/home/static/conreq/buttons.css @@ -0,0 +1,32 @@ +.btn { + border: none; + box-shadow: none; +} + +.btn.btn-primary { + background: #258a6d; +} + +.btn.btn-primary:hover, +.btn.btn-primary:focus { + background: #249e7b; +} + +.btn.btn-primary:active { + background: #28b18b; +} + +.btn.btn-info { + color: #fff; + background: #127d93; +} + +.btn.btn-info:hover, +.btn.btn-info:focus { + color: #fff; + background: #1592ac; +} +.btn.btn-info:active { + color: #fff; + background: #1a9db9; +} diff --git a/conreq/_core/home/static/conreq/components.css b/conreq/_core/home/static/conreq/components.css new file mode 100644 index 00000000..384be29d --- /dev/null +++ b/conreq/_core/home/static/conreq/components.css @@ -0,0 +1,39 @@ +.tabbed-viewport-container { + display: flex; + width: 100%; + min-height: 100%; + height: 100%; + max-height: 100%; + overflow: hidden; +} + +.tabbed-viewport-selector { + width: auto; + margin-top: 100px; + margin-left: 20px; + max-height: calc(100% - 100px); + overflow-y: auto; + overflow-x: hidden; +} + +.tabbed-viewport { + width: -webkit-fill-available; + width: -moz-available; + width: stretch; +} + +.tabbed-viewport iframe { + height: 100%; + width: 100%; +} + +.list-group-item { + display: inline-block; + white-space: nowrap; + min-width: 200px; +} + +.list-group-item.active { + background: var(--accent-color); + border-color: var(--accent-color); +} diff --git a/conreq/_core/home/static/conreq/iframe_events.js b/conreq/_core/home/static/conreq/iframe_events.js new file mode 100644 index 00000000..db045a65 --- /dev/null +++ b/conreq/_core/home/static/conreq/iframe_events.js @@ -0,0 +1,55 @@ +// TODO: Delete this file after view_to_iframe is fleshed out + +window.document.addEventListener( + "reload-page", + async function (event) { + window.location.reload(); + }, + false +); + +window.document.addEventListener( + "generic-toast", + async function (event) { + default_params = { + titleColor: "var(--accent-color)", + messageColor: "var(--accent-color)", + iconColor: "var(--accent-color)", + progressBarColor: "var(--accent-color)", + }; + iziToast.show({ ...default_params, ...event.detail }); + }, + false +); + +window.document.addEventListener( + "success-toast", + async function (event) { + default_params = { + icon: "fas fa-check-circle", + title: "Success", + titleColor: "var(--accent-color)", + messageColor: "var(--accent-color)", + iconColor: "var(--accent-color)", + progressBarColor: "var(--accent-color)", + }; + iziToast.show({ ...default_params, ...event.detail }); + }, + false +); + +window.document.addEventListener( + "warning-toast", + async function (event) { + default_params = { + icon: "fas fa-exclamation-triangle", + title: "Warning", + titleColor: "#9a5c0f", + messageColor: "#9a5c0f", + iconColor: "#c57615", + progressBarColor: "var(--accent-color)", + }; + iziToast.show({ ...default_params, ...event.detail }); + }, + false +); diff --git a/conreq/core/base/static/css/libraries/izi_toast_1.4.0.min.css b/conreq/_core/home/static/conreq/izi_toast_1.4.0.min.css similarity index 99% rename from conreq/core/base/static/css/libraries/izi_toast_1.4.0.min.css rename to conreq/_core/home/static/conreq/izi_toast_1.4.0.min.css index 321823fa..0ade5e33 100644 --- a/conreq/core/base/static/css/libraries/izi_toast_1.4.0.min.css +++ b/conreq/_core/home/static/conreq/izi_toast_1.4.0.min.css @@ -3,4 +3,4 @@ * http://izitoast.marcelodolce.com * by Marcelo Dolce. */ -.iziToast-capsule{font-size:0;height:0;width:100%;transform:translateZ(0);backface-visibility:hidden;transition:transform .5s cubic-bezier(.25,.8,.25,1),height .5s cubic-bezier(.25,.8,.25,1)}.iziToast-capsule,.iziToast-capsule *{box-sizing:border-box}.iziToast-overlay{display:block;position:fixed;top:-100px;left:0;right:0;bottom:-100px;z-index:997}.iziToast{display:inline-block;clear:both;position:relative;font-family:'Lato',Tahoma,Arial;font-size:14px;padding:8px 45px 9px 0;background:rgba(238,238,238,.9);border-color:rgba(238,238,238,.9);width:100%;pointer-events:all;cursor:default;transform:translateX(0);-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-height:54px}.iziToast>.iziToast-progressbar{position:absolute;left:0;bottom:0;width:100%;z-index:1;background:rgba(255,255,255,.2)}.iziToast>.iziToast-progressbar>div{height:2px;width:100%;background:rgba(0,0,0,.3);border-radius:0 0 3px 3px}.iziToast.iziToast-balloon:before{content:'';position:absolute;right:8px;left:auto;width:0;height:0;top:100%;border-right:0 solid transparent;border-left:15px solid transparent;border-top:10px solid #000;border-top-color:inherit;border-radius:0}.iziToast.iziToast-balloon .iziToast-progressbar{top:0;bottom:auto}.iziToast.iziToast-balloon>div{border-radius:0 0 0 3px}.iziToast>.iziToast-cover{position:absolute;left:0;top:0;bottom:0;height:100%;margin:0;background-size:100%;background-position:50% 50%;background-repeat:no-repeat;background-color:rgba(0,0,0,.1)}.iziToast>.iziToast-close{position:absolute;right:0;top:0;border:0;padding:0;opacity:.6;width:42px;height:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJPAAACTwBcGfW0QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAD3SURBVFiF1ZdtDoMgDEBfdi4PwAX8vLFn0qT7wxantojKupmQmCi8R4tSACpgjC2ICCUbEBa8ingjsU1AXRBeR8aLN64FiknswN8CYefBBDQ3whuFESy7WyQMeC0ipEI0A+0FeBvHUFN8xPaUhAH/iKoWsnXHGegy4J0yxialOfaHJAz4bhRzQzgDvdGnz4GbAonZbCQMuBm1K/kcFu8Mp1N2cFFpsxsMuJqqbIGExGl4loARajU1twskJLLhIsID7+tvUoDnIjTg5T9DPH9EBrz8rxjPzciAl9+O8SxI8CzJ8CxKFfh3ynK8Dyb8wNHM/XDqejx/AtNyPO87tNybAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:8px;cursor:pointer;outline:0}.iziToast>.iziToast-close:hover{opacity:1}.iziToast>.iziToast-body{position:relative;padding:0 0 0 10px;height:auto;min-height:36px;margin:0 0 0 15px;text-align:left}.iziToast>.iziToast-body:after{content:"";display:table;clear:both}.iziToast>.iziToast-body .iziToast-texts{margin:10px 0 0;padding-right:2px;display:inline-block;float:left}.iziToast>.iziToast-body .iziToast-inputs{min-height:19px;float:left;margin:3px -2px}.iziToast>.iziToast-body .iziToast-inputs>input:not([type=checkbox]):not([type=radio]),.iziToast>.iziToast-body .iziToast-inputs>select{position:relative;display:inline-block;margin:2px;border-radius:2px;border:0;padding:4px 7px;font-size:13px;letter-spacing:.02em;background:rgba(0,0,0,.1);color:#000;box-shadow:0 0 0 1px rgba(0,0,0,.2);min-height:26px}.iziToast>.iziToast-body .iziToast-inputs>input:not([type=checkbox]):not([type=radio]):focus,.iziToast>.iziToast-body .iziToast-inputs>select:focus{box-shadow:0 0 0 1px rgba(0,0,0,.6)}.iziToast>.iziToast-body .iziToast-buttons{min-height:17px;float:left;margin:4px -2px}.iziToast>.iziToast-body .iziToast-buttons>a,.iziToast>.iziToast-body .iziToast-buttons>button,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]){position:relative;display:inline-block;margin:2px;border-radius:2px;border:0;padding:5px 10px;font-size:12px;letter-spacing:.02em;cursor:pointer;background:rgba(0,0,0,.1);color:#000}.iziToast>.iziToast-body .iziToast-buttons>a:hover,.iziToast>.iziToast-body .iziToast-buttons>button:hover,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):hover{background:rgba(0,0,0,.2)}.iziToast>.iziToast-body .iziToast-buttons>a:focus,.iziToast>.iziToast-body .iziToast-buttons>button:focus,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):focus{box-shadow:0 0 0 1px rgba(0,0,0,.6)}.iziToast>.iziToast-body .iziToast-buttons>a:active,.iziToast>.iziToast-body .iziToast-buttons>button:active,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):active{top:1px}.iziToast>.iziToast-body .iziToast-icon{position:absolute;left:0;top:50%;display:table;font-size:23px;line-height:24px;margin-top:-12px;color:#000;width:24px;height:24px}.iziToast>.iziToast-body .iziToast-icon.ico-info{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCtoPsAAAAKXRSTlMA6PsIvDob+OapavVhWRYPrIry2MxGQ97czsOzpJaMcE0qJQOwVtKjfxCVFeIAAAI3SURBVFjDlJPZsoIwEETnCiGyb8q+qmjl/3/wFmGKwjBROS9QWbtnOqDDGPq4MdMkSc0m7gcDDhF4NRdv8NoL4EcMpzoJglPl/KTDz4WW3IdvXEvxkfIKn7BMZb1bFK4yZFqghZ03jk0nG8N5NBwzx9xU5cxAg8fXi20/hDdC316lcA8o7t16eRuQvW1XGd2d2P8QSHQDDbdIII/9CR3lUF+lbucfJy4WfMS64EJPORnrZxtfc2pjJdnbuags3l04TTtJMXrdTph4Pyg4XAjugAJqMDf5Rf+oXx2/qi4u6nipakIi7CsgiuMSEF9IGKg8heQJKkxIfFSUU/egWSwNrS1fPDtLfon8sZOcYUQml1Qv9a3kfwsEUyJEMgFBKzdV8o3Iw9yAjg1jdLQCV4qbd3no8yD2GugaC3oMbF0NYHCpJYSDhNI5N2DAWB4F4z9Aj/04Cna/x7eVAQ17vRjQZPh+G/kddYv0h49yY4NWNDWMMOMUIRYvlTECmrN8pUAjo5RCMn8KoPmbJ/+Appgnk//Sy90GYBCGgm7IAskQ7D9hFKW4ApB1ei3FSYD9PjGAKygAV+ARFYBH5BsVgG9kkBSAQWKUFYBRZpkUgGVinRWAdUZQDABBQdIcAElDVBUAUUXWHQBZx1gMAGMprM0AsLbVXHsA5trZe93/wp3svQ0YNb/jWV3AIOLsMtlznSNOH7JqjOpDVh7z8qCZR10ftvO4nxeOvPLkpSuvfXnxzKtvXr7j+v8C5ii0e71At7cAAAAASUVORK5CYII=) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-warning{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAkFBMVEUAAAAAAAABAAIAAAABAAIAAAMAAAABAAIBAAIBAAIAAAIAAAABAAIAAAABAAICAAICAAIAAAIAAAAAAAAAAAABAAIBAAIAAAMAAAABAAIBAAMBAAECAAIAAAIAAAIAAAABAAIBAAIBAAMBAAIBAAEAAAIAAAMAAAAAAAABAAECAAICAAIAAAIAAAMAAAQAAAE05yNAAAAAL3RSTlMAB+kD7V8Q+PXicwv7I9iYhkAzJxnx01IV5cmnk2xmHfzexsK4eEw5L7Gei39aRw640awAAAHQSURBVFjD7ZfJdoJAEEWJgCiI4oDiPM8m7///LidErRO7sHrY5u7YXLr7vKqu9kTC0HPmo9n8cJbEQOzqqAdAUHeUZACQuTkGDQBoDJwkHZR0XBz9FkpafXuHP0SJ09mGeJLZ5wwlTmcbA0THPmdEK7XPGTG1zxmInn3OiJ19zkB0jSVTKExMHT0wjAwlWzC0fSPHF1gWRpIhWMYm7fYTFcQGlbemf4dFfdTGg0B/KXM8qBU/3wntbq7rSGqvJ9kla6IpueFJet8fxfem5yhykjyOgNaWF1qSGd5JMNNxpNF7SZQaVh5JzLrTCZIEJ1GyEyVyd+pClMjdaSJK5O40giSRu5PfFiVyd1pAksjdKRnrSsbVdbiHrgT7yss315fkVQPLFQrL+4FHeOXKO5YRFEKv5AiFaMlKLlBpJuVCJlC5sJfvCgztru/3NmBYccPgGTxRAzxn1XGEMUf58pXZvjoOsOCgjL08+b53mtfAM/SVsZcjKLtysQZPqIy9HPP3m/3zKItRwT0LyQo8sTr26tcO83DIUMWIJjierHLsJda/tbNBFY0BP/bKtcM8HNIWCK3aYR4OMzgxo5w5EFLOLKDExXAm9gI4E3iAO94/Ct/lKWuM2LMGbgAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-error{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAeFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVyEiIAAAAJ3RSTlMA3BsB98QV8uSyWVUFz7+kcWMM2LuZioBpTUVBNcq2qaibj4d1azLZZYABAAACZElEQVRYw7WX25KCMAyGAxUoFDkpiohnV97/DXeGBtoOUprZ2dyo1K82fxKbwJJVp+KQZ7so2mX5oThVQLKwjDe9YZu4DF3ptAn6rxY0qQPOEq9fNC9ha3y77a22ba24v+9Xbe8v8x03dPOC2/NdvB6xeSreLfGJpnx0TyotKqLm2s7Jd/WO6ivXNp0tCy02R/aFz5VQ5wUPlUL5fIfj5KIlVGU0nWHm/5QtoTVMWY8mzIVu1K9O7XH2JiU/xnOOT39gnUfj+lFHddx4tFjL3/H8jjzaFCy2Rf0c/fdQyQszI8BDR973IyMSKa4krjxAiW/lkRvMP+bKK9WbYS1ASQg8dKjaUGlYPwRe/WoIkz8tiQchH5QAEMv6T0k8MD4mUyWr4E7jAWqZ+xWcMIYkXvlwggJ3IvFK+wIOcpXAo8n8P0COAaXyKH4OsjBuZB4ew0IGu+H1SebhNazsQBbWm8yj+hFuUJB5eMsN0IUXmYendAFFfJB5uEkRMYwxmcd6zDGRtmQePEykAgubymMRFmMxCSIPCRbTuFNN5OGORTjmNGc0Po0m8Uv0gcCry6xUhR2QeLii9tofbEfhz/qvNti+OfPqNm2Mq6105FUMvdT4GPmufMiV8PqBMkc+DdT1bjYYbjzU/ew23VP4n3mLAz4n8Jtv/Ui3ceTT2mzz5o1mZt0gnBpmsdjqRqVlmplcPdqa7X23kL9brdm2t/uBYDPn2+tyu48mtIGD10JTuUrukVrbCFiwDzcHrPjxKt7PW+AZQyT/WESO+1WL7f3o+WLHL2dYMSZsg6dg/z360ofvP4//v1NPzgs28WlWAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:80%}.iziToast>.iziToast-body .iziToast-icon.ico-success{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAAIVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABt0UjBAAAACnRSTlMApAPhIFn82wgGv8mVtwAAAKVJREFUSMft0LEJAkEARNFFFEw1NFJb8CKjAy1AEOzAxNw+bEEEg6nyFjbY4LOzcBwX7S/gwUxoTdIn+Jbv4Lv8bx446+kB6VsBtK0B+wbMCKxrwL33wOrVeeChX28n7KTOTjgoEu6DRSYAgAAAAkAmAIAAAAIACQIkMkACAAgAIACAyECBKAOJuCagTJwSUCaUAEMAABEBRwAAEQFLbCJgO4bW+AZKGnktR+jAFAAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-question{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfhCQkUEhFovxTxAAAEDklEQVRo3s2ZTWgTQRTHf03ipTRUqghNSgsRjHgQrFUQC6JgD1Kak3gQUUoPqRdBglf1oBehBws9Cn4cGk+1SOmh2upBxAYVoeJHrR9tgq0i1Cq0lqYeks7MbpPdmU00/c8hm9n33v/t7Nt5M2+qMEWQI0QIibZKRrQpHvLL2KI2wnQzzBKrDm2RIeKEy01dTYKUI7G1ZRknQXV5yP10kTYgly1NF/5S6duZ8ES+1iZodyaocrjXxE0OFeifYYgp0mRIkwFChAkRJsIxGgrIP+I0n82fvZW5dc/zkss0O2o1c5mX6/TmaDWl77RFe5YkUW3tKEmyFv0lOvXJ/fTYnmCEFuMRbGHEZqVHLyT9DFjUJmkzJl9DG5MWWwM6Llif/gF1nukB6nhgGwUXdFrE+wiURA8QoM9i0zEWWpXQW+ZsyeRrOMuyEo5Fv4gmy4dXPvqcC+pH2VRYaMwy+OWG+iLGCgm0W0Kv9HdvR8ASjmKCXpuK/bxiV/76A/v5UdDIZuKcJGjrnec5KZ7wwsWFOp6xPX/9mt2sqDe7FO+Kf/fXHBPPDWpdXGhTpLvUG9VKwh1xMDDjkvu+cNDFBTk7ptX1QkKZ850m3duu6fcrWxwdaFFyREJ2j4vOpKP6Du6z4uJCv8sYJIVkCnJBGGZaBONO3roY2EqNrSfIPi7SKP4fdXyNUd6I6wbSAHEl33tFLe+FlSsusnK90A0+oEPcuufZgXnOi+u9LrKSJQZQw6LwqBnv2CKsfHORbFbyQhA6xN/pEuihSdj56Co7LWRjPiKie6gkB2LiKuUqK5kiPkLiz1QJ9K1cNXBAMoUCigNpQ9IqDtMI1HKA4/jyvUsaoSyZLA5kjOjDPFZen8Ql5TsvBskUgjciIPSX3QAXC86DT7VWvlEh/xZ+ij9BDVWJ0QL0SbZq6QaFxoLPcXPmBLveLCc4wXdDK6s+6/vwhCSniFLPXW0NJe5UB8zKCsviqpc7vGPVQFcyZbyPwGD+d5ZnxmNWlhG4xSBZZjivjIWHEQgoDkSMjMwTo54569JSE5IpA7EyJSMTyGTUAUFlO1ZKOtaHTMeL1PhYYFTcihmY2cQ5+ullj7EDkiVfVez2sCTz8yiv84djhg7IJVk81xFWJlPdfHBG0flkRC/zQFZ+DSllNtfDdUsOMCliyGX5uOzU3ZhIXFDof4m1gDuKbEx0t2YS25gVGpcMnr/I1kx3c6piB8P8ZoqEwfMX3ZyCXynJTmq/U7NUXqfUzCbWL1wqVKBQUeESzQYoUlW8TAcVL1RCxUu1G6BYXfFyfQ4VPbDI4T8d2WzgQ6sc/vmxnTsqfHCZQzUJxm1h5dxS5Tu6lQgTZ0ipqRVqSwzTbbLHMt+c19iO76tsx/cLZub+Ali+tYC93olEAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA5LTA5VDIwOjE4OjE3KzAyOjAwjKtfjgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wOS0wOVQyMDoxODoxNyswMjowMP325zIAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-message,.iziToast>.iziToast-body .iziToast-title{padding:0;font-size:14px;line-height:16px;text-align:left;float:left;white-space:normal}.iziToast>.iziToast-body .iziToast-title{color:#000;margin:0}.iziToast>.iziToast-body .iziToast-message{margin:0 0 10px;color:rgba(0,0,0,.6)}.iziToast.iziToast-animateInside .iziToast-buttons-child,.iziToast.iziToast-animateInside .iziToast-icon,.iziToast.iziToast-animateInside .iziToast-inputs-child,.iziToast.iziToast-animateInside .iziToast-message,.iziToast.iziToast-animateInside .iziToast-title{opacity:0}.iziToast-target{position:relative;width:100%;margin:0 auto}.iziToast-target .iziToast-capsule{overflow:hidden}.iziToast-target .iziToast-capsule:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.iziToast-target .iziToast-capsule .iziToast{width:100%;float:left}.iziToast-wrapper{z-index:99999;position:fixed;width:100%;pointer-events:none;display:flex;flex-direction:column}.iziToast-wrapper .iziToast.iziToast-balloon:before{border-right:0 solid transparent;border-left:15px solid transparent;border-top:10px solid #000;border-top-color:inherit;right:8px;left:auto}.iziToast-wrapper-bottomLeft{left:0;bottom:0;text-align:left}.iziToast-wrapper-bottomLeft .iziToast.iziToast-balloon:before,.iziToast-wrapper-topLeft .iziToast.iziToast-balloon:before{border-right:15px solid transparent;border-left:0 solid transparent;right:auto;left:8px}.iziToast-wrapper-bottomRight{right:0;bottom:0;text-align:right}.iziToast-wrapper-topLeft{left:0;top:0;text-align:left}.iziToast-wrapper-topRight{top:0;right:0;text-align:right}.iziToast-wrapper-topCenter{top:0;left:0;right:0;text-align:center}.iziToast-wrapper-bottomCenter,.iziToast-wrapper-center{bottom:0;left:0;right:0;text-align:center}.iziToast-wrapper-center{top:0;justify-content:center;flex-flow:column;align-items:center}.iziToast-rtl{direction:rtl;padding:8px 0 9px 45px;font-family:Tahoma,'Lato',Arial}.iziToast-rtl .iziToast-cover{left:auto;right:0}.iziToast-rtl .iziToast-close{right:auto;left:0}.iziToast-rtl .iziToast-body{padding:0 10px 0 0;margin:0 16px 0 0;text-align:right}.iziToast-rtl .iziToast-body .iziToast-buttons,.iziToast-rtl .iziToast-body .iziToast-inputs,.iziToast-rtl .iziToast-body .iziToast-message,.iziToast-rtl .iziToast-body .iziToast-texts,.iziToast-rtl .iziToast-body .iziToast-title{float:right;text-align:right}.iziToast-rtl .iziToast-body .iziToast-icon{left:auto;right:0}@media only screen and (min-width:568px){.iziToast-wrapper{padding:10px 15px}.iziToast{margin:5px 0;border-radius:3px;width:auto}.iziToast:after{content:'';z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;border-radius:3px;box-shadow:inset 0 -10px 20px -10px rgba(0,0,0,.2),inset 0 0 5px rgba(0,0,0,.1),0 8px 8px -5px rgba(0,0,0,.25)}.iziToast:not(.iziToast-rtl) .iziToast-cover{border-radius:3px 0 0 3px}.iziToast.iziToast-rtl .iziToast-cover{border-radius:0 3px 3px 0}.iziToast.iziToast-color-dark:after{box-shadow:inset 0 -10px 20px -10px rgba(255,255,255,.3),0 10px 10px -5px rgba(0,0,0,.25)}.iziToast.iziToast-balloon .iziToast-progressbar{background:0 0}.iziToast.iziToast-balloon:after{box-shadow:0 10px 10px -5px rgba(0,0,0,.25),inset 0 10px 20px -5px rgba(0,0,0,.25)}.iziToast-target .iziToast:after{box-shadow:inset 0 -10px 20px -10px rgba(0,0,0,.2),inset 0 0 5px rgba(0,0,0,.1)}}.iziToast.iziToast-theme-dark{background:#565c70;border-color:#565c70}.iziToast.iziToast-theme-dark .iziToast-title{color:#fff}.iziToast.iziToast-theme-dark .iziToast-message{color:rgba(255,255,255,.7);font-weight:300}.iziToast.iziToast-theme-dark .iziToast-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfgCR4OIQIPSao6AAAAwElEQVRIx72VUQ6EIAwFmz2XB+AConhjzqTJ7JeGKhLYlyx/BGdoBVpjIpMJNjgIZDKTkQHYmYfwmR2AfAqGFBcO2QjXZCd24bEggvd1KBx+xlwoDpYmvnBUUy68DYXD77ESr8WDtYqvxRex7a8oHP4Wo1Mkt5I68Mc+qYqv1h5OsZmZsQ3gj/02h6cO/KEYx29hu3R+VTTwz6D3TymIP1E8RvEiiVdZfEzicxYLiljSxKIqlnW5seitTW6uYnv/Aqh4whX3mEUrAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA5LTMwVDE0OjMzOjAyKzAyOjAwl6RMVgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wOS0zMFQxNDozMzowMiswMjowMOb59OoAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:8px}.iziToast.iziToast-theme-dark .iziToast-icon{color:#fff}.iziToast.iziToast-theme-dark .iziToast-icon.ico-info{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAflBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vroaSAAAAKXRSTlMA6PsIvDob+OapavVhWRYPrIry2MxGQ97czsOzpJaMcE0qJQOwVtKjfxCVFeIAAAI3SURBVFjDlJPZsoIwEETnCiGyb8q+qmjl/3/wFmGKwjBROS9QWbtnOqDDGPq4MdMkSc0m7gcDDhF4NRdv8NoL4EcMpzoJglPl/KTDz4WW3IdvXEvxkfIKn7BMZb1bFK4yZFqghZ03jk0nG8N5NBwzx9xU5cxAg8fXi20/hDdC316lcA8o7t16eRuQvW1XGd2d2P8QSHQDDbdIII/9CR3lUF+lbucfJy4WfMS64EJPORnrZxtfc2pjJdnbuags3l04TTtJMXrdTph4Pyg4XAjugAJqMDf5Rf+oXx2/qi4u6nipakIi7CsgiuMSEF9IGKg8heQJKkxIfFSUU/egWSwNrS1fPDtLfon8sZOcYUQml1Qv9a3kfwsEUyJEMgFBKzdV8o3Iw9yAjg1jdLQCV4qbd3no8yD2GugaC3oMbF0NYHCpJYSDhNI5N2DAWB4F4z9Aj/04Cna/x7eVAQ17vRjQZPh+G/kddYv0h49yY4NWNDWMMOMUIRYvlTECmrN8pUAjo5RCMn8KoPmbJ/+Appgnk//Sy90GYBCGgm7IAskQ7D9hFKW4ApB1ei3FSYD9PjGAKygAV+ARFYBH5BsVgG9kkBSAQWKUFYBRZpkUgGVinRWAdUZQDABBQdIcAElDVBUAUUXWHQBZx1gMAGMprM0AsLbVXHsA5trZe93/wp3svQ0YNb/jWV3AIOLsMtlznSNOH7JqjOpDVh7z8qCZR10ftvO4nxeOvPLkpSuvfXnxzKtvXr7j+v8C5ii0e71At7cAAAAASUVORK5CYII=) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-warning{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAllBMVEUAAAD////+//3+//3+//3///////z+//3+//3+//3////////////9//3////+//39//3///3////////////+//3+//39//3///z+//z+//7///3///3///3///3////////+//3+//3+//3+//z+//3+//7///3///z////////+//79//3///3///z///v+//3///+trXouAAAAMHRSTlMAB+j87RBf+PXiCwQClSPYhkAzJxnx05tSyadzcmxmHRbp5d7Gwrh4TDkvsYt/WkdQzCITAAAB1UlEQVRYw+3XaXKCQBCGYSIIighoxCVqNJrEPfly/8vFImKXduNsf/Mc4K1y7FnwlMLQc/bUbj85R6bA1LXRDICg6RjJcZa7NQYtnLUGTpERSiOXxrOPkv9s30iGKDmtbYir3H7OUHJa2ylAuvZzRvzUfs7Ii/2cgfTt54x82s8ZSM848gJmYtroQzA2jHwA+LkBIEuMGt+QIng1igzlyMrkuP2CyOi47axRaYTL5jhDJehoR+aovC29s3iIyly3Eb+hRCvZo2qsGTnhKr2cLDS+J73GsqBI9W80UCmWWpEuhIjh6ZRGjyNRarjzKGJ2Ou2himCvjHwqI+rTqQdlRH06TZQR9ek0hiqiPp06mV4ke7QPX6ERUZxO8Uo3sqrfhxvoRrCpvXwL/UjR9GRHMIvLgke4d5QbiwhM6JV2YKKF4vIl7XIBkwm4keryJVmvk/TfwcmPwQNkUQuyA2/sYGwnXL7GPu4bW1jYsmevrNj09/MGZMOEPXslQVqO8hqykD17JfPHP/bmo2yGGpdZiH3IZvzZa7B3+IdDjjpjesHJcvbs5dZ/e+cddVoDdvlq7x12Nac+iN7e4R8OXTjp0pw5CGnOLNDEzeBs5gVwFniAO+8f8wvfeXP2hyqnmwAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-error{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAeFBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////GqOSsAAAAJ3RSTlMA3BsB98QV8uSyWVUFz6RxYwzYvbupmYqAaU1FQTXKv7abj4d1azKNUit3AAACZElEQVRYw7WXaZOCMAyGw30UORRQBLxX/v8/3BkaWjrY2szO5otKfGrzJrEp6Kw6F8f8sI+i/SE/FucKSBaWiT8p5idlaEtnXTB9tKDLLHAvdSatOan3je93k9F2vRF36+mr1a6eH2NFNydoHq/ieU/UXcWjjk9XykdNWq2ywtp4tXL6Wb2T/MqtzzZutsrNyfvA51KoQROhVCjfrnASIRpSVUZiD5v4RbWExjRdJzSmOsZFvzYz59kRSr6V5zE+/QELHkNdb3VRx45HS1b1u+zfkkcbRAZ3qJ9l/A4qefHUDMShJe+6kZKJDD2pLQ9Q4lu+5Q7rz7Plperd7AtQEgIPI6o2dxr2D4GXvxqCiKcn8cD4gxIAEt7/GYkHL16KqeJd0NB4gJbXfgVnzCGJlzGcocCVSLzUvoAj9xJ4NF7/R8gxoVQexc/hgBpSebjPjgPs59cHmYfn7NkDb6wXmUf1I1ygIPPw4gtgCE8yDw8eAop4J/PQcBExjQmZx37MsZB2ZB4cLKQCG5vKYxMWSzMxIg8pNtOyUkvkocEmXGo69mh8FgnxS4yBwMvDrJSNHZB4uC3ayz/YkcIP4lflwVIT+OU07ZSjrbTkZQ6dTPkYubZ8GC/Cqxu6WvJZII93dcCw46GdNqdpTeF/tiMOuDGB9z/NI6NvyWetGPM0g+bVNeovBmamHXWj0nCbEaGeTMN2PWrqd6cM26ZxP2DeJvj+ph/30Zi/GmRbtlK5SptI+nwGGnvH6gUruT+L16MJHF+58rwNIifTV0vM8+hwMeOXAb6Yx0wXT+b999WXfvn+8/X/F7fWzjdTord5AAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:80%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-success{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMApAPhIFn82wgGv8mVtwAAAKVJREFUSMft0LEJAkEARNFFFEw1NFJb8CKjAy1AEOzAxNw+bEEEg6nyFjbY4LOzcBwX7S/gwUxoTdIn+Jbv4Lv8bx446+kB6VsBtK0B+wbMCKxrwL33wOrVeeChX28n7KTOTjgoEu6DRSYAgAAAAkAmAIAAAAIACQIkMkACAAgAIACAyECBKAOJuCagTJwSUCaUAEMAABEBRwAAEQFLbCJgO4bW+AZKGnktR+jAFAAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-question{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfhCQkUEg18vki+AAAETUlEQVRo3s1ZTWhbRxD+VlIuxsLFCYVIIQYVopBDoK5bKDWUBupDMNbJ5FBKg/FBziUQdE9yaC+FHBrwsdCfQ9RTGoLxwWl+DqHEojUFFydxnB9bInZDqOsErBrr6yGvs/ueX97bldTKo4Pe7puZb3Z33s7srIIjMY1jyCEjP6ImvyX8pF64arSHznKC06wzijY5xSKz7YbuYokV2lODsyyxqz3gSY6z6gCuqcpxJluFH+Z8U+D/0jyHoxFUBHgfvsGHIS9WMIUlVFFDFTUAGWSRQRY5HMeBEP6b+Ew9dh/7INd2jGeO59kfKdXP85zbIbfGQVf4sYC3N1hm3lo6zzIbPvk6x+zBk7wQGMEMB5xncIAzAS0XrFySSV72iS1yyBVcdA1x0afrsoUJgdFfY2+z8ADAXl7zz0KcwJiPfZKpVuABgClO+nRG+QIHDdfb4qlWwUXvKW4Z7vi6L4J9vg+vbfCeCeZH2RfOdMOc/HbCA4BvIW6EMQz7XK/ltd+hP+VzR9mgva2YSfyGI17fA7ynnocqeQNFfIJ0oHsdv6CC2+rXGBN6cQdveY3fcVRtmy/HDete+93zy8jA8zV7YkwYMrjHzRddRsCdiVCwwmh6wg9iTNC7Y9XIF1iS7kbUpsvvGEdPuTfSgAEjRpR096x0liPFD/Eqt2NMuBQzB2XhrACAApjFsuQFh9XdGAX70B3oSuNdnMVBaX+sopYxjwVpHFBVACyKTXNoktjD+6Ll8xhenS9MAAkAI/Lux2YNUOs4I413Ypg1SgEAu7kpFvWjaeJe0fJHDGe/cNaZBkekudw8PMA+0fMwlndZeAsJ5KR/qhUDUJCnSiyvRsolkJHGUgvjH8QXDgZopEzKMKDqCKrwEQ4C6MH7GEXC665buLJG8hlQc4LP4paxfJrOqYVYYY2UARfEIazTbgDg2dB98GebzJd54b8L/iWNdLyooeR6CHyZ+6xk0yKxkYg6nEVSUG4VJ9QJ9cxRCxO+9WiOyvgUeexXP1hLGH5nGuBWVtiSp4vqe3VP0UFWI9Wan4Er3v8q7jjPWVtm4FtcQQMrOKO2nOQCM5AyDMi56FDrKHA/1nyppS1ppBpYaE8wciEjGI2AaeM41kI4doDX4XiT3Qm1gevyruCgZg9P8xIv8m1nCzTKq6oiJ9xTMiZ505P5m8cdZ0CnZMVXHVljM7WMBzxpyDxygtdxoCEFTaMIWbZU85UvBjgUMYy0fBaAF8V1Lj9qWQ1aMZ5f4k9r+AGMSkMP1vZoZih6k6sicc5h/OFHM9vDqU/VIU7zJZdYYsKGH4g4nAJMGiXZRds1pVMoZ69RM5vfkbh0qkBhsnS2RLMLilQdL9MBHS9UAh0v1e6CYnXHy/WeeCcvLDwl/9OVze69tPKM+M+v7eJN6OzFpWdEF0ucDbhVNFXadnVrmJFlkVNGTS2M6pzmhMvltfPhnN2B63sVuL7fcNP3D1TSk2ihosPrAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA5LTA5VDIwOjE4OjEzKzAyOjAweOR7nQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wOS0wOVQyMDoxODoxMyswMjowMAm5wyEAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-buttons>a,.iziToast.iziToast-theme-dark .iziToast-buttons>button,.iziToast.iziToast-theme-dark .iziToast-buttons>input{color:#fff;background:rgba(255,255,255,.1)}.iziToast.iziToast-theme-dark .iziToast-buttons>a:hover,.iziToast.iziToast-theme-dark .iziToast-buttons>button:hover,.iziToast.iziToast-theme-dark .iziToast-buttons>input:hover{background:rgba(255,255,255,.2)}.iziToast.iziToast-theme-dark .iziToast-buttons>a:focus,.iziToast.iziToast-theme-dark .iziToast-buttons>button:focus,.iziToast.iziToast-theme-dark .iziToast-buttons>input:focus{box-shadow:0 0 0 1px rgba(255,255,255,.6)}.iziToast.iziToast-color-red{background:rgba(255,175,180,.9);border-color:rgba(255,175,180,.9)}.iziToast.iziToast-color-orange{background:rgba(255,207,165,.9);border-color:rgba(255,207,165,.9)}.iziToast.iziToast-color-yellow{background:rgba(255,249,178,.9);border-color:rgba(255,249,178,.9)}.iziToast.iziToast-color-blue{background:rgba(157,222,255,.9);border-color:rgba(157,222,255,.9)}.iziToast.iziToast-color-green{background:rgba(166,239,184,.9);border-color:rgba(166,239,184,.9)}.iziToast.iziToast-layout2 .iziToast-body .iziToast-message,.iziToast.iziToast-layout2 .iziToast-body .iziToast-texts{width:100%}.iziToast.iziToast-layout3{border-radius:2px}.iziToast.iziToast-layout3::after{display:none}.iziToast .revealIn,.iziToast.revealIn{-webkit-animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both;-moz-animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both;animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both}.iziToast .slideIn,.iziToast.slideIn{-webkit-animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both}.iziToast.bounceInLeft{-webkit-animation:iziT-bounceInLeft .7s ease-in-out both;animation:iziT-bounceInLeft .7s ease-in-out both}.iziToast.bounceInRight{-webkit-animation:iziT-bounceInRight .85s ease-in-out both;animation:iziT-bounceInRight .85s ease-in-out both}.iziToast.bounceInDown{-webkit-animation:iziT-bounceInDown .7s ease-in-out both;animation:iziT-bounceInDown .7s ease-in-out both}.iziToast.bounceInUp{-webkit-animation:iziT-bounceInUp .7s ease-in-out both;animation:iziT-bounceInUp .7s ease-in-out both}.iziToast .fadeIn,.iziToast.fadeIn{-webkit-animation:iziT-fadeIn .5s ease both;animation:iziT-fadeIn .5s ease both}.iziToast.fadeInUp{-webkit-animation:iziT-fadeInUp .7s ease both;animation:iziT-fadeInUp .7s ease both}.iziToast.fadeInDown{-webkit-animation:iziT-fadeInDown .7s ease both;animation:iziT-fadeInDown .7s ease both}.iziToast.fadeInLeft{-webkit-animation:iziT-fadeInLeft .85s cubic-bezier(.25,.8,.25,1) both;animation:iziT-fadeInLeft .85s cubic-bezier(.25,.8,.25,1) both}.iziToast.fadeInRight{-webkit-animation:iziT-fadeInRight .85s cubic-bezier(.25,.8,.25,1) both;animation:iziT-fadeInRight .85s cubic-bezier(.25,.8,.25,1) both}.iziToast.flipInX{-webkit-animation:iziT-flipInX .85s cubic-bezier(.35,0,.25,1) both;animation:iziT-flipInX .85s cubic-bezier(.35,0,.25,1) both}.iziToast.fadeOut{-webkit-animation:iziT-fadeOut .7s ease both;animation:iziT-fadeOut .7s ease both}.iziToast.fadeOutDown{-webkit-animation:iziT-fadeOutDown .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-fadeOutDown .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast.fadeOutUp{-webkit-animation:iziT-fadeOutUp .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-fadeOutUp .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast.fadeOutLeft{-webkit-animation:iziT-fadeOutLeft .5s ease both;animation:iziT-fadeOutLeft .5s ease both}.iziToast.fadeOutRight{-webkit-animation:iziT-fadeOutRight .5s ease both;animation:iziT-fadeOutRight .5s ease both}.iziToast.flipOutX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation:iziT-flipOutX .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-flipOutX .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast-overlay.fadeIn{-webkit-animation:iziT-fadeIn .5s ease both;animation:iziT-fadeIn .5s ease both}.iziToast-overlay.fadeOut{-webkit-animation:iziT-fadeOut .7s ease both;animation:iziT-fadeOut .7s ease both}@-webkit-keyframes iziT-revealIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,1)}to{opacity:1}}@-moz-keyframes iziT-revealIn{0%{opacity:0;-moz-transform:scale3d(.3,.3,1)}to{opacity:1}}@-webkit-keyframes iziT-slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}to{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes iziT-slideIn{0%{opacity:0;-moz-transform:translateX(50px)}to{opacity:1;-moz-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInLeft{0%{opacity:0;-webkit-transform:translateX(280px)}50%{opacity:1;-webkit-transform:translateX(-20px)}70%{-webkit-transform:translateX(10px)}to{-webkit-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInRight{0%{opacity:0;-webkit-transform:translateX(-280px)}50%{opacity:1;-webkit-transform:translateX(20px)}70%{-webkit-transform:translateX(-10px)}to{-webkit-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInDown{0%{opacity:0;-webkit-transform:translateY(-200px)}50%{opacity:1;-webkit-transform:translateY(10px)}70%{-webkit-transform:translateY(-5px)}to{-webkit-transform:translateY(0)}}@-webkit-keyframes iziT-bounceInUp{0%{opacity:0;-webkit-transform:translateY(200px)}50%{opacity:1;-webkit-transform:translateY(-10px)}70%{-webkit-transform:translateY(5px)}to{-webkit-transform:translateY(0)}}@-webkit-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-webkit-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-webkit-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-moz-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-webkit-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-o-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-moz-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-webkit-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-o-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-moz-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-webkit-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-o-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-moz-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-webkit-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-o-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-moz-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-webkit-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-o-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-moz-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-webkit-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-o-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-moz-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-o-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-moz-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-webkit-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-o-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-moz-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-o-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-moz-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-o-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-moz-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-webkit-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-o-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-moz-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-o-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-moz-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-o-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-moz-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-webkit-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-o-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}} \ No newline at end of file +.iziToast-capsule{font-size:0;height:0;width:100%;transform:translateZ(0);backface-visibility:hidden;transition:transform .5s cubic-bezier(.25,.8,.25,1),height .5s cubic-bezier(.25,.8,.25,1)}.iziToast-capsule,.iziToast-capsule *{box-sizing:border-box}.iziToast-overlay{display:block;position:fixed;top:-100px;left:0;right:0;bottom:-100px;z-index:997}.iziToast{display:inline-block;clear:both;position:relative;font-family:'Lato',Tahoma,Arial;font-size:14px;padding:8px 45px 9px 0;background:rgba(238,238,238,.9);border-color:rgba(238,238,238,.9);width:100%;pointer-events:all;cursor:default;transform:translateX(0);-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-height:54px}.iziToast>.iziToast-progressbar{position:absolute;left:0;bottom:0;width:100%;z-index:1;background:rgba(255,255,255,.2)}.iziToast>.iziToast-progressbar>div{height:2px;width:100%;background:rgba(0,0,0,.3);border-radius:0 0 3px 3px}.iziToast.iziToast-balloon:before{content:'';position:absolute;right:8px;left:auto;width:0;height:0;top:100%;border-right:0 solid transparent;border-left:15px solid transparent;border-top:10px solid #000;border-top-color:inherit;border-radius:0}.iziToast.iziToast-balloon .iziToast-progressbar{top:0;bottom:auto}.iziToast.iziToast-balloon>div{border-radius:0 0 0 3px}.iziToast>.iziToast-cover{position:absolute;left:0;top:0;bottom:0;height:100%;margin:0;background-size:100%;background-position:50% 50%;background-repeat:no-repeat;background-color:rgba(0,0,0,.1)}.iziToast>.iziToast-close{position:absolute;right:0;top:0;border:0;padding:0;opacity:.6;width:42px;height:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJPAAACTwBcGfW0QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAD3SURBVFiF1ZdtDoMgDEBfdi4PwAX8vLFn0qT7wxantojKupmQmCi8R4tSACpgjC2ICCUbEBa8ingjsU1AXRBeR8aLN64FiknswN8CYefBBDQ3whuFESy7WyQMeC0ipEI0A+0FeBvHUFN8xPaUhAH/iKoWsnXHGegy4J0yxialOfaHJAz4bhRzQzgDvdGnz4GbAonZbCQMuBm1K/kcFu8Mp1N2cFFpsxsMuJqqbIGExGl4loARajU1twskJLLhIsID7+tvUoDnIjTg5T9DPH9EBrz8rxjPzciAl9+O8SxI8CzJ8CxKFfh3ynK8Dyb8wNHM/XDqejx/AtNyPO87tNybAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:8px;cursor:pointer;outline:0}.iziToast>.iziToast-close:hover{opacity:1}.iziToast>.iziToast-body{position:relative;padding:0 0 0 10px;height:auto;min-height:36px;margin:0 0 0 15px;text-align:left}.iziToast>.iziToast-body:after{content:"";display:table;clear:both}.iziToast>.iziToast-body .iziToast-texts{margin:10px 0 0;padding-right:2px;display:inline-block;float:left}.iziToast>.iziToast-body .iziToast-inputs{min-height:19px;float:left;margin:3px -2px}.iziToast>.iziToast-body .iziToast-inputs>input:not([type=checkbox]):not([type=radio]),.iziToast>.iziToast-body .iziToast-inputs>select{position:relative;display:inline-block;margin:2px;border-radius:2px;border:0;padding:4px 7px;font-size:13px;letter-spacing:.02em;background:rgba(0,0,0,.1);color:#000;box-shadow:0 0 0 1px rgba(0,0,0,.2);min-height:26px}.iziToast>.iziToast-body .iziToast-inputs>input:not([type=checkbox]):not([type=radio]):focus,.iziToast>.iziToast-body .iziToast-inputs>select:focus{box-shadow:0 0 0 1px rgba(0,0,0,.6)}.iziToast>.iziToast-body .iziToast-buttons{min-height:17px;float:left;margin:4px -2px}.iziToast>.iziToast-body .iziToast-buttons>a,.iziToast>.iziToast-body .iziToast-buttons>button,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]){position:relative;display:inline-block;margin:2px;border-radius:2px;border:0;padding:5px 10px;font-size:12px;letter-spacing:.02em;cursor:pointer;background:rgba(0,0,0,.1);color:#000}.iziToast>.iziToast-body .iziToast-buttons>a:hover,.iziToast>.iziToast-body .iziToast-buttons>button:hover,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):hover{background:rgba(0,0,0,.2)}.iziToast>.iziToast-body .iziToast-buttons>a:focus,.iziToast>.iziToast-body .iziToast-buttons>button:focus,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):focus{box-shadow:0 0 0 1px rgba(0,0,0,.6)}.iziToast>.iziToast-body .iziToast-buttons>a:active,.iziToast>.iziToast-body .iziToast-buttons>button:active,.iziToast>.iziToast-body .iziToast-buttons>input:not([type=checkbox]):not([type=radio]):active{top:1px}.iziToast>.iziToast-body .iziToast-icon{position:absolute;left:0;top:50%;display:table;font-size:23px;line-height:24px;margin-top:-12px;color:#000;width:24px;height:24px}.iziToast>.iziToast-body .iziToast-icon.ico-info{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCtoPsAAAAKXRSTlMA6PsIvDob+OapavVhWRYPrIry2MxGQ97czsOzpJaMcE0qJQOwVtKjfxCVFeIAAAI3SURBVFjDlJPZsoIwEETnCiGyb8q+qmjl/3/wFmGKwjBROS9QWbtnOqDDGPq4MdMkSc0m7gcDDhF4NRdv8NoL4EcMpzoJglPl/KTDz4WW3IdvXEvxkfIKn7BMZb1bFK4yZFqghZ03jk0nG8N5NBwzx9xU5cxAg8fXi20/hDdC316lcA8o7t16eRuQvW1XGd2d2P8QSHQDDbdIII/9CR3lUF+lbucfJy4WfMS64EJPORnrZxtfc2pjJdnbuags3l04TTtJMXrdTph4Pyg4XAjugAJqMDf5Rf+oXx2/qi4u6nipakIi7CsgiuMSEF9IGKg8heQJKkxIfFSUU/egWSwNrS1fPDtLfon8sZOcYUQml1Qv9a3kfwsEUyJEMgFBKzdV8o3Iw9yAjg1jdLQCV4qbd3no8yD2GugaC3oMbF0NYHCpJYSDhNI5N2DAWB4F4z9Aj/04Cna/x7eVAQ17vRjQZPh+G/kddYv0h49yY4NWNDWMMOMUIRYvlTECmrN8pUAjo5RCMn8KoPmbJ/+Appgnk//Sy90GYBCGgm7IAskQ7D9hFKW4ApB1ei3FSYD9PjGAKygAV+ARFYBH5BsVgG9kkBSAQWKUFYBRZpkUgGVinRWAdUZQDABBQdIcAElDVBUAUUXWHQBZx1gMAGMprM0AsLbVXHsA5trZe93/wp3svQ0YNb/jWV3AIOLsMtlznSNOH7JqjOpDVh7z8qCZR10ftvO4nxeOvPLkpSuvfXnxzKtvXr7j+v8C5ii0e71At7cAAAAASUVORK5CYII=) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-warning{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAkFBMVEUAAAAAAAABAAIAAAABAAIAAAMAAAABAAIBAAIBAAIAAAIAAAABAAIAAAABAAICAAICAAIAAAIAAAAAAAAAAAABAAIBAAIAAAMAAAABAAIBAAMBAAECAAIAAAIAAAIAAAABAAIBAAIBAAMBAAIBAAEAAAIAAAMAAAAAAAABAAECAAICAAIAAAIAAAMAAAQAAAE05yNAAAAAL3RSTlMAB+kD7V8Q+PXicwv7I9iYhkAzJxnx01IV5cmnk2xmHfzexsK4eEw5L7Gei39aRw640awAAAHQSURBVFjD7ZfJdoJAEEWJgCiI4oDiPM8m7///LidErRO7sHrY5u7YXLr7vKqu9kTC0HPmo9n8cJbEQOzqqAdAUHeUZACQuTkGDQBoDJwkHZR0XBz9FkpafXuHP0SJ09mGeJLZ5wwlTmcbA0THPmdEK7XPGTG1zxmInn3OiJ19zkB0jSVTKExMHT0wjAwlWzC0fSPHF1gWRpIhWMYm7fYTFcQGlbemf4dFfdTGg0B/KXM8qBU/3wntbq7rSGqvJ9kla6IpueFJet8fxfem5yhykjyOgNaWF1qSGd5JMNNxpNF7SZQaVh5JzLrTCZIEJ1GyEyVyd+pClMjdaSJK5O40giSRu5PfFiVyd1pAksjdKRnrSsbVdbiHrgT7yss315fkVQPLFQrL+4FHeOXKO5YRFEKv5AiFaMlKLlBpJuVCJlC5sJfvCgztru/3NmBYccPgGTxRAzxn1XGEMUf58pXZvjoOsOCgjL08+b53mtfAM/SVsZcjKLtysQZPqIy9HPP3m/3zKItRwT0LyQo8sTr26tcO83DIUMWIJjierHLsJda/tbNBFY0BP/bKtcM8HNIWCK3aYR4OMzgxo5w5EFLOLKDExXAm9gI4E3iAO94/Ct/lKWuM2LMGbgAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-error{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAeFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVyEiIAAAAJ3RSTlMA3BsB98QV8uSyWVUFz7+kcWMM2LuZioBpTUVBNcq2qaibj4d1azLZZYABAAACZElEQVRYw7WX25KCMAyGAxUoFDkpiohnV97/DXeGBtoOUprZ2dyo1K82fxKbwJJVp+KQZ7so2mX5oThVQLKwjDe9YZu4DF3ptAn6rxY0qQPOEq9fNC9ha3y77a22ba24v+9Xbe8v8x03dPOC2/NdvB6xeSreLfGJpnx0TyotKqLm2s7Jd/WO6ivXNp0tCy02R/aFz5VQ5wUPlUL5fIfj5KIlVGU0nWHm/5QtoTVMWY8mzIVu1K9O7XH2JiU/xnOOT39gnUfj+lFHddx4tFjL3/H8jjzaFCy2Rf0c/fdQyQszI8BDR973IyMSKa4krjxAiW/lkRvMP+bKK9WbYS1ASQg8dKjaUGlYPwRe/WoIkz8tiQchH5QAEMv6T0k8MD4mUyWr4E7jAWqZ+xWcMIYkXvlwggJ3IvFK+wIOcpXAo8n8P0COAaXyKH4OsjBuZB4ew0IGu+H1SebhNazsQBbWm8yj+hFuUJB5eMsN0IUXmYendAFFfJB5uEkRMYwxmcd6zDGRtmQePEykAgubymMRFmMxCSIPCRbTuFNN5OGORTjmNGc0Po0m8Uv0gcCry6xUhR2QeLii9tofbEfhz/qvNti+OfPqNm2Mq6105FUMvdT4GPmufMiV8PqBMkc+DdT1bjYYbjzU/ew23VP4n3mLAz4n8Jtv/Ui3ceTT2mzz5o1mZt0gnBpmsdjqRqVlmplcPdqa7X23kL9brdm2t/uBYDPn2+tyu48mtIGD10JTuUrukVrbCFiwDzcHrPjxKt7PW+AZQyT/WESO+1WL7f3o+WLHL2dYMSZsg6dg/z360ofvP4//v1NPzgs28WlWAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:80%}.iziToast>.iziToast-body .iziToast-icon.ico-success{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAAIVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABt0UjBAAAACnRSTlMApAPhIFn82wgGv8mVtwAAAKVJREFUSMft0LEJAkEARNFFFEw1NFJb8CKjAy1AEOzAxNw+bEEEg6nyFjbY4LOzcBwX7S/gwUxoTdIn+Jbv4Lv8bx446+kB6VsBtK0B+wbMCKxrwL33wOrVeeChX28n7KTOTjgoEu6DRSYAgAAAAkAmAIAAAAIACQIkMkACAAgAIACAyECBKAOJuCagTJwSUCaUAEMAABEBRwAAEQFLbCJgO4bW+AZKGnktR+jAFAAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-icon.ico-question{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfhCQkUEhFovxTxAAAEDklEQVRo3s2ZTWgTQRTHf03ipTRUqghNSgsRjHgQrFUQC6JgD1Kak3gQUUoPqRdBglf1oBehBws9Cn4cGk+1SOmh2upBxAYVoeJHrR9tgq0i1Cq0lqYeks7MbpPdmU00/c8hm9n33v/t7Nt5M2+qMEWQI0QIibZKRrQpHvLL2KI2wnQzzBKrDm2RIeKEy01dTYKUI7G1ZRknQXV5yP10kTYgly1NF/5S6duZ8ES+1iZodyaocrjXxE0OFeifYYgp0mRIkwFChAkRJsIxGgrIP+I0n82fvZW5dc/zkss0O2o1c5mX6/TmaDWl77RFe5YkUW3tKEmyFv0lOvXJ/fTYnmCEFuMRbGHEZqVHLyT9DFjUJmkzJl9DG5MWWwM6Llif/gF1nukB6nhgGwUXdFrE+wiURA8QoM9i0zEWWpXQW+ZsyeRrOMuyEo5Fv4gmy4dXPvqcC+pH2VRYaMwy+OWG+iLGCgm0W0Kv9HdvR8ASjmKCXpuK/bxiV/76A/v5UdDIZuKcJGjrnec5KZ7wwsWFOp6xPX/9mt2sqDe7FO+Kf/fXHBPPDWpdXGhTpLvUG9VKwh1xMDDjkvu+cNDFBTk7ptX1QkKZ850m3duu6fcrWxwdaFFyREJ2j4vOpKP6Du6z4uJCv8sYJIVkCnJBGGZaBONO3roY2EqNrSfIPi7SKP4fdXyNUd6I6wbSAHEl33tFLe+FlSsusnK90A0+oEPcuufZgXnOi+u9LrKSJQZQw6LwqBnv2CKsfHORbFbyQhA6xN/pEuihSdj56Co7LWRjPiKie6gkB2LiKuUqK5kiPkLiz1QJ9K1cNXBAMoUCigNpQ9IqDtMI1HKA4/jyvUsaoSyZLA5kjOjDPFZen8Ql5TsvBskUgjciIPSX3QAXC86DT7VWvlEh/xZ+ij9BDVWJ0QL0SbZq6QaFxoLPcXPmBLveLCc4wXdDK6s+6/vwhCSniFLPXW0NJe5UB8zKCsviqpc7vGPVQFcyZbyPwGD+d5ZnxmNWlhG4xSBZZjivjIWHEQgoDkSMjMwTo54569JSE5IpA7EyJSMTyGTUAUFlO1ZKOtaHTMeL1PhYYFTcihmY2cQ5+ullj7EDkiVfVez2sCTz8yiv84djhg7IJVk81xFWJlPdfHBG0flkRC/zQFZ+DSllNtfDdUsOMCliyGX5uOzU3ZhIXFDof4m1gDuKbEx0t2YS25gVGpcMnr/I1kx3c6piB8P8ZoqEwfMX3ZyCXynJTmq/U7NUXqfUzCbWL1wqVKBQUeESzQYoUlW8TAcVL1RCxUu1G6BYXfFyfQ4VPbDI4T8d2WzgQ6sc/vmxnTsqfHCZQzUJxm1h5dxS5Tu6lQgTZ0ipqRVqSwzTbbLHMt+c19iO76tsx/cLZub+Ali+tYC93olEAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA5LTA5VDIwOjE4OjE3KzAyOjAwjKtfjgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wOS0wOVQyMDoxODoxNyswMjowMP325zIAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:85%}.iziToast>.iziToast-body .iziToast-message,.iziToast>.iziToast-body .iziToast-title{padding:0;font-size:14px;line-height:16px;text-align:left;float:left;white-space:normal}.iziToast>.iziToast-body .iziToast-title{color:#000;margin:0}.iziToast>.iziToast-body .iziToast-message{margin:0 0 10px;color:rgba(0,0,0,.6)}.iziToast.iziToast-animateInside .iziToast-buttons-child,.iziToast.iziToast-animateInside .iziToast-icon,.iziToast.iziToast-animateInside .iziToast-inputs-child,.iziToast.iziToast-animateInside .iziToast-message,.iziToast.iziToast-animateInside .iziToast-title{opacity:0}.iziToast-target{position:relative;width:100%;margin:0 auto}.iziToast-target .iziToast-capsule{overflow:hidden}.iziToast-target .iziToast-capsule:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.iziToast-target .iziToast-capsule .iziToast{width:100%;float:left}.iziToast-wrapper{z-index:99999;position:fixed;width:100%;pointer-events:none;display:flex;flex-direction:column}.iziToast-wrapper .iziToast.iziToast-balloon:before{border-right:0 solid transparent;border-left:15px solid transparent;border-top:10px solid #000;border-top-color:inherit;right:8px;left:auto}.iziToast-wrapper-bottomLeft{left:0;bottom:0;text-align:left}.iziToast-wrapper-bottomLeft .iziToast.iziToast-balloon:before,.iziToast-wrapper-topLeft .iziToast.iziToast-balloon:before{border-right:15px solid transparent;border-left:0 solid transparent;right:auto;left:8px}.iziToast-wrapper-bottomRight{right:0;bottom:0;text-align:right}.iziToast-wrapper-topLeft{left:0;top:0;text-align:left}.iziToast-wrapper-topRight{top:0;right:0;text-align:right}.iziToast-wrapper-topCenter{top:0;left:0;right:0;text-align:center}.iziToast-wrapper-bottomCenter,.iziToast-wrapper-center{bottom:0;left:0;right:0;text-align:center}.iziToast-wrapper-center{top:0;justify-content:center;flex-flow:column;align-items:center}.iziToast-rtl{direction:rtl;padding:8px 0 9px 45px;font-family:Tahoma,'Lato',Arial}.iziToast-rtl .iziToast-cover{left:auto;right:0}.iziToast-rtl .iziToast-close{right:auto;left:0}.iziToast-rtl .iziToast-body{padding:0 10px 0 0;margin:0 16px 0 0;text-align:right}.iziToast-rtl .iziToast-body .iziToast-buttons,.iziToast-rtl .iziToast-body .iziToast-inputs,.iziToast-rtl .iziToast-body .iziToast-message,.iziToast-rtl .iziToast-body .iziToast-texts,.iziToast-rtl .iziToast-body .iziToast-title{float:right;text-align:right}.iziToast-rtl .iziToast-body .iziToast-icon{left:auto;right:0}@media only screen and (min-width:568px){.iziToast-wrapper{padding:10px 15px}.iziToast{margin:5px 0;border-radius:3px;width:auto}.iziToast:after{content:'';z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;border-radius:3px;box-shadow:inset 0 -10px 20px -10px rgba(0,0,0,.2),inset 0 0 5px rgba(0,0,0,.1),0 8px 8px -5px rgba(0,0,0,.25)}.iziToast:not(.iziToast-rtl) .iziToast-cover{border-radius:3px 0 0 3px}.iziToast.iziToast-rtl .iziToast-cover{border-radius:0 3px 3px 0}.iziToast.iziToast-color-dark:after{box-shadow:inset 0 -10px 20px -10px rgba(255,255,255,.3),0 10px 10px -5px rgba(0,0,0,.25)}.iziToast.iziToast-balloon .iziToast-progressbar{background:0 0}.iziToast.iziToast-balloon:after{box-shadow:0 10px 10px -5px rgba(0,0,0,.25),inset 0 10px 20px -5px rgba(0,0,0,.25)}.iziToast-target .iziToast:after{box-shadow:inset 0 -10px 20px -10px rgba(0,0,0,.2),inset 0 0 5px rgba(0,0,0,.1)}}.iziToast.iziToast-theme-dark{background:#565c70;border-color:#565c70}.iziToast.iziToast-theme-dark .iziToast-title{color:#fff}.iziToast.iziToast-theme-dark .iziToast-message{color:rgba(255,255,255,.7);font-weight:300}.iziToast.iziToast-theme-dark .iziToast-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfgCR4OIQIPSao6AAAAwElEQVRIx72VUQ6EIAwFmz2XB+AConhjzqTJ7JeGKhLYlyx/BGdoBVpjIpMJNjgIZDKTkQHYmYfwmR2AfAqGFBcO2QjXZCd24bEggvd1KBx+xlwoDpYmvnBUUy68DYXD77ESr8WDtYqvxRex7a8oHP4Wo1Mkt5I68Mc+qYqv1h5OsZmZsQ3gj/02h6cO/KEYx29hu3R+VTTwz6D3TymIP1E8RvEiiVdZfEzicxYLiljSxKIqlnW5seitTW6uYnv/Aqh4whX3mEUrAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA5LTMwVDE0OjMzOjAyKzAyOjAwl6RMVgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wOS0zMFQxNDozMzowMiswMjowMOb59OoAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:8px}.iziToast.iziToast-theme-dark .iziToast-icon{color:#fff}.iziToast.iziToast-theme-dark .iziToast-icon.ico-info{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAflBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vroaSAAAAKXRSTlMA6PsIvDob+OapavVhWRYPrIry2MxGQ97czsOzpJaMcE0qJQOwVtKjfxCVFeIAAAI3SURBVFjDlJPZsoIwEETnCiGyb8q+qmjl/3/wFmGKwjBROS9QWbtnOqDDGPq4MdMkSc0m7gcDDhF4NRdv8NoL4EcMpzoJglPl/KTDz4WW3IdvXEvxkfIKn7BMZb1bFK4yZFqghZ03jk0nG8N5NBwzx9xU5cxAg8fXi20/hDdC316lcA8o7t16eRuQvW1XGd2d2P8QSHQDDbdIII/9CR3lUF+lbucfJy4WfMS64EJPORnrZxtfc2pjJdnbuags3l04TTtJMXrdTph4Pyg4XAjugAJqMDf5Rf+oXx2/qi4u6nipakIi7CsgiuMSEF9IGKg8heQJKkxIfFSUU/egWSwNrS1fPDtLfon8sZOcYUQml1Qv9a3kfwsEUyJEMgFBKzdV8o3Iw9yAjg1jdLQCV4qbd3no8yD2GugaC3oMbF0NYHCpJYSDhNI5N2DAWB4F4z9Aj/04Cna/x7eVAQ17vRjQZPh+G/kddYv0h49yY4NWNDWMMOMUIRYvlTECmrN8pUAjo5RCMn8KoPmbJ/+Appgnk//Sy90GYBCGgm7IAskQ7D9hFKW4ApB1ei3FSYD9PjGAKygAV+ARFYBH5BsVgG9kkBSAQWKUFYBRZpkUgGVinRWAdUZQDABBQdIcAElDVBUAUUXWHQBZx1gMAGMprM0AsLbVXHsA5trZe93/wp3svQ0YNb/jWV3AIOLsMtlznSNOH7JqjOpDVh7z8qCZR10ftvO4nxeOvPLkpSuvfXnxzKtvXr7j+v8C5ii0e71At7cAAAAASUVORK5CYII=) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-warning{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAllBMVEUAAAD////+//3+//3+//3///////z+//3+//3+//3////////////9//3////+//39//3///3////////////+//3+//39//3///z+//z+//7///3///3///3///3////////+//3+//3+//3+//z+//3+//7///3///z////////+//79//3///3///z///v+//3///+trXouAAAAMHRSTlMAB+j87RBf+PXiCwQClSPYhkAzJxnx05tSyadzcmxmHRbp5d7Gwrh4TDkvsYt/WkdQzCITAAAB1UlEQVRYw+3XaXKCQBCGYSIIighoxCVqNJrEPfly/8vFImKXduNsf/Mc4K1y7FnwlMLQc/bUbj85R6bA1LXRDICg6RjJcZa7NQYtnLUGTpERSiOXxrOPkv9s30iGKDmtbYir3H7OUHJa2ylAuvZzRvzUfs7Ii/2cgfTt54x82s8ZSM848gJmYtroQzA2jHwA+LkBIEuMGt+QIng1igzlyMrkuP2CyOi47axRaYTL5jhDJehoR+aovC29s3iIyly3Eb+hRCvZo2qsGTnhKr2cLDS+J73GsqBI9W80UCmWWpEuhIjh6ZRGjyNRarjzKGJ2Ou2himCvjHwqI+rTqQdlRH06TZQR9ek0hiqiPp06mV4ke7QPX6ERUZxO8Uo3sqrfhxvoRrCpvXwL/UjR9GRHMIvLgke4d5QbiwhM6JV2YKKF4vIl7XIBkwm4keryJVmvk/TfwcmPwQNkUQuyA2/sYGwnXL7GPu4bW1jYsmevrNj09/MGZMOEPXslQVqO8hqykD17JfPHP/bmo2yGGpdZiH3IZvzZa7B3+IdDjjpjesHJcvbs5dZ/e+cddVoDdvlq7x12Nac+iN7e4R8OXTjp0pw5CGnOLNDEzeBs5gVwFniAO+8f8wvfeXP2hyqnmwAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-error{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAeFBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////GqOSsAAAAJ3RSTlMA3BsB98QV8uSyWVUFz6RxYwzYvbupmYqAaU1FQTXKv7abj4d1azKNUit3AAACZElEQVRYw7WXaZOCMAyGw30UORRQBLxX/v8/3BkaWjrY2szO5otKfGrzJrEp6Kw6F8f8sI+i/SE/FucKSBaWiT8p5idlaEtnXTB9tKDLLHAvdSatOan3je93k9F2vRF36+mr1a6eH2NFNydoHq/ieU/UXcWjjk9XykdNWq2ywtp4tXL6Wb2T/MqtzzZutsrNyfvA51KoQROhVCjfrnASIRpSVUZiD5v4RbWExjRdJzSmOsZFvzYz59kRSr6V5zE+/QELHkNdb3VRx45HS1b1u+zfkkcbRAZ3qJ9l/A4qefHUDMShJe+6kZKJDD2pLQ9Q4lu+5Q7rz7Plperd7AtQEgIPI6o2dxr2D4GXvxqCiKcn8cD4gxIAEt7/GYkHL16KqeJd0NB4gJbXfgVnzCGJlzGcocCVSLzUvoAj9xJ4NF7/R8gxoVQexc/hgBpSebjPjgPs59cHmYfn7NkDb6wXmUf1I1ygIPPw4gtgCE8yDw8eAop4J/PQcBExjQmZx37MsZB2ZB4cLKQCG5vKYxMWSzMxIg8pNtOyUkvkocEmXGo69mh8FgnxS4yBwMvDrJSNHZB4uC3ayz/YkcIP4lflwVIT+OU07ZSjrbTkZQ6dTPkYubZ8GC/Cqxu6WvJZII93dcCw46GdNqdpTeF/tiMOuDGB9z/NI6NvyWetGPM0g+bVNeovBmamHXWj0nCbEaGeTMN2PWrqd6cM26ZxP2DeJvj+ph/30Zi/GmRbtlK5SptI+nwGGnvH6gUruT+L16MJHF+58rwNIifTV0vM8+hwMeOXAb6Yx0wXT+b999WXfvn+8/X/F7fWzjdTord5AAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:80%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-success{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMApAPhIFn82wgGv8mVtwAAAKVJREFUSMft0LEJAkEARNFFFEw1NFJb8CKjAy1AEOzAxNw+bEEEg6nyFjbY4LOzcBwX7S/gwUxoTdIn+Jbv4Lv8bx446+kB6VsBtK0B+wbMCKxrwL33wOrVeeChX28n7KTOTjgoEu6DRSYAgAAAAkAmAIAAAAIACQIkMkACAAgAIACAyECBKAOJuCagTJwSUCaUAEMAABEBRwAAEQFLbCJgO4bW+AZKGnktR+jAFAAAAABJRU5ErkJggg==) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-icon.ico-question{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfhCQkUEg18vki+AAAETUlEQVRo3s1ZTWhbRxD+VlIuxsLFCYVIIQYVopBDoK5bKDWUBupDMNbJ5FBKg/FBziUQdE9yaC+FHBrwsdCfQ9RTGoLxwWl+DqHEojUFFydxnB9bInZDqOsErBrr6yGvs/ueX97bldTKo4Pe7puZb3Z33s7srIIjMY1jyCEjP6ImvyX8pF64arSHznKC06wzijY5xSKz7YbuYokV2lODsyyxqz3gSY6z6gCuqcpxJluFH+Z8U+D/0jyHoxFUBHgfvsGHIS9WMIUlVFFDFTUAGWSRQRY5HMeBEP6b+Ew9dh/7INd2jGeO59kfKdXP85zbIbfGQVf4sYC3N1hm3lo6zzIbPvk6x+zBk7wQGMEMB5xncIAzAS0XrFySSV72iS1yyBVcdA1x0afrsoUJgdFfY2+z8ADAXl7zz0KcwJiPfZKpVuABgClO+nRG+QIHDdfb4qlWwUXvKW4Z7vi6L4J9vg+vbfCeCeZH2RfOdMOc/HbCA4BvIW6EMQz7XK/ltd+hP+VzR9mgva2YSfyGI17fA7ynnocqeQNFfIJ0oHsdv6CC2+rXGBN6cQdveY3fcVRtmy/HDete+93zy8jA8zV7YkwYMrjHzRddRsCdiVCwwmh6wg9iTNC7Y9XIF1iS7kbUpsvvGEdPuTfSgAEjRpR096x0liPFD/Eqt2NMuBQzB2XhrACAApjFsuQFh9XdGAX70B3oSuNdnMVBaX+sopYxjwVpHFBVACyKTXNoktjD+6Ll8xhenS9MAAkAI/Lux2YNUOs4I413Ypg1SgEAu7kpFvWjaeJe0fJHDGe/cNaZBkekudw8PMA+0fMwlndZeAsJ5KR/qhUDUJCnSiyvRsolkJHGUgvjH8QXDgZopEzKMKDqCKrwEQ4C6MH7GEXC665buLJG8hlQc4LP4paxfJrOqYVYYY2UARfEIazTbgDg2dB98GebzJd54b8L/iWNdLyooeR6CHyZ+6xk0yKxkYg6nEVSUG4VJ9QJ9cxRCxO+9WiOyvgUeexXP1hLGH5nGuBWVtiSp4vqe3VP0UFWI9Wan4Er3v8q7jjPWVtm4FtcQQMrOKO2nOQCM5AyDMi56FDrKHA/1nyppS1ppBpYaE8wciEjGI2AaeM41kI4doDX4XiT3Qm1gevyruCgZg9P8xIv8m1nCzTKq6oiJ9xTMiZ505P5m8cdZ0CnZMVXHVljM7WMBzxpyDxygtdxoCEFTaMIWbZU85UvBjgUMYy0fBaAF8V1Lj9qWQ1aMZ5f4k9r+AGMSkMP1vZoZih6k6sicc5h/OFHM9vDqU/VIU7zJZdYYsKGH4g4nAJMGiXZRds1pVMoZ69RM5vfkbh0qkBhsnS2RLMLilQdL9MBHS9UAh0v1e6CYnXHy/WeeCcvLDwl/9OVze69tPKM+M+v7eJN6OzFpWdEF0ucDbhVNFXadnVrmJFlkVNGTS2M6pzmhMvltfPhnN2B63sVuL7fcNP3D1TSk2ihosPrAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA5LTA5VDIwOjE4OjEzKzAyOjAweOR7nQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wOS0wOVQyMDoxODoxMyswMjowMAm5wyEAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) no-repeat 50% 50%;background-size:85%}.iziToast.iziToast-theme-dark .iziToast-buttons>a,.iziToast.iziToast-theme-dark .iziToast-buttons>button,.iziToast.iziToast-theme-dark .iziToast-buttons>input{color:#fff;background:rgba(255,255,255,.1)}.iziToast.iziToast-theme-dark .iziToast-buttons>a:hover,.iziToast.iziToast-theme-dark .iziToast-buttons>button:hover,.iziToast.iziToast-theme-dark .iziToast-buttons>input:hover{background:rgba(255,255,255,.2)}.iziToast.iziToast-theme-dark .iziToast-buttons>a:focus,.iziToast.iziToast-theme-dark .iziToast-buttons>button:focus,.iziToast.iziToast-theme-dark .iziToast-buttons>input:focus{box-shadow:0 0 0 1px rgba(255,255,255,.6)}.iziToast.iziToast-color-red{background:rgba(255,175,180,.9);border-color:rgba(255,175,180,.9)}.iziToast.iziToast-color-orange{background:rgba(255,207,165,.9);border-color:rgba(255,207,165,.9)}.iziToast.iziToast-color-yellow{background:rgba(255,249,178,.9);border-color:rgba(255,249,178,.9)}.iziToast.iziToast-color-blue{background:rgba(157,222,255,.9);border-color:rgba(157,222,255,.9)}.iziToast.iziToast-color-green{background:rgba(166,239,184,.9);border-color:rgba(166,239,184,.9)}.iziToast.iziToast-layout2 .iziToast-body .iziToast-message,.iziToast.iziToast-layout2 .iziToast-body .iziToast-texts{width:100%}.iziToast.iziToast-layout3{border-radius:2px}.iziToast.iziToast-layout3::after{display:none}.iziToast .revealIn,.iziToast.revealIn{-webkit-animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both;-moz-animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both;animation:iziT-revealIn 1s cubic-bezier(.25,1.6,.25,1) both}.iziToast .slideIn,.iziToast.slideIn{-webkit-animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziT-slideIn 1s cubic-bezier(.16,.81,.32,1) both}.iziToast.bounceInLeft{-webkit-animation:iziT-bounceInLeft .7s ease-in-out both;animation:iziT-bounceInLeft .7s ease-in-out both}.iziToast.bounceInRight{-webkit-animation:iziT-bounceInRight .85s ease-in-out both;animation:iziT-bounceInRight .85s ease-in-out both}.iziToast.bounceInDown{-webkit-animation:iziT-bounceInDown .7s ease-in-out both;animation:iziT-bounceInDown .7s ease-in-out both}.iziToast.bounceInUp{-webkit-animation:iziT-bounceInUp .7s ease-in-out both;animation:iziT-bounceInUp .7s ease-in-out both}.iziToast .fadeIn,.iziToast.fadeIn{-webkit-animation:iziT-fadeIn .5s ease both;animation:iziT-fadeIn .5s ease both}.iziToast.fadeInUp{-webkit-animation:iziT-fadeInUp .7s ease both;animation:iziT-fadeInUp .7s ease both}.iziToast.fadeInDown{-webkit-animation:iziT-fadeInDown .7s ease both;animation:iziT-fadeInDown .7s ease both}.iziToast.fadeInLeft{-webkit-animation:iziT-fadeInLeft .85s cubic-bezier(.25,.8,.25,1) both;animation:iziT-fadeInLeft .85s cubic-bezier(.25,.8,.25,1) both}.iziToast.fadeInRight{-webkit-animation:iziT-fadeInRight .85s cubic-bezier(.25,.8,.25,1) both;animation:iziT-fadeInRight .85s cubic-bezier(.25,.8,.25,1) both}.iziToast.flipInX{-webkit-animation:iziT-flipInX .85s cubic-bezier(.35,0,.25,1) both;animation:iziT-flipInX .85s cubic-bezier(.35,0,.25,1) both}.iziToast.fadeOut{-webkit-animation:iziT-fadeOut .7s ease both;animation:iziT-fadeOut .7s ease both}.iziToast.fadeOutDown{-webkit-animation:iziT-fadeOutDown .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-fadeOutDown .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast.fadeOutUp{-webkit-animation:iziT-fadeOutUp .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-fadeOutUp .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast.fadeOutLeft{-webkit-animation:iziT-fadeOutLeft .5s ease both;animation:iziT-fadeOutLeft .5s ease both}.iziToast.fadeOutRight{-webkit-animation:iziT-fadeOutRight .5s ease both;animation:iziT-fadeOutRight .5s ease both}.iziToast.flipOutX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation:iziT-flipOutX .7s cubic-bezier(.4,.45,.15,.91) both;animation:iziT-flipOutX .7s cubic-bezier(.4,.45,.15,.91) both}.iziToast-overlay.fadeIn{-webkit-animation:iziT-fadeIn .5s ease both;animation:iziT-fadeIn .5s ease both}.iziToast-overlay.fadeOut{-webkit-animation:iziT-fadeOut .7s ease both;animation:iziT-fadeOut .7s ease both}@-webkit-keyframes iziT-revealIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,1)}to{opacity:1}}@-moz-keyframes iziT-revealIn{0%{opacity:0;-moz-transform:scale3d(.3,.3,1)}to{opacity:1}}@-webkit-keyframes iziT-slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}to{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes iziT-slideIn{0%{opacity:0;-moz-transform:translateX(50px)}to{opacity:1;-moz-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInLeft{0%{opacity:0;-webkit-transform:translateX(280px)}50%{opacity:1;-webkit-transform:translateX(-20px)}70%{-webkit-transform:translateX(10px)}to{-webkit-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInRight{0%{opacity:0;-webkit-transform:translateX(-280px)}50%{opacity:1;-webkit-transform:translateX(20px)}70%{-webkit-transform:translateX(-10px)}to{-webkit-transform:translateX(0)}}@-webkit-keyframes iziT-bounceInDown{0%{opacity:0;-webkit-transform:translateY(-200px)}50%{opacity:1;-webkit-transform:translateY(10px)}70%{-webkit-transform:translateY(-5px)}to{-webkit-transform:translateY(0)}}@-webkit-keyframes iziT-bounceInUp{0%{opacity:0;-webkit-transform:translateY(200px)}50%{opacity:1;-webkit-transform:translateY(-10px)}70%{-webkit-transform:translateY(5px)}to{-webkit-transform:translateY(0)}}@-webkit-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-webkit-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-webkit-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-moz-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-webkit-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-o-keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@keyframes iziT-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}to{opacity:1}}@-moz-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-webkit-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-o-keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@keyframes iziT-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-moz-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-webkit-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-o-keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@keyframes iziT-bounceInLeft{0%{opacity:0;transform:translateX(280px)}50%{opacity:1;transform:translateX(-20px)}70%{transform:translateX(10px)}to{transform:translateX(0)}}@-moz-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-webkit-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-o-keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@keyframes iziT-bounceInRight{0%{opacity:0;transform:translateX(-280px)}50%{opacity:1;transform:translateX(20px)}70%{transform:translateX(-10px)}to{transform:translateX(0)}}@-moz-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-webkit-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-o-keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@keyframes iziT-bounceInDown{0%{opacity:0;transform:translateY(-200px)}50%{opacity:1;transform:translateY(10px)}70%{transform:translateY(-5px)}to{transform:translateY(0)}}@-moz-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-webkit-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-o-keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@keyframes iziT-bounceInUp{0%{opacity:0;transform:translateY(200px)}50%{opacity:1;transform:translateY(-10px)}70%{transform:translateY(5px)}to{transform:translateY(0)}}@-moz-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-o-keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes iziT-fadeIn{0%{opacity:0}to{opacity:1}}@-moz-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(300px,0,0);transform:translate3d(300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-o-keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziT-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(-300px,0,0);transform:translate3d(-300px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-moz-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-webkit-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-o-keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes iziT-flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg)}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@-moz-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-o-keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@keyframes iziT-fadeOut{0%{opacity:1}to{opacity:0}}@-moz-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-o-keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes iziT-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-moz-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-webkit-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-o-keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes iziT-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@-moz-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-o-keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@keyframes iziT-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-moz-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-o-keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@keyframes iziT-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-moz-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-webkit-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@-o-keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes iziT-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}} diff --git a/conreq/core/base/static/js/libraries/izi_toast_1.4.0.min.js b/conreq/_core/home/static/conreq/izi_toast_1.4.0.min.js similarity index 99% rename from conreq/core/base/static/js/libraries/izi_toast_1.4.0.min.js rename to conreq/_core/home/static/conreq/izi_toast_1.4.0.min.js index 2d788dcd..d63d6eeb 100644 --- a/conreq/core/base/static/js/libraries/izi_toast_1.4.0.min.js +++ b/conreq/_core/home/static/conreq/izi_toast_1.4.0.min.js @@ -3,4 +3,4 @@ * http://izitoast.marcelodolce.com * by Marcelo Dolce. */ -!function(t,e){"function"==typeof define&&define.amd?define([],e(t)):"object"==typeof exports?module.exports=e(t):t.iziToast=e(t)}("undefined"!=typeof global?global:window||this.window||this.global,function(t){"use strict";var e={},n="iziToast",o=(document.querySelector("body"),!!/Mobi/.test(navigator.userAgent)),i=/Chrome/.test(navigator.userAgent)&&/Google Inc/.test(navigator.vendor),s="undefined"!=typeof InstallTrigger,a="ontouchstart"in document.documentElement,r=["bottomRight","bottomLeft","bottomCenter","topRight","topLeft","topCenter","center"],l={info:{color:"blue",icon:"ico-info"},success:{color:"green",icon:"ico-success"},warning:{color:"orange",icon:"ico-warning"},error:{color:"red",icon:"ico-error"},question:{color:"yellow",icon:"ico-question"}},d=568,c={};e.children={};var u={id:null,"class":"",title:"",titleColor:"",titleSize:"",titleLineHeight:"",message:"",messageColor:"",messageSize:"",messageLineHeight:"",backgroundColor:"",theme:"light",color:"",icon:"",iconText:"",iconColor:"",iconUrl:null,image:"",imageWidth:50,maxWidth:null,zindex:null,layout:1,balloon:!1,close:!0,closeOnEscape:!1,closeOnClick:!1,displayMode:0,position:"bottomRight",target:"",targetFirst:!0,timeout:5e3,rtl:!1,animateInside:!0,drag:!0,pauseOnHover:!0,resetOnHover:!1,progressBar:!0,progressBarColor:"",progressBarEasing:"linear",overlay:!1,overlayClose:!1,overlayColor:"rgba(0, 0, 0, 0.6)",transitionIn:"fadeInUp",transitionOut:"fadeOut",transitionInMobile:"fadeInUp",transitionOutMobile:"fadeOutDown",buttons:{},inputs:{},onOpening:function(){},onOpened:function(){},onClosing:function(){},onClosed:function(){}};if("remove"in Element.prototype||(Element.prototype.remove=function(){this.parentNode&&this.parentNode.removeChild(this)}),"function"!=typeof window.CustomEvent){var p=function(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n};p.prototype=window.Event.prototype,window.CustomEvent=p}var m=function(t,e,n){if("[object Object]"===Object.prototype.toString.call(t))for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.call(n,t[o],o,t);else if(t)for(var i=0,s=t.length;s>i;i++)e.call(n,t[i],i,t)},g=function(t,e){var n={};return m(t,function(e,o){n[o]=t[o]}),m(e,function(t,o){n[o]=e[o]}),n},f=function(t){var e=document.createDocumentFragment(),n=document.createElement("div");for(n.innerHTML=t;n.firstChild;)e.appendChild(n.firstChild);return e},v=function(t){var e=btoa(encodeURIComponent(t));return e.replace(/=/g,"")},y=function(t){return"#"==t.substring(0,1)||"rgb"==t.substring(0,3)||"hsl"==t.substring(0,3)},h=function(t){try{return btoa(atob(t))==t}catch(e){return!1}},b=function(){return{move:function(t,e,o,a){var r,l=.3,d=180;0!==a&&(t.classList.add(n+"-dragged"),t.style.transform="translateX("+a+"px)",a>0?(r=(d-a)/d,l>r&&e.hide(g(o,{transitionOut:"fadeOutRight",transitionOutMobile:"fadeOutRight"}),t,"drag")):(r=(d+a)/d,l>r&&e.hide(g(o,{transitionOut:"fadeOutLeft",transitionOutMobile:"fadeOutLeft"}),t,"drag")),t.style.opacity=r,l>r&&((i||s)&&(t.style.left=a+"px"),t.parentNode.style.opacity=l,this.stopMoving(t,null)))},startMoving:function(t,e,n,o){o=o||window.event;var i=a?o.touches[0].clientX:o.clientX,s=t.style.transform.replace("px)","");s=s.replace("translateX(","");var r=i-s;n.transitionIn&&t.classList.remove(n.transitionIn),n.transitionInMobile&&t.classList.remove(n.transitionInMobile),t.style.transition="",a?document.ontouchmove=function(o){o.preventDefault(),o=o||window.event;var i=o.touches[0].clientX,s=i-r;b.move(t,e,n,s)}:document.onmousemove=function(o){o.preventDefault(),o=o||window.event;var i=o.clientX,s=i-r;b.move(t,e,n,s)}},stopMoving:function(t,e){a?document.ontouchmove=function(){}:document.onmousemove=function(){},t.style.opacity="",t.style.transform="",t.classList.contains(n+"-dragged")&&(t.classList.remove(n+"-dragged"),t.style.transition="transform 0.4s ease, opacity 0.4s ease",setTimeout(function(){t.style.transition=""},400))}}}();return e.setSetting=function(t,n,o){e.children[t][n]=o},e.getSetting=function(t,n){return e.children[t][n]},e.destroy=function(){m(document.querySelectorAll("."+n+"-overlay"),function(t,e){t.remove()}),m(document.querySelectorAll("."+n+"-wrapper"),function(t,e){t.remove()}),m(document.querySelectorAll("."+n),function(t,e){t.remove()}),this.children={},document.removeEventListener(n+"-opened",{},!1),document.removeEventListener(n+"-opening",{},!1),document.removeEventListener(n+"-closing",{},!1),document.removeEventListener(n+"-closed",{},!1),document.removeEventListener("keyup",{},!1),c={}},e.settings=function(t){e.destroy(),c=t,u=g(u,t||{})},m(l,function(t,n){e[n]=function(e){var n=g(c,e||{});n=g(t,n||{}),this.show(n)}}),e.progress=function(t,e,o){var i=this,s=e.getAttribute("data-iziToast-ref"),a=g(this.children[s],t||{}),r=e.querySelector("."+n+"-progressbar div");return{start:function(){"undefined"==typeof a.time.REMAINING&&(e.classList.remove(n+"-reseted"),null!==r&&(r.style.transition="width "+a.timeout+"ms "+a.progressBarEasing,r.style.width="0%"),a.time.START=(new Date).getTime(),a.time.END=a.time.START+a.timeout,a.time.TIMER=setTimeout(function(){clearTimeout(a.time.TIMER),e.classList.contains(n+"-closing")||(i.hide(a,e,"timeout"),"function"==typeof o&&o.apply(i))},a.timeout),i.setSetting(s,"time",a.time))},pause:function(){if("undefined"!=typeof a.time.START&&!e.classList.contains(n+"-paused")&&!e.classList.contains(n+"-reseted")){if(e.classList.add(n+"-paused"),a.time.REMAINING=a.time.END-(new Date).getTime(),clearTimeout(a.time.TIMER),i.setSetting(s,"time",a.time),null!==r){var t=window.getComputedStyle(r),l=t.getPropertyValue("width");r.style.transition="none",r.style.width=l}"function"==typeof o&&setTimeout(function(){o.apply(i)},10)}},resume:function(){"undefined"!=typeof a.time.REMAINING?(e.classList.remove(n+"-paused"),null!==r&&(r.style.transition="width "+a.time.REMAINING+"ms "+a.progressBarEasing,r.style.width="0%"),a.time.END=(new Date).getTime()+a.time.REMAINING,a.time.TIMER=setTimeout(function(){clearTimeout(a.time.TIMER),e.classList.contains(n+"-closing")||(i.hide(a,e,"timeout"),"function"==typeof o&&o.apply(i))},a.time.REMAINING),i.setSetting(s,"time",a.time)):this.start()},reset:function(){clearTimeout(a.time.TIMER),delete a.time.REMAINING,i.setSetting(s,"time",a.time),e.classList.add(n+"-reseted"),e.classList.remove(n+"-paused"),null!==r&&(r.style.transition="none",r.style.width="100%"),"function"==typeof o&&setTimeout(function(){o.apply(i)},10)}}},e.hide=function(t,e,i){"object"!=typeof e&&(e=document.querySelector(e));var s=this,a=g(this.children[e.getAttribute("data-iziToast-ref")],t||{});a.closedBy=i||null,delete a.time.REMAINING,e.classList.add(n+"-closing"),function(){var t=document.querySelector("."+n+"-overlay");if(null!==t){var e=t.getAttribute("data-iziToast-ref");e=e.split(",");var o=e.indexOf(String(a.ref));-1!==o&&e.splice(o,1),t.setAttribute("data-iziToast-ref",e.join()),0===e.length&&(t.classList.remove("fadeIn"),t.classList.add("fadeOut"),setTimeout(function(){t.remove()},700))}}(),a.transitionIn&&e.classList.remove(a.transitionIn),a.transitionInMobile&&e.classList.remove(a.transitionInMobile),o||window.innerWidth<=d?a.transitionOutMobile&&e.classList.add(a.transitionOutMobile):a.transitionOut&&e.classList.add(a.transitionOut);var r=e.parentNode.offsetHeight;e.parentNode.style.height=r+"px",e.style.pointerEvents="none",(!o||window.innerWidth>d)&&(e.parentNode.style.transitionDelay="0.2s");try{var l=new CustomEvent(n+"-closing",{detail:a,bubbles:!0,cancelable:!0});document.dispatchEvent(l)}catch(c){console.warn(c)}setTimeout(function(){e.parentNode.style.height="0px",e.parentNode.style.overflow="",setTimeout(function(){delete s.children[a.ref],e.parentNode.remove();try{var t=new CustomEvent(n+"-closed",{detail:a,bubbles:!0,cancelable:!0});document.dispatchEvent(t)}catch(o){console.warn(o)}"undefined"!=typeof a.onClosed&&a.onClosed.apply(null,[a,e,i])},1e3)},200),"undefined"!=typeof a.onClosing&&a.onClosing.apply(null,[a,e,i])},e.show=function(t){var i=this,s=g(c,t||{});if(s=g(u,s),s.time={},null===s.id&&(s.id=v(s.title+s.message+s.color)),1===s.displayMode||"once"==s.displayMode)try{if(document.querySelectorAll("."+n+"#"+s.id).length>0)return!1}catch(l){console.warn("["+n+"] Could not find an element with this selector: #"+s.id+". Try to set an valid id.")}if(2===s.displayMode||"replace"==s.displayMode)try{m(document.querySelectorAll("."+n+"#"+s.id),function(t,e){i.hide(s,t,"replaced")})}catch(l){console.warn("["+n+"] Could not find an element with this selector: #"+s.id+". Try to set an valid id.")}s.ref=(new Date).getTime()+Math.floor(1e7*Math.random()+1),e.children[s.ref]=s;var p={body:document.querySelector("body"),overlay:document.createElement("div"),toast:document.createElement("div"),toastBody:document.createElement("div"),toastTexts:document.createElement("div"),toastCapsule:document.createElement("div"),cover:document.createElement("div"),buttons:document.createElement("div"),inputs:document.createElement("div"),icon:s.iconUrl?document.createElement("img"):document.createElement("i"),wrapper:null};p.toast.setAttribute("data-iziToast-ref",s.ref),p.toast.appendChild(p.toastBody),p.toastCapsule.appendChild(p.toast),function(){if(p.toast.classList.add(n),p.toast.classList.add(n+"-opening"),p.toastCapsule.classList.add(n+"-capsule"),p.toastBody.classList.add(n+"-body"),p.toastTexts.classList.add(n+"-texts"),o||window.innerWidth<=d?s.transitionInMobile&&p.toast.classList.add(s.transitionInMobile):s.transitionIn&&p.toast.classList.add(s.transitionIn),s["class"]){var t=s["class"].split(" ");m(t,function(t,e){p.toast.classList.add(t)})}s.id&&(p.toast.id=s.id),s.rtl&&(p.toast.classList.add(n+"-rtl"),p.toast.setAttribute("dir","rtl")),s.layout>1&&p.toast.classList.add(n+"-layout"+s.layout),s.balloon&&p.toast.classList.add(n+"-balloon"),s.maxWidth&&(isNaN(s.maxWidth)?p.toast.style.maxWidth=s.maxWidth:p.toast.style.maxWidth=s.maxWidth+"px"),""===s.theme&&"light"===s.theme||p.toast.classList.add(n+"-theme-"+s.theme),s.color&&(y(s.color)?p.toast.style.background=s.color:p.toast.classList.add(n+"-color-"+s.color)),s.backgroundColor&&(p.toast.style.background=s.backgroundColor,s.balloon&&(p.toast.style.borderColor=s.backgroundColor))}(),function(){s.image&&(p.cover.classList.add(n+"-cover"),p.cover.style.width=s.imageWidth+"px",h(s.image.replace(/ /g,""))?p.cover.style.backgroundImage="url(data:image/png;base64,"+s.image.replace(/ /g,"")+")":p.cover.style.backgroundImage="url("+s.image+")",s.rtl?p.toastBody.style.marginRight=s.imageWidth+10+"px":p.toastBody.style.marginLeft=s.imageWidth+10+"px",p.toast.appendChild(p.cover))}(),function(){s.close?(p.buttonClose=document.createElement("button"),p.buttonClose.type="button",p.buttonClose.classList.add(n+"-close"),p.buttonClose.addEventListener("click",function(t){t.target;i.hide(s,p.toast,"button")}),p.toast.appendChild(p.buttonClose)):s.rtl?p.toast.style.paddingLeft="18px":p.toast.style.paddingRight="18px"}(),function(){s.progressBar&&(p.progressBar=document.createElement("div"),p.progressBarDiv=document.createElement("div"),p.progressBar.classList.add(n+"-progressbar"),p.progressBarDiv.style.background=s.progressBarColor,p.progressBar.appendChild(p.progressBarDiv),p.toast.appendChild(p.progressBar)),s.timeout&&(s.pauseOnHover&&!s.resetOnHover&&(p.toast.addEventListener("mouseenter",function(t){i.progress(s,p.toast).pause()}),p.toast.addEventListener("mouseleave",function(t){i.progress(s,p.toast).resume()})),s.resetOnHover&&(p.toast.addEventListener("mouseenter",function(t){i.progress(s,p.toast).reset()}),p.toast.addEventListener("mouseleave",function(t){i.progress(s,p.toast).start()})))}(),function(){s.iconUrl?(p.icon.setAttribute("class",n+"-icon"),p.icon.setAttribute("src",s.iconUrl)):s.icon&&(p.icon.setAttribute("class",n+"-icon "+s.icon),s.iconText&&p.icon.appendChild(document.createTextNode(s.iconText)),s.iconColor&&(p.icon.style.color=s.iconColor)),(s.icon||s.iconUrl)&&(s.rtl?p.toastBody.style.paddingRight="33px":p.toastBody.style.paddingLeft="33px",p.toastBody.appendChild(p.icon))}(),function(){s.title.length>0&&(p.strong=document.createElement("strong"),p.strong.classList.add(n+"-title"),p.strong.appendChild(f(s.title)),p.toastTexts.appendChild(p.strong),s.titleColor&&(p.strong.style.color=s.titleColor),s.titleSize&&(isNaN(s.titleSize)?p.strong.style.fontSize=s.titleSize:p.strong.style.fontSize=s.titleSize+"px"),s.titleLineHeight&&(isNaN(s.titleSize)?p.strong.style.lineHeight=s.titleLineHeight:p.strong.style.lineHeight=s.titleLineHeight+"px")),s.message.length>0&&(p.p=document.createElement("p"),p.p.classList.add(n+"-message"),p.p.appendChild(f(s.message)),p.toastTexts.appendChild(p.p),s.messageColor&&(p.p.style.color=s.messageColor),s.messageSize&&(isNaN(s.titleSize)?p.p.style.fontSize=s.messageSize:p.p.style.fontSize=s.messageSize+"px"),s.messageLineHeight&&(isNaN(s.titleSize)?p.p.style.lineHeight=s.messageLineHeight:p.p.style.lineHeight=s.messageLineHeight+"px")),s.title.length>0&&s.message.length>0&&(s.rtl?p.strong.style.marginLeft="10px":2===s.layout||s.rtl||(p.strong.style.marginRight="10px"))}(),p.toastBody.appendChild(p.toastTexts);var L;!function(){s.inputs.length>0&&(p.inputs.classList.add(n+"-inputs"),m(s.inputs,function(t,e){p.inputs.appendChild(f(t[0])),L=p.inputs.childNodes,L[e].classList.add(n+"-inputs-child"),t[3]&&setTimeout(function(){L[e].focus()},300),L[e].addEventListener(t[1],function(e){var n=t[2];return n(i,p.toast,this,e)})}),p.toastBody.appendChild(p.inputs))}(),function(){s.buttons.length>0&&(p.buttons.classList.add(n+"-buttons"),m(s.buttons,function(t,e){p.buttons.appendChild(f(t[0]));var o=p.buttons.childNodes;o[e].classList.add(n+"-buttons-child"),t[2]&&setTimeout(function(){o[e].focus()},300),o[e].addEventListener("click",function(e){e.preventDefault();var n=t[1];return n(i,p.toast,this,e,L)})})),p.toastBody.appendChild(p.buttons)}(),s.message.length>0&&(s.inputs.length>0||s.buttons.length>0)&&(p.p.style.marginBottom="0"),(s.inputs.length>0||s.buttons.length>0)&&(s.rtl?p.toastTexts.style.marginLeft="10px":p.toastTexts.style.marginRight="10px",s.inputs.length>0&&s.buttons.length>0&&(s.rtl?p.inputs.style.marginLeft="8px":p.inputs.style.marginRight="8px")),function(){p.toastCapsule.style.visibility="hidden",setTimeout(function(){var t=p.toast.offsetHeight,e=p.toast.currentStyle||window.getComputedStyle(p.toast),n=e.marginTop;n=n.split("px"),n=parseInt(n[0]);var o=e.marginBottom;o=o.split("px"),o=parseInt(o[0]),p.toastCapsule.style.visibility="",p.toastCapsule.style.height=t+o+n+"px",setTimeout(function(){p.toastCapsule.style.height="auto",s.target&&(p.toastCapsule.style.overflow="visible")},500),s.timeout&&i.progress(s,p.toast).start()},100)}(),function(){var t=s.position;if(s.target)p.wrapper=document.querySelector(s.target),p.wrapper.classList.add(n+"-target"),s.targetFirst?p.wrapper.insertBefore(p.toastCapsule,p.wrapper.firstChild):p.wrapper.appendChild(p.toastCapsule);else{if(-1==r.indexOf(s.position))return void console.warn("["+n+"] Incorrect position.\nIt can be › "+r);t=o||window.innerWidth<=d?"bottomLeft"==s.position||"bottomRight"==s.position||"bottomCenter"==s.position?n+"-wrapper-bottomCenter":"topLeft"==s.position||"topRight"==s.position||"topCenter"==s.position?n+"-wrapper-topCenter":n+"-wrapper-center":n+"-wrapper-"+t,p.wrapper=document.querySelector("."+n+"-wrapper."+t),p.wrapper||(p.wrapper=document.createElement("div"),p.wrapper.classList.add(n+"-wrapper"),p.wrapper.classList.add(t),document.body.appendChild(p.wrapper)),"topLeft"==s.position||"topCenter"==s.position||"topRight"==s.position?p.wrapper.insertBefore(p.toastCapsule,p.wrapper.firstChild):p.wrapper.appendChild(p.toastCapsule)}isNaN(s.zindex)?console.warn("["+n+"] Invalid zIndex."):p.wrapper.style.zIndex=s.zindex}(),function(){s.overlay&&(null!==document.querySelector("."+n+"-overlay.fadeIn")?(p.overlay=document.querySelector("."+n+"-overlay"),p.overlay.setAttribute("data-iziToast-ref",p.overlay.getAttribute("data-iziToast-ref")+","+s.ref),isNaN(s.zindex)||null===s.zindex||(p.overlay.style.zIndex=s.zindex-1)):(p.overlay.classList.add(n+"-overlay"),p.overlay.classList.add("fadeIn"),p.overlay.style.background=s.overlayColor,p.overlay.setAttribute("data-iziToast-ref",s.ref),isNaN(s.zindex)||null===s.zindex||(p.overlay.style.zIndex=s.zindex-1),document.querySelector("body").appendChild(p.overlay)),s.overlayClose?(p.overlay.removeEventListener("click",{}),p.overlay.addEventListener("click",function(t){i.hide(s,p.toast,"overlay")})):p.overlay.removeEventListener("click",{}))}(),function(){if(s.animateInside){p.toast.classList.add(n+"-animateInside");var t=[200,100,300];"bounceInLeft"!=s.transitionIn&&"bounceInRight"!=s.transitionIn||(t=[400,200,400]),s.title.length>0&&setTimeout(function(){p.strong.classList.add("slideIn")},t[0]),s.message.length>0&&setTimeout(function(){p.p.classList.add("slideIn")},t[1]),(s.icon||s.iconUrl)&&setTimeout(function(){p.icon.classList.add("revealIn")},t[2]);var e=150;s.buttons.length>0&&p.buttons&&setTimeout(function(){m(p.buttons.childNodes,function(t,n){setTimeout(function(){t.classList.add("revealIn")},e),e+=150})},s.inputs.length>0?150:0),s.inputs.length>0&&p.inputs&&(e=150,m(p.inputs.childNodes,function(t,n){setTimeout(function(){t.classList.add("revealIn")},e),e+=150}))}}(),s.onOpening.apply(null,[s,p.toast]);try{var C=new CustomEvent(n+"-opening",{detail:s,bubbles:!0,cancelable:!0});document.dispatchEvent(C)}catch(w){console.warn(w)}setTimeout(function(){p.toast.classList.remove(n+"-opening"),p.toast.classList.add(n+"-opened");try{var t=new CustomEvent(n+"-opened",{detail:s,bubbles:!0,cancelable:!0});document.dispatchEvent(t)}catch(e){console.warn(e)}s.onOpened.apply(null,[s,p.toast])},1e3),s.drag&&(a?(p.toast.addEventListener("touchstart",function(t){b.startMoving(this,i,s,t)},!1),p.toast.addEventListener("touchend",function(t){b.stopMoving(this,t)},!1)):(p.toast.addEventListener("mousedown",function(t){t.preventDefault(),b.startMoving(this,i,s,t)},!1),p.toast.addEventListener("mouseup",function(t){t.preventDefault(),b.stopMoving(this,t)},!1))),s.closeOnEscape&&document.addEventListener("keyup",function(t){t=t||window.event,27==t.keyCode&&i.hide(s,p.toast,"esc")}),s.closeOnClick&&p.toast.addEventListener("click",function(t){i.hide(s,p.toast,"toast")}),i.toast=p.toast},e}); \ No newline at end of file +!function(t,e){"function"==typeof define&&define.amd?define([],e(t)):"object"==typeof exports?module.exports=e(t):t.iziToast=e(t)}("undefined"!=typeof global?global:window||this.window||this.global,function(t){"use strict";var e={},n="iziToast",o=(document.querySelector("body"),!!/Mobi/.test(navigator.userAgent)),i=/Chrome/.test(navigator.userAgent)&&/Google Inc/.test(navigator.vendor),s="undefined"!=typeof InstallTrigger,a="ontouchstart"in document.documentElement,r=["bottomRight","bottomLeft","bottomCenter","topRight","topLeft","topCenter","center"],l={info:{color:"blue",icon:"ico-info"},success:{color:"green",icon:"ico-success"},warning:{color:"orange",icon:"ico-warning"},error:{color:"red",icon:"ico-error"},question:{color:"yellow",icon:"ico-question"}},d=568,c={};e.children={};var u={id:null,"class":"",title:"",titleColor:"",titleSize:"",titleLineHeight:"",message:"",messageColor:"",messageSize:"",messageLineHeight:"",backgroundColor:"",theme:"light",color:"",icon:"",iconText:"",iconColor:"",iconUrl:null,image:"",imageWidth:50,maxWidth:null,zindex:null,layout:1,balloon:!1,close:!0,closeOnEscape:!1,closeOnClick:!1,displayMode:0,position:"bottomRight",target:"",targetFirst:!0,timeout:5e3,rtl:!1,animateInside:!0,drag:!0,pauseOnHover:!0,resetOnHover:!1,progressBar:!0,progressBarColor:"",progressBarEasing:"linear",overlay:!1,overlayClose:!1,overlayColor:"rgba(0, 0, 0, 0.6)",transitionIn:"fadeInUp",transitionOut:"fadeOut",transitionInMobile:"fadeInUp",transitionOutMobile:"fadeOutDown",buttons:{},inputs:{},onOpening:function(){},onOpened:function(){},onClosing:function(){},onClosed:function(){}};if("remove"in Element.prototype||(Element.prototype.remove=function(){this.parentNode&&this.parentNode.removeChild(this)}),"function"!=typeof window.CustomEvent){var p=function(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n};p.prototype=window.Event.prototype,window.CustomEvent=p}var m=function(t,e,n){if("[object Object]"===Object.prototype.toString.call(t))for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.call(n,t[o],o,t);else if(t)for(var i=0,s=t.length;s>i;i++)e.call(n,t[i],i,t)},g=function(t,e){var n={};return m(t,function(e,o){n[o]=t[o]}),m(e,function(t,o){n[o]=e[o]}),n},f=function(t){var e=document.createDocumentFragment(),n=document.createElement("div");for(n.innerHTML=t;n.firstChild;)e.appendChild(n.firstChild);return e},v=function(t){var e=btoa(encodeURIComponent(t));return e.replace(/=/g,"")},y=function(t){return"#"==t.substring(0,1)||"rgb"==t.substring(0,3)||"hsl"==t.substring(0,3)},h=function(t){try{return btoa(atob(t))==t}catch(e){return!1}},b=function(){return{move:function(t,e,o,a){var r,l=.3,d=180;0!==a&&(t.classList.add(n+"-dragged"),t.style.transform="translateX("+a+"px)",a>0?(r=(d-a)/d,l>r&&e.hide(g(o,{transitionOut:"fadeOutRight",transitionOutMobile:"fadeOutRight"}),t,"drag")):(r=(d+a)/d,l>r&&e.hide(g(o,{transitionOut:"fadeOutLeft",transitionOutMobile:"fadeOutLeft"}),t,"drag")),t.style.opacity=r,l>r&&((i||s)&&(t.style.left=a+"px"),t.parentNode.style.opacity=l,this.stopMoving(t,null)))},startMoving:function(t,e,n,o){o=o||window.event;var i=a?o.touches[0].clientX:o.clientX,s=t.style.transform.replace("px)","");s=s.replace("translateX(","");var r=i-s;n.transitionIn&&t.classList.remove(n.transitionIn),n.transitionInMobile&&t.classList.remove(n.transitionInMobile),t.style.transition="",a?document.ontouchmove=function(o){o.preventDefault(),o=o||window.event;var i=o.touches[0].clientX,s=i-r;b.move(t,e,n,s)}:document.onmousemove=function(o){o.preventDefault(),o=o||window.event;var i=o.clientX,s=i-r;b.move(t,e,n,s)}},stopMoving:function(t,e){a?document.ontouchmove=function(){}:document.onmousemove=function(){},t.style.opacity="",t.style.transform="",t.classList.contains(n+"-dragged")&&(t.classList.remove(n+"-dragged"),t.style.transition="transform 0.4s ease, opacity 0.4s ease",setTimeout(function(){t.style.transition=""},400))}}}();return e.setSetting=function(t,n,o){e.children[t][n]=o},e.getSetting=function(t,n){return e.children[t][n]},e.destroy=function(){m(document.querySelectorAll("."+n+"-overlay"),function(t,e){t.remove()}),m(document.querySelectorAll("."+n+"-wrapper"),function(t,e){t.remove()}),m(document.querySelectorAll("."+n),function(t,e){t.remove()}),this.children={},document.removeEventListener(n+"-opened",{},!1),document.removeEventListener(n+"-opening",{},!1),document.removeEventListener(n+"-closing",{},!1),document.removeEventListener(n+"-closed",{},!1),document.removeEventListener("keyup",{},!1),c={}},e.settings=function(t){e.destroy(),c=t,u=g(u,t||{})},m(l,function(t,n){e[n]=function(e){var n=g(c,e||{});n=g(t,n||{}),this.show(n)}}),e.progress=function(t,e,o){var i=this,s=e.getAttribute("data-iziToast-ref"),a=g(this.children[s],t||{}),r=e.querySelector("."+n+"-progressbar div");return{start:function(){"undefined"==typeof a.time.REMAINING&&(e.classList.remove(n+"-reseted"),null!==r&&(r.style.transition="width "+a.timeout+"ms "+a.progressBarEasing,r.style.width="0%"),a.time.START=(new Date).getTime(),a.time.END=a.time.START+a.timeout,a.time.TIMER=setTimeout(function(){clearTimeout(a.time.TIMER),e.classList.contains(n+"-closing")||(i.hide(a,e,"timeout"),"function"==typeof o&&o.apply(i))},a.timeout),i.setSetting(s,"time",a.time))},pause:function(){if("undefined"!=typeof a.time.START&&!e.classList.contains(n+"-paused")&&!e.classList.contains(n+"-reseted")){if(e.classList.add(n+"-paused"),a.time.REMAINING=a.time.END-(new Date).getTime(),clearTimeout(a.time.TIMER),i.setSetting(s,"time",a.time),null!==r){var t=window.getComputedStyle(r),l=t.getPropertyValue("width");r.style.transition="none",r.style.width=l}"function"==typeof o&&setTimeout(function(){o.apply(i)},10)}},resume:function(){"undefined"!=typeof a.time.REMAINING?(e.classList.remove(n+"-paused"),null!==r&&(r.style.transition="width "+a.time.REMAINING+"ms "+a.progressBarEasing,r.style.width="0%"),a.time.END=(new Date).getTime()+a.time.REMAINING,a.time.TIMER=setTimeout(function(){clearTimeout(a.time.TIMER),e.classList.contains(n+"-closing")||(i.hide(a,e,"timeout"),"function"==typeof o&&o.apply(i))},a.time.REMAINING),i.setSetting(s,"time",a.time)):this.start()},reset:function(){clearTimeout(a.time.TIMER),delete a.time.REMAINING,i.setSetting(s,"time",a.time),e.classList.add(n+"-reseted"),e.classList.remove(n+"-paused"),null!==r&&(r.style.transition="none",r.style.width="100%"),"function"==typeof o&&setTimeout(function(){o.apply(i)},10)}}},e.hide=function(t,e,i){"object"!=typeof e&&(e=document.querySelector(e));var s=this,a=g(this.children[e.getAttribute("data-iziToast-ref")],t||{});a.closedBy=i||null,delete a.time.REMAINING,e.classList.add(n+"-closing"),function(){var t=document.querySelector("."+n+"-overlay");if(null!==t){var e=t.getAttribute("data-iziToast-ref");e=e.split(",");var o=e.indexOf(String(a.ref));-1!==o&&e.splice(o,1),t.setAttribute("data-iziToast-ref",e.join()),0===e.length&&(t.classList.remove("fadeIn"),t.classList.add("fadeOut"),setTimeout(function(){t.remove()},700))}}(),a.transitionIn&&e.classList.remove(a.transitionIn),a.transitionInMobile&&e.classList.remove(a.transitionInMobile),o||window.innerWidth<=d?a.transitionOutMobile&&e.classList.add(a.transitionOutMobile):a.transitionOut&&e.classList.add(a.transitionOut);var r=e.parentNode.offsetHeight;e.parentNode.style.height=r+"px",e.style.pointerEvents="none",(!o||window.innerWidth>d)&&(e.parentNode.style.transitionDelay="0.2s");try{var l=new CustomEvent(n+"-closing",{detail:a,bubbles:!0,cancelable:!0});document.dispatchEvent(l)}catch(c){console.warn(c)}setTimeout(function(){e.parentNode.style.height="0px",e.parentNode.style.overflow="",setTimeout(function(){delete s.children[a.ref],e.parentNode.remove();try{var t=new CustomEvent(n+"-closed",{detail:a,bubbles:!0,cancelable:!0});document.dispatchEvent(t)}catch(o){console.warn(o)}"undefined"!=typeof a.onClosed&&a.onClosed.apply(null,[a,e,i])},1e3)},200),"undefined"!=typeof a.onClosing&&a.onClosing.apply(null,[a,e,i])},e.show=function(t){var i=this,s=g(c,t||{});if(s=g(u,s),s.time={},null===s.id&&(s.id=v(s.title+s.message+s.color)),1===s.displayMode||"once"==s.displayMode)try{if(document.querySelectorAll("."+n+"#"+s.id).length>0)return!1}catch(l){console.warn("["+n+"] Could not find an element with this selector: #"+s.id+". Try to set an valid id.")}if(2===s.displayMode||"replace"==s.displayMode)try{m(document.querySelectorAll("."+n+"#"+s.id),function(t,e){i.hide(s,t,"replaced")})}catch(l){console.warn("["+n+"] Could not find an element with this selector: #"+s.id+". Try to set an valid id.")}s.ref=(new Date).getTime()+Math.floor(1e7*Math.random()+1),e.children[s.ref]=s;var p={body:document.querySelector("body"),overlay:document.createElement("div"),toast:document.createElement("div"),toastBody:document.createElement("div"),toastTexts:document.createElement("div"),toastCapsule:document.createElement("div"),cover:document.createElement("div"),buttons:document.createElement("div"),inputs:document.createElement("div"),icon:s.iconUrl?document.createElement("img"):document.createElement("i"),wrapper:null};p.toast.setAttribute("data-iziToast-ref",s.ref),p.toast.appendChild(p.toastBody),p.toastCapsule.appendChild(p.toast),function(){if(p.toast.classList.add(n),p.toast.classList.add(n+"-opening"),p.toastCapsule.classList.add(n+"-capsule"),p.toastBody.classList.add(n+"-body"),p.toastTexts.classList.add(n+"-texts"),o||window.innerWidth<=d?s.transitionInMobile&&p.toast.classList.add(s.transitionInMobile):s.transitionIn&&p.toast.classList.add(s.transitionIn),s["class"]){var t=s["class"].split(" ");m(t,function(t,e){p.toast.classList.add(t)})}s.id&&(p.toast.id=s.id),s.rtl&&(p.toast.classList.add(n+"-rtl"),p.toast.setAttribute("dir","rtl")),s.layout>1&&p.toast.classList.add(n+"-layout"+s.layout),s.balloon&&p.toast.classList.add(n+"-balloon"),s.maxWidth&&(isNaN(s.maxWidth)?p.toast.style.maxWidth=s.maxWidth:p.toast.style.maxWidth=s.maxWidth+"px"),""===s.theme&&"light"===s.theme||p.toast.classList.add(n+"-theme-"+s.theme),s.color&&(y(s.color)?p.toast.style.background=s.color:p.toast.classList.add(n+"-color-"+s.color)),s.backgroundColor&&(p.toast.style.background=s.backgroundColor,s.balloon&&(p.toast.style.borderColor=s.backgroundColor))}(),function(){s.image&&(p.cover.classList.add(n+"-cover"),p.cover.style.width=s.imageWidth+"px",h(s.image.replace(/ /g,""))?p.cover.style.backgroundImage="url(data:image/png;base64,"+s.image.replace(/ /g,"")+")":p.cover.style.backgroundImage="url("+s.image+")",s.rtl?p.toastBody.style.marginRight=s.imageWidth+10+"px":p.toastBody.style.marginLeft=s.imageWidth+10+"px",p.toast.appendChild(p.cover))}(),function(){s.close?(p.buttonClose=document.createElement("button"),p.buttonClose.type="button",p.buttonClose.classList.add(n+"-close"),p.buttonClose.addEventListener("click",function(t){t.target;i.hide(s,p.toast,"button")}),p.toast.appendChild(p.buttonClose)):s.rtl?p.toast.style.paddingLeft="18px":p.toast.style.paddingRight="18px"}(),function(){s.progressBar&&(p.progressBar=document.createElement("div"),p.progressBarDiv=document.createElement("div"),p.progressBar.classList.add(n+"-progressbar"),p.progressBarDiv.style.background=s.progressBarColor,p.progressBar.appendChild(p.progressBarDiv),p.toast.appendChild(p.progressBar)),s.timeout&&(s.pauseOnHover&&!s.resetOnHover&&(p.toast.addEventListener("mouseenter",function(t){i.progress(s,p.toast).pause()}),p.toast.addEventListener("mouseleave",function(t){i.progress(s,p.toast).resume()})),s.resetOnHover&&(p.toast.addEventListener("mouseenter",function(t){i.progress(s,p.toast).reset()}),p.toast.addEventListener("mouseleave",function(t){i.progress(s,p.toast).start()})))}(),function(){s.iconUrl?(p.icon.setAttribute("class",n+"-icon"),p.icon.setAttribute("src",s.iconUrl)):s.icon&&(p.icon.setAttribute("class",n+"-icon "+s.icon),s.iconText&&p.icon.appendChild(document.createTextNode(s.iconText)),s.iconColor&&(p.icon.style.color=s.iconColor)),(s.icon||s.iconUrl)&&(s.rtl?p.toastBody.style.paddingRight="33px":p.toastBody.style.paddingLeft="33px",p.toastBody.appendChild(p.icon))}(),function(){s.title.length>0&&(p.strong=document.createElement("strong"),p.strong.classList.add(n+"-title"),p.strong.appendChild(f(s.title)),p.toastTexts.appendChild(p.strong),s.titleColor&&(p.strong.style.color=s.titleColor),s.titleSize&&(isNaN(s.titleSize)?p.strong.style.fontSize=s.titleSize:p.strong.style.fontSize=s.titleSize+"px"),s.titleLineHeight&&(isNaN(s.titleSize)?p.strong.style.lineHeight=s.titleLineHeight:p.strong.style.lineHeight=s.titleLineHeight+"px")),s.message.length>0&&(p.p=document.createElement("p"),p.p.classList.add(n+"-message"),p.p.appendChild(f(s.message)),p.toastTexts.appendChild(p.p),s.messageColor&&(p.p.style.color=s.messageColor),s.messageSize&&(isNaN(s.titleSize)?p.p.style.fontSize=s.messageSize:p.p.style.fontSize=s.messageSize+"px"),s.messageLineHeight&&(isNaN(s.titleSize)?p.p.style.lineHeight=s.messageLineHeight:p.p.style.lineHeight=s.messageLineHeight+"px")),s.title.length>0&&s.message.length>0&&(s.rtl?p.strong.style.marginLeft="10px":2===s.layout||s.rtl||(p.strong.style.marginRight="10px"))}(),p.toastBody.appendChild(p.toastTexts);var L;!function(){s.inputs.length>0&&(p.inputs.classList.add(n+"-inputs"),m(s.inputs,function(t,e){p.inputs.appendChild(f(t[0])),L=p.inputs.childNodes,L[e].classList.add(n+"-inputs-child"),t[3]&&setTimeout(function(){L[e].focus()},300),L[e].addEventListener(t[1],function(e){var n=t[2];return n(i,p.toast,this,e)})}),p.toastBody.appendChild(p.inputs))}(),function(){s.buttons.length>0&&(p.buttons.classList.add(n+"-buttons"),m(s.buttons,function(t,e){p.buttons.appendChild(f(t[0]));var o=p.buttons.childNodes;o[e].classList.add(n+"-buttons-child"),t[2]&&setTimeout(function(){o[e].focus()},300),o[e].addEventListener("click",function(e){e.preventDefault();var n=t[1];return n(i,p.toast,this,e,L)})})),p.toastBody.appendChild(p.buttons)}(),s.message.length>0&&(s.inputs.length>0||s.buttons.length>0)&&(p.p.style.marginBottom="0"),(s.inputs.length>0||s.buttons.length>0)&&(s.rtl?p.toastTexts.style.marginLeft="10px":p.toastTexts.style.marginRight="10px",s.inputs.length>0&&s.buttons.length>0&&(s.rtl?p.inputs.style.marginLeft="8px":p.inputs.style.marginRight="8px")),function(){p.toastCapsule.style.visibility="hidden",setTimeout(function(){var t=p.toast.offsetHeight,e=p.toast.currentStyle||window.getComputedStyle(p.toast),n=e.marginTop;n=n.split("px"),n=parseInt(n[0]);var o=e.marginBottom;o=o.split("px"),o=parseInt(o[0]),p.toastCapsule.style.visibility="",p.toastCapsule.style.height=t+o+n+"px",setTimeout(function(){p.toastCapsule.style.height="auto",s.target&&(p.toastCapsule.style.overflow="visible")},500),s.timeout&&i.progress(s,p.toast).start()},100)}(),function(){var t=s.position;if(s.target)p.wrapper=document.querySelector(s.target),p.wrapper.classList.add(n+"-target"),s.targetFirst?p.wrapper.insertBefore(p.toastCapsule,p.wrapper.firstChild):p.wrapper.appendChild(p.toastCapsule);else{if(-1==r.indexOf(s.position))return void console.warn("["+n+"] Incorrect position.\nIt can be › "+r);t=o||window.innerWidth<=d?"bottomLeft"==s.position||"bottomRight"==s.position||"bottomCenter"==s.position?n+"-wrapper-bottomCenter":"topLeft"==s.position||"topRight"==s.position||"topCenter"==s.position?n+"-wrapper-topCenter":n+"-wrapper-center":n+"-wrapper-"+t,p.wrapper=document.querySelector("."+n+"-wrapper."+t),p.wrapper||(p.wrapper=document.createElement("div"),p.wrapper.classList.add(n+"-wrapper"),p.wrapper.classList.add(t),document.body.appendChild(p.wrapper)),"topLeft"==s.position||"topCenter"==s.position||"topRight"==s.position?p.wrapper.insertBefore(p.toastCapsule,p.wrapper.firstChild):p.wrapper.appendChild(p.toastCapsule)}isNaN(s.zindex)?console.warn("["+n+"] Invalid zIndex."):p.wrapper.style.zIndex=s.zindex}(),function(){s.overlay&&(null!==document.querySelector("."+n+"-overlay.fadeIn")?(p.overlay=document.querySelector("."+n+"-overlay"),p.overlay.setAttribute("data-iziToast-ref",p.overlay.getAttribute("data-iziToast-ref")+","+s.ref),isNaN(s.zindex)||null===s.zindex||(p.overlay.style.zIndex=s.zindex-1)):(p.overlay.classList.add(n+"-overlay"),p.overlay.classList.add("fadeIn"),p.overlay.style.background=s.overlayColor,p.overlay.setAttribute("data-iziToast-ref",s.ref),isNaN(s.zindex)||null===s.zindex||(p.overlay.style.zIndex=s.zindex-1),document.querySelector("body").appendChild(p.overlay)),s.overlayClose?(p.overlay.removeEventListener("click",{}),p.overlay.addEventListener("click",function(t){i.hide(s,p.toast,"overlay")})):p.overlay.removeEventListener("click",{}))}(),function(){if(s.animateInside){p.toast.classList.add(n+"-animateInside");var t=[200,100,300];"bounceInLeft"!=s.transitionIn&&"bounceInRight"!=s.transitionIn||(t=[400,200,400]),s.title.length>0&&setTimeout(function(){p.strong.classList.add("slideIn")},t[0]),s.message.length>0&&setTimeout(function(){p.p.classList.add("slideIn")},t[1]),(s.icon||s.iconUrl)&&setTimeout(function(){p.icon.classList.add("revealIn")},t[2]);var e=150;s.buttons.length>0&&p.buttons&&setTimeout(function(){m(p.buttons.childNodes,function(t,n){setTimeout(function(){t.classList.add("revealIn")},e),e+=150})},s.inputs.length>0?150:0),s.inputs.length>0&&p.inputs&&(e=150,m(p.inputs.childNodes,function(t,n){setTimeout(function(){t.classList.add("revealIn")},e),e+=150}))}}(),s.onOpening.apply(null,[s,p.toast]);try{var C=new CustomEvent(n+"-opening",{detail:s,bubbles:!0,cancelable:!0});document.dispatchEvent(C)}catch(w){console.warn(w)}setTimeout(function(){p.toast.classList.remove(n+"-opening"),p.toast.classList.add(n+"-opened");try{var t=new CustomEvent(n+"-opened",{detail:s,bubbles:!0,cancelable:!0});document.dispatchEvent(t)}catch(e){console.warn(e)}s.onOpened.apply(null,[s,p.toast])},1e3),s.drag&&(a?(p.toast.addEventListener("touchstart",function(t){b.startMoving(this,i,s,t)},!1),p.toast.addEventListener("touchend",function(t){b.stopMoving(this,t)},!1)):(p.toast.addEventListener("mousedown",function(t){t.preventDefault(),b.startMoving(this,i,s,t)},!1),p.toast.addEventListener("mouseup",function(t){t.preventDefault(),b.stopMoving(this,t)},!1))),s.closeOnEscape&&document.addEventListener("keyup",function(t){t=t||window.event,27==t.keyCode&&i.hide(s,p.toast,"esc")}),s.closeOnClick&&p.toast.addEventListener("click",function(t){i.hide(s,p.toast,"toast")}),i.toast=p.toast},e}); diff --git a/conreq/_core/home/static/conreq/main.css b/conreq/_core/home/static/conreq/main.css new file mode 100644 index 00000000..4284eb58 --- /dev/null +++ b/conreq/_core/home/static/conreq/main.css @@ -0,0 +1,114 @@ +:root { + /* Globals */ + --body-bg: linear-gradient(145deg, rgb(24 31 32), rgb(18 18 18)); + --global-font: "Roboto", sans-serif; + --primary-font-size: 14px; + --secondary-font-size: 12px; + --box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), + 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12); + --accent-color: #258a6d; + --blur-filter: blur(20px); + /* Bootstrap */ + --bs-link-color: #5495f6; + --bs-link-hover-color: #286dd3; + --bs-warning-rgb: 255, 99, 7; + /* Sidebar */ + --sidebar-width: 240px; + --navigation-btn-padding: 13px 15px; + /* Navbar */ + --navbar-height: 0px; + /* Viewport */ + --viewport-padding: 30px; + --viewport-total-padding: calc(var(--viewport-padding) * 2); + --viewport-left: var(--sidebar-width); +} + +/* Generic rules */ +html { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + height: 100%; + font-family: var(--global-font); + scroll-behavior: smooth; + overflow-x: hidden; +} + +body { + background: url("data:image/png;base64,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"), + var(--body-bg); + margin: 0px; + padding: 0px; + overflow-y: hidden; + box-sizing: content-box; + position: relative; + line-height: 1; + width: 100%; + height: 100%; + z-index: 9999; + overflow-x: hidden; + color: rgba(255, 255, 255, 0.75); +} + +a { + transition: 0.3s ease color; + text-decoration: none; +} + +a:hover { + text-decoration: initial; +} + +:focus { + outline: none; +} + +.bold { + font-weight: 700; +} + +.no-highlighting { + /* iOS Safari */ + -webkit-touch-callout: none; + /* Konqueror HTML */ + -webkit-user-select: none; + /* Old versions of Firefox */ + -moz-user-select: none; + /* Internet Explorer/Edge */ + -ms-user-select: none; + /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ + user-select: none; +} + +.clickable { + cursor: pointer; +} + +.ellipsis { + text-overflow: ellipsis; + overflow: hidden; +} + +.spinner-border { + z-index: 400; + margin: auto; + color: var(--accent-color); +} + +.spinner-border.lg { + width: 4.5em; + height: 4.5em; + border-width: 0.68em; +} + +.homepage { + height: 100%; +} + +.blur { + -webkit-backdrop-filter: var(--blur-filter); + backdrop-filter: var(--blur-filter); +} + +.dropdown-menu { + --bs-dropdown-link-active-bg: var(--accent-color); +} diff --git a/conreq/_core/home/static/conreq/modal.css b/conreq/_core/home/static/conreq/modal.css new file mode 100644 index 00000000..51332f65 --- /dev/null +++ b/conreq/_core/home/static/conreq/modal.css @@ -0,0 +1,155 @@ +/* Modal Container */ + +.modal-open .modal { + overflow: hidden; +} + +.modal-content { + background: #3f3f3f; +} + +@media (min-width: 1200px) { + .modal-lg, + .modal-xl { + --bs-modal-width: 1000px; + } +} + +/* Modal Body */ + +.modal-body { + background: #252525; + color: #fff; + padding: 0; + line-height: 1.25; + max-height: 50vh; + overflow-y: auto; +} + +.modal-body > .loading { + display: flex; + align-items: center; + justify-content: center; + min-height: 65px; +} + +/* Modal Header */ + +.modal-header { + border: none; + align-items: center; + justify-content: space-between; + flex-direction: row-reverse; +} + +.modal-header .fas { + color: rgba(255, 255, 255, 0.7); + font-size: 20px; + transition: color 0.3s ease; +} + +.modal-header-btns { + margin-left: 12px; +} + +.modal-header-btns i:before { + margin-left: 13px; +} + +.modal-header .fas:hover { + color: #fff; +} + +.modal-header .title { + color: #fff; + font-weight: 700; + line-height: 1; + overflow-wrap: anywhere; +} + +/* Modal Footer */ + +.modal-footer { + border: none; +} + +/* Fullscreen large modals for mobile */ +@media (max-width: 575px) { + .modal-dialog.modal-lg { + margin: 0; + width: 100vw; + max-width: none; + height: 100%; + } + .modal-dialog.modal-lg .modal-content { + min-height: 100%; + border-radius: 0; + } + + .modal-dialog.modal-lg .modal-body { + max-height: 100%; + border-radius: 0; + } +} + +/* Replicating bootstrap animations */ +.modal.show .modal-dialog { + transform: initial; +} + +.modal.fade .modal-dialog { + -webkit-animation: modal 0.5s ease-out; + animation: modal 0.5s ease-out; +} + +@-webkit-keyframes modal { + 0% { + transform: translate(0, 50px); + opacity: 0; + } + 33% { + transform: translate(0, 50px); + opacity: 0; + } + 100% { + transform: translate(0, 0px); + opacity: 1; + } +} +@keyframes modal { + 0% { + transform: translate(0, 50px); + opacity: 0; + } + 33% { + transform: translate(0, 50px); + opacity: 0; + } + 100% { + transform: translate(0, 0px); + opacity: 1; + } +} + +.modal-backdrop.show { + -webkit-animation: modal-backdrop 0.5s ease-out; + animation: modal-backdrop 0.5s ease-out; +} + +@-webkit-keyframes modal-backdrop { + 0% { + opacity: 0; + } + 100% { + opacity: var(--bs-backdrop-opacity); + } +} + +@keyframes modal-backdrop { + 0% { + opacity: 0; + } + 100% { + opacity: var(--bs-backdrop-opacity); + } +} diff --git a/conreq/_core/home/static/conreq/navbar.css b/conreq/_core/home/static/conreq/navbar.css new file mode 100644 index 00000000..b51d4de6 --- /dev/null +++ b/conreq/_core/home/static/conreq/navbar.css @@ -0,0 +1,50 @@ +.navbar { + background: rgb(0 0 0 / 07%); + height: var(--navbar-height); + box-shadow: var(--box-shadow); + padding-left: 15px; + padding-right: 15px; + z-index: 300; + display: none; + border-color: #ffffff17; + border-width: 0 0 1px 0; + border-style: solid; +} + +.navbar-dark .navbar-brand { + margin-left: 20px; + margin-right: 0; + color: rgba(255, 255, 255, 0.5); + font-weight: 500; + font-size: 16px; +} + +.navbar-toggler { + display: inline-block; + border: none; + padding-left: 0; + padding-right: 0; + background: none; + border-radius: 5px; +} +.navbar-toggler:focus { + box-shadow: none; +} + +.navbar-toggler-icon { + font-size: 16px; +} + +@media only screen and (max-width: 800px) { + :root { + --navbar-height: 45px; + } + ::-webkit-scrollbar { + display: none; + } + .navbar { + display: flex; + flex-wrap: nowrap; + justify-content: flex-start; + } +} diff --git a/conreq/_core/home/static/conreq/navbar.js b/conreq/_core/home/static/conreq/navbar.js new file mode 100644 index 00000000..e45c29ae --- /dev/null +++ b/conreq/_core/home/static/conreq/navbar.js @@ -0,0 +1,3 @@ +$(".navbar-toggler").click(function () { + $(".sidebar").toggle(); +}); diff --git a/conreq/_core/home/static/conreq/scrollbar.css b/conreq/_core/home/static/conreq/scrollbar.css new file mode 100644 index 00000000..971abe3b --- /dev/null +++ b/conreq/_core/home/static/conreq/scrollbar.css @@ -0,0 +1,29 @@ +/* Webkit Scrollbar Styling */ + +::-webkit-scrollbar { + width: 7px; + height: 7px; +} + +::-webkit-scrollbar-thumb { + border-radius: 3px; + background: rgb(76 79 79 / 60%); +} + +::-webkit-scrollbar-thumb:hover { + background: rgb(76 79 79); +} + +::-webkit-scrollbar-track, +::-webkit-scrollbar-corner { + display: none; +} + +/* Hide scrollbars for non-webkit browsers */ + +* { + /* IE 11+ */ + -ms-overflow-style: none; + /* Firefox 64+ */ + scrollbar-width: none; +} diff --git a/conreq/_core/home/static/conreq/sidebar.css b/conreq/_core/home/static/conreq/sidebar.css new file mode 100644 index 00000000..8ecdfba3 --- /dev/null +++ b/conreq/_core/home/static/conreq/sidebar.css @@ -0,0 +1,196 @@ +.sidebar { + z-index: 200; + height: calc(100% - var(--navbar-height)); + width: var(--sidebar-width); + position: absolute; + left: calc(var(--sidebar-width) * -1); + opacity: 0; + background: rgb(0 0 0 / 07%); + border-color: #ffffff17; + border-width: 0 1px 0 0; + border-style: solid; + font-family: var(--global-font); + font-weight: 400; + box-shadow: var(--box-shadow); + overflow-x: hidden; + overflow-y: auto; + overflow-y: overlay; + display: inline-block; + color: rgb(156 156 156); + -webkit-animation: slide 1.25s forwards; + animation: slide 1.25s forwards; +} + +.sidebar::-webkit-scrollbar { + display: none; +} + +@-webkit-keyframes slide { + 100% { + left: 0; + opacity: 1; + } +} + +@keyframes slide { + 100% { + left: 0; + opacity: 1; + } +} + +.sidebar #navigation { + white-space: nowrap; + height: -webkit-min-content; + height: -moz-min-content; + height: min-content; + text-overflow: ellipsis; +} + +.nav-tab:hover { + background: rgba(255, 255, 255, 0.03); +} + +.nav-tab.active { + background: rgba(255, 255, 255, 0.08); + color: #fff; +} + +.nav-tab { + margin: 0 5px; +} + +.nav-tab, +.nav-group { + text-decoration: none; + font-size: var(--primary-font-size); + display: block; + transition: 0.3s; + white-space: nowrap; + overflow: hidden; + position: relative; + border-radius: 10px; + width: auto; +} + +.nav-group { + font-size: 15px; +} + +.nav-group.collapsed .fa-caret-up { + transform: rotate(180deg); +} + +.group-name { + padding: 23px 30px 10px 20px; +} + +.nav-tab > a, +.nav-tab > div { + display: block; + padding: var(--navigation-btn-padding); +} + +.nav-group .icon-right, +.nav-tab .icon-right { + color: rgb(94 94 94); + transition: color 0.3s ease, opacity 0.3s ease; + position: absolute; + right: 0; + top: 0; +} + +.nav-group .icon-right { + margin: 23px 20px 10px 20px; +} + +.nav-tab .icon-right { + margin: var(--navigation-btn-padding); +} + +.nav-group .icon-right:hover, +.nav-tab .icon-right:hover { + color: #fff; +} + +.sidebar-user { + color: #fff; + padding: 10px 15px; + background: var(--accent-color); + border-radius: 10px; + margin: 10px; + margin-bottom: 0; +} + +.sidebar-user .sidebar-profile-pic { + display: inline-flex; + margin-right: 15px; + background: #2e2e2e; + padding: 10px; + border-radius: 50%; + height: 35px; + width: 35px; + justify-content: center; + align-items: center; +} + +.sidebar-user .username-container { + display: inline-flex; + width: calc(100% - 50px); + font-weight: 700; +} + +.sidebar-user .username-container .username { + width: 100%; +} + +.tabs-collapse { + display: flex; + width: 100%; +} + +.tabs-indicator { + background: #5d5d5d; + width: 2px; + height: auto; + border-radius: 20px; + margin-left: 27px; + margin-bottom: 5px; +} + +.tabs { + width: 100%; +} + +.group-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 42px; + margin-left: -13px; +} + +@media only screen and (max-width: 1150px) { + :root { + --sidebar-width: 200px; + } +} + +@media only screen and (max-width: 800px) { + :root { + --sidebar-width: 100%; + } + .sidebar { + transition: height 0.4s ease-in; + background: #1f1f1f; + } + .sidebar.collapsed { + display: none; + } + .nav-tab .fas { + opacity: 1; + margin: 0; + padding: var(--navigation-btn-padding); + padding-left: 20px; + } +} diff --git a/conreq/_core/home/static/conreq/viewport.css b/conreq/_core/home/static/conreq/viewport.css new file mode 100644 index 00000000..02c937e6 --- /dev/null +++ b/conreq/_core/home/static/conreq/viewport.css @@ -0,0 +1,74 @@ +.viewport-container { + position: relative; + left: var(--sidebar-width); + height: calc(100% - var(--navbar-height)); + width: calc(100vw - var(--viewport-left)); + padding: 0 var(--viewport-padding); + opacity: 0; + overflow-y: auto; + z-index: 100; + -webkit-animation: fade-in 1s forwards; + animation: fade-in 1s forwards; +} + +.viewport-container > iframe { + width: 100%; + height: 100%; + display: block; +} + +.viewport-container.no-padding { + padding: 0; +} + +.viewport-container.loading { + position: absolute; + display: inline-flex; + background: rgb(0 0 0 / 25%); + visibility: visible; + opacity: 1; + transition-delay: 0.15s; + transition: visibility 0.65s, opacity 0.65s linear; +} + +.viewport-container.loading.hidden { + visibility: hidden; + opacity: 0; + transition: visibility 0.15s, opacity 0.15s linear; +} + +.viewport { + padding-bottom: var(--viewport-padding); + min-height: -webkit-fit-content; + min-height: -moz-fit-content; + min-height: fit-content; + margin: auto; + transition: opacity 1.5s ease; +} + +@media only screen and (max-width: 800px) { + :root { + --viewport-left: 0; + --viewport-padding: 15px; + --primary-font-size: 16px; + } + ::-webkit-scrollbar { + display: none; + } + .viewport-container { + width: 100vw; + left: 0px; + } +} + +@-webkit-keyframes fade-in { + 100% { + opacity: 1; + } +} + +@keyframes fade-in { + 100% { + opacity: 1; + } +} diff --git a/conreq/_core/home/static/conreq/welcome.css b/conreq/_core/home/static/conreq/welcome.css new file mode 100644 index 00000000..faceebc7 --- /dev/null +++ b/conreq/_core/home/static/conreq/welcome.css @@ -0,0 +1,20 @@ +.welcome { + text-align: center; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} + +.welcome button { + width: 200px; + margin: 0 auto; + margin-top: 30px; + height: 50px; +} + +.welcome h1, +.welcome p, +.welcome button { + z-index: 6; +} diff --git a/conreq/_core/home/templates/conreq/bootstrap_5.html b/conreq/_core/home/templates/conreq/bootstrap_5.html new file mode 100644 index 00000000..3444e5a7 --- /dev/null +++ b/conreq/_core/home/templates/conreq/bootstrap_5.html @@ -0,0 +1,5 @@ + + diff --git a/conreq/_core/home/templates/conreq/home.html b/conreq/_core/home/templates/conreq/home.html new file mode 100644 index 00000000..9a4d829e --- /dev/null +++ b/conreq/_core/home/templates/conreq/home.html @@ -0,0 +1,19 @@ +{% load static compress %} +{% load static %} +{% load reactpy %} +{% load solo_tags %} +{% get_solo 'server_settings.StylingSettings' as StylingSettings %} +{% get_solo 'server_settings.GeneralSettings' as GeneralSettings %} + + + + + + {% include "conreq/home_head.html" %} + + + + {% component "conreq._core.home.components.homepage" class="homepage" %} + + + diff --git a/conreq/_core/home/templates/conreq/home_head.html b/conreq/_core/home/templates/conreq/home_head.html new file mode 100644 index 00000000..64983c8f --- /dev/null +++ b/conreq/_core/home/templates/conreq/home_head.html @@ -0,0 +1,92 @@ +{% load static compress %} +{% load static %} +{% load pwa %} +{% load bootstrap %} + + + + + +{{ GeneralSettings.server_name }} + + + + +{% include "conreq/icons.html" %} +{% pwa_head_content %} + + + + + + + + + + + + + + + +{% bootstrap_5 %} + + + + + + + + + +{% compress css %} + + + + + + + + + +{% for stylesheet in home_config.local_stylesheets %} + +{% endfor %} +{% endcompress %} + +{% for stylesheet in home_config.remote_stylesheets %} + +{% endfor %} + + +{% compress js %} + +{% for script in home_config.local_scripts %} + +{% endfor %} +{% endcompress %} + +{% for script in home_config.remote_scripts %} + +{% endfor %} + + +{% for template in home_config.head_content %} +{% include template.path %} +{% endfor %} + + + + +{{ StylingSettings.head_html | safe }} diff --git a/conreq/_core/home/templates/conreq/icons.html b/conreq/_core/home/templates/conreq/icons.html new file mode 100644 index 00000000..cb0878c7 --- /dev/null +++ b/conreq/_core/home/templates/conreq/icons.html @@ -0,0 +1,4 @@ +{% load static %} + + + diff --git a/conreq/core/manage_users/__init__.py b/conreq/_core/home/templatetags/__init__.py similarity index 100% rename from conreq/core/manage_users/__init__.py rename to conreq/_core/home/templatetags/__init__.py diff --git a/conreq/_core/home/templatetags/bootstrap.py b/conreq/_core/home/templatetags/bootstrap.py new file mode 100644 index 00000000..e668ffc9 --- /dev/null +++ b/conreq/_core/home/templatetags/bootstrap.py @@ -0,0 +1,8 @@ +from django import template + +register = template.Library() + + +@register.inclusion_tag("conreq/bootstrap_5.html") +def bootstrap_5(): + pass diff --git a/conreq/_core/home/views.py b/conreq/_core/home/views.py new file mode 100644 index 00000000..beeaeaed --- /dev/null +++ b/conreq/_core/home/views.py @@ -0,0 +1,13 @@ +from django.contrib.auth.decorators import login_required +from django.shortcuts import render + +from conreq import config +from conreq._core.initialization.views import initialize + + +def home(request): + """Renders the homepage.""" + # Render the home page + return initialize(request) or login_required(render)( + request, config.templates.home, {"home_config": config.homepage} + ) diff --git a/conreq/core/manage_users/migrations/__init__.py b/conreq/_core/initialization/__init__.py similarity index 100% rename from conreq/core/manage_users/migrations/__init__.py rename to conreq/_core/initialization/__init__.py diff --git a/conreq/_core/initialization/admin.py b/conreq/_core/initialization/admin.py new file mode 100644 index 00000000..186ca040 --- /dev/null +++ b/conreq/_core/initialization/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from conreq._core.initialization.models import Initialization + + +@admin.register(Initialization) +class InitializationAdmin(admin.ModelAdmin): + pass diff --git a/conreq/_core/initialization/apps.py b/conreq/_core/initialization/apps.py new file mode 100644 index 00000000..a5af0c55 --- /dev/null +++ b/conreq/_core/initialization/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class InitializationConfig(AppConfig): + name = "conreq._core.initialization" + verbose_name = "First Run" diff --git a/conreq/_core/initialization/forms.py b/conreq/_core/initialization/forms.py new file mode 100644 index 00000000..00253b7d --- /dev/null +++ b/conreq/_core/initialization/forms.py @@ -0,0 +1,8 @@ +from django.contrib.auth import get_user_model +from django.contrib.auth.forms import UserCreationForm + + +class InitializationForm(UserCreationForm): + class Meta: + model = get_user_model() + fields = ("username", "email", "password1", "password2") diff --git a/conreq/_core/initialization/migrations/0001_initial.py b/conreq/_core/initialization/migrations/0001_initial.py new file mode 100644 index 00000000..bcfda451 --- /dev/null +++ b/conreq/_core/initialization/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 4.0 on 2021-12-20 19:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Initialization", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("initialized", models.BooleanField(default=False)), + ], + options={ + "verbose_name": "Initialization", + "verbose_name_plural": "Initialization", + }, + ), + ] diff --git a/conreq/_core/initialization/migrations/0002_alter_initialization_options.py b/conreq/_core/initialization/migrations/0002_alter_initialization_options.py new file mode 100644 index 00000000..738a6019 --- /dev/null +++ b/conreq/_core/initialization/migrations/0002_alter_initialization_options.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.1 on 2023-12-29 01:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("initialization", "0001_initial"), + ] + + operations = [ + migrations.AlterModelOptions( + name="initialization", + options={ + "verbose_name": "Initialization Completed Flag", + "verbose_name_plural": "Initialization Completed Flag", + }, + ), + ] diff --git a/conreq/core/more_info/__init__.py b/conreq/_core/initialization/migrations/__init__.py similarity index 100% rename from conreq/core/more_info/__init__.py rename to conreq/_core/initialization/migrations/__init__.py diff --git a/conreq/_core/initialization/models.py b/conreq/_core/initialization/models.py new file mode 100644 index 00000000..61ec4657 --- /dev/null +++ b/conreq/_core/initialization/models.py @@ -0,0 +1,17 @@ +from django.db import models +from solo.models import SingletonModel + + +# Create server settings model for accepting TOS +# This might be better created as a homepage initialization screen +# Will need to specifiy if the TOS is shown per-user, or only once per-server to admins +# Will need to support showing a new TOS if TOS version has changed +class Initialization(SingletonModel): + def __str__(self): + return "Initialization" + + class Meta: + verbose_name = "Initialization Completed Flag" + verbose_name_plural = verbose_name + + initialized = models.BooleanField(default=False) diff --git a/conreq/_core/initialization/templates/conreq/initialization.html b/conreq/_core/initialization/templates/conreq/initialization.html new file mode 100644 index 00000000..e6bb2830 --- /dev/null +++ b/conreq/_core/initialization/templates/conreq/initialization.html @@ -0,0 +1,40 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + +{% block title %} +First Time Setup +{% endblock %} + +{% block content %} +
+ +
+ + +

FIRST TIME SETUP

+

Create your admin account.

+ +
+ {% csrf_token %} + + {{ form.email.errors }} + + + {{ form.username.errors }} + + + {{ form.password2.errors }} + + + + + +
+{% endblock %} diff --git a/conreq/_core/initialization/views.py b/conreq/_core/initialization/views.py new file mode 100644 index 00000000..70c41d40 --- /dev/null +++ b/conreq/_core/initialization/views.py @@ -0,0 +1,61 @@ +from django.contrib.auth import authenticate, login +from django.core.exceptions import ValidationError +from django.shortcuts import redirect, render + +from conreq._core.initialization.forms import InitializationForm +from conreq._core.initialization.models import Initialization + +INITIALIZED = False + + +# TODO: Have an "IMPORT BACKUP" button that will import a backup file, if one exists. +def initialize(request): + # pylint: disable=global-statement + # Check cached value if we've already initialized + global INITIALIZED + if INITIALIZED: + return None + + # Run the first time initialization if needed + initialization = Initialization.get_solo() + if initialization.initialized: + INITIALIZED = True + return None + + # User submitted the first time setup form + if request.method == "POST": + form = InitializationForm(request.POST) + + # Create the superuser and set up the database if the form is valid + if form.is_valid(): + return _display_initialization(form, request, initialization) + + # Form data wasn't valid, so return the error codes + return render(request, "conreq/initialization.html", {"form": form}) + + # User needs to fill out the first time setup + return render(request, "conreq/initialization.html") + + +def _display_initialization( + form: InitializationForm, request, initialization: Initialization +): + form.full_clean() + form.save() + username = form.cleaned_data.get("username") + password = form.cleaned_data.get("password1") + user = authenticate(username=username, password=password) + + if not user: + raise ValidationError("Failed to authenticate user") + + setattr(user, "is_staff", True) + setattr(user, "is_admin", True) + setattr(user, "is_superuser", True) + user.full_clean() + user.save() + login(request, user) + initialization.initialized = True + initialization.full_clean() + initialization.save() + return redirect("conreq:landing") diff --git a/conreq/core/more_info/migrations/__init__.py b/conreq/_core/landing/__init__.py similarity index 100% rename from conreq/core/more_info/migrations/__init__.py rename to conreq/_core/landing/__init__.py diff --git a/conreq/_core/landing/apps.py b/conreq/_core/landing/apps.py new file mode 100644 index 00000000..8a048cb2 --- /dev/null +++ b/conreq/_core/landing/apps.py @@ -0,0 +1,10 @@ +from django.apps import AppConfig + +from conreq.utils.modules import load + + +class LandingConfig(AppConfig): + name = "conreq._core.landing" + + def ready(self): + load("views") diff --git a/conreq/_core/landing/views.py b/conreq/_core/landing/views.py new file mode 100644 index 00000000..5e94e0e5 --- /dev/null +++ b/conreq/_core/landing/views.py @@ -0,0 +1,15 @@ +from django.shortcuts import redirect, render + +from conreq import config +from conreq._core.initialization.views import initialize + + +def landing(request): + """Renders the landing page (if available).""" + # sourcery skip: assign-if-exp + # Redirect if a landing page doesn't exist + if not config.templates.landing: + return redirect("conreq:home") + + # Render the landing page + return initialize(request) or render(request, config.templates.landing) diff --git a/conreq/core/password_reset/__init__.py b/conreq/_core/password_reset/__init__.py similarity index 100% rename from conreq/core/password_reset/__init__.py rename to conreq/_core/password_reset/__init__.py diff --git a/conreq/_core/password_reset/apps.py b/conreq/_core/password_reset/apps.py new file mode 100644 index 00000000..289054dd --- /dev/null +++ b/conreq/_core/password_reset/apps.py @@ -0,0 +1,11 @@ +from django.apps import AppConfig + +from conreq.utils.modules import load + + +class PasswordResetConfig(AppConfig): + name = "conreq._core.password_reset" + verbose_name = "Password Reset" + + def ready(self): + load("views") diff --git a/conreq/_core/password_reset/forms.py b/conreq/_core/password_reset/forms.py new file mode 100644 index 00000000..127be5ea --- /dev/null +++ b/conreq/_core/password_reset/forms.py @@ -0,0 +1,61 @@ +from django import forms +from django.contrib.auth import get_user_model, password_validation +from django.contrib.auth.forms import PasswordResetForm as _PasswordResetForm +from django.contrib.auth.forms import SetPasswordForm as _SetPasswordForm +from django.contrib.auth.forms import _unicode_ci_compare # type: ignore +from django.db.models import Q +from django.forms import CharField, TextInput +from django.utils.translation import gettext_lazy as _ + + +class PasswordResetForm(_PasswordResetForm): + email = CharField( + label=_("Email"), + max_length=254, + widget=TextInput( + attrs={"autocomplete": "email", "placeholder": "Username or Email"} + ), + ) + + def get_users(self, username_or_email): + """Given an email, return matching user(s) who should receive a reset. + + This allows subclasses to more easily customize the default policies + that prevent inactive users and users with unusable passwords from + resetting their password. + """ + # pylint: disable=arguments-renamed, protected-access + active_users = get_user_model().objects.filter( + Q(email__iexact=username_or_email) | Q(username__iexact=username_or_email), + is_active=True, + ) + return ( + u + for u in active_users + if u.has_usable_password() + and ( + _unicode_ci_compare(username_or_email, getattr(u, "email")) + or _unicode_ci_compare(username_or_email, getattr(u, "username")), + ) + ) + + +class SetPasswordForm(_SetPasswordForm): + new_password1 = forms.CharField( + label=_("New password"), + widget=forms.PasswordInput( + attrs={"autocomplete": "new-password", "placeholder": "New Password"} + ), + strip=False, + help_text=password_validation.password_validators_help_text_html(), + ) + new_password2 = forms.CharField( + label=_("New password confirmation"), + strip=False, + widget=forms.PasswordInput( + attrs={ + "autocomplete": "new-password", + "placeholder": "Confirm New Password", + } + ), + ) diff --git a/conreq/_core/password_reset/templates/conreq/password_reset.html b/conreq/_core/password_reset/templates/conreq/password_reset.html new file mode 100644 index 00000000..a4e69d15 --- /dev/null +++ b/conreq/_core/password_reset/templates/conreq/password_reset.html @@ -0,0 +1,21 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + +{% block title %} +Password Reset +{% endblock %} + +{% block content %} +
+ +
+ +

RESET MY PASSWORD

+

Enter your username or email.

+ +
+ {% csrf_token %} + {{ form.email }} + +
+{% endblock %} diff --git a/conreq/_core/password_reset/templates/conreq/password_reset_confirm.html b/conreq/_core/password_reset/templates/conreq/password_reset_confirm.html new file mode 100644 index 00000000..24a06374 --- /dev/null +++ b/conreq/_core/password_reset/templates/conreq/password_reset_confirm.html @@ -0,0 +1,39 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + + +{% block title %} +{% if validLink %} +Password Reset +{% else %} +Invalid Password Reset +{% endif %} +{% endblock %} + + +{% block content %} + + +
+ +
+ +{% if validlink %} +

PASSWORD RESET

+

Please enter your new password.

+
+ {% csrf_token %} + {{ form.new_password1.errors }} + {{ form.new_password1 }} + {{ form.new_password2.errors }} + {{ form.new_password2 }} + +
+{% else %} +

INVALID PASSWORD RESET

+

Key used or expired.

+

+ The password reset link was invalid, possibly because it has already been used. Please request a new password reset. +

+{% endif %} +{% endblock %} diff --git a/conreq/_core/password_reset/templates/conreq/password_reset_sent.html b/conreq/_core/password_reset/templates/conreq/password_reset_sent.html new file mode 100644 index 00000000..592f442f --- /dev/null +++ b/conreq/_core/password_reset/templates/conreq/password_reset_sent.html @@ -0,0 +1,25 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + +{% block title %} +Password Reset Sent +{% endblock %} + +{% block content %} +
+ +
+ +
+

PASSWORD RESET SENT

+

Reset email has been sent.

+

+ We’ve emailed you instructions for setting your password, if an account exists with the details you entered. You + should receive them shortly. +

+

+ If you don’t receive an email, please make sure you’ve entered the correct information. Additionally, make sure + to check your spam folder. +

+
+{% endblock %} diff --git a/conreq/_core/password_reset/urls.py b/conreq/_core/password_reset/urls.py new file mode 100644 index 00000000..44c3efa6 --- /dev/null +++ b/conreq/_core/password_reset/urls.py @@ -0,0 +1,13 @@ +from django.urls import path + +from conreq.config.wrappers import views + +urlpatterns = [ + path("", views.password_reset, name="password_reset"), + path("sent", views.password_reset_sent, name="password_reset_sent"), + path( + "/", + views.password_reset_confirm, + name="password_reset_confirm", + ), +] diff --git a/conreq/_core/password_reset/views.py b/conreq/_core/password_reset/views.py new file mode 100644 index 00000000..9e960a83 --- /dev/null +++ b/conreq/_core/password_reset/views.py @@ -0,0 +1,22 @@ +from django.contrib.auth import views as auth_views +from django.urls import reverse_lazy + +from conreq import config +from conreq._core.password_reset.forms import PasswordResetForm, SetPasswordForm + + +class PasswordResetView(auth_views.PasswordResetView): + success_url = reverse_lazy("conreq:password_reset_sent") + template_name = config.templates.password_reset + form_class = PasswordResetForm + + +class PassWordResetSentView(auth_views.PasswordResetDoneView): + template_name = config.templates.password_reset_sent + + +class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): + template_name = config.templates.password_reset_confirm + success_url = reverse_lazy("conreq:home") + post_reset_login = True + form_class = SetPasswordForm diff --git a/conreq/core/pwa/__init__.py b/conreq/_core/pwa/__init__.py similarity index 100% rename from conreq/core/pwa/__init__.py rename to conreq/_core/pwa/__init__.py diff --git a/conreq/_core/pwa/apps.py b/conreq/_core/pwa/apps.py new file mode 100644 index 00000000..33680cdc --- /dev/null +++ b/conreq/_core/pwa/apps.py @@ -0,0 +1,47 @@ +""" Settings required by django-app. """ + + +from django.apps import AppConfig +from django.conf import settings + +from conreq.utils.environment import get_base_url + + +class PwaConfig(AppConfig): + name = "conreq._core.pwa" + + # Parameters to include in site.webmanifest and appropriate meta tags + + app_name = "Conreq" + app_description = "A hub for great things." + app_theme_color = "#3fcfa6" + app_background_color = "#04110d" + app_display = "standalone" + app_start_url = get_base_url() + app_scope = get_base_url() + app_debug_mode = settings.DEBUG + app_orientation = "any" + app_status_bar_color = "default" + app_icons = [ + { + "src": f"{get_base_url()}static/conreq/icons/standard.png", + "sizes": "512x512", + "purpose": "any", + }, + { + "src": f"{get_base_url()}static/conreq/icons/maskable.png", + "sizes": "512x512", + "purpose": "maskable", + }, + ] + + app_icons_apple = [ + { + "src": f"{get_base_url()}static/conreq/icons/apple-touch-icon.png", + "sizes": "180x180", + } + ] + + app_splash_screen: list[str] = [] + app_dir = "auto" + app_lang = "en-US" diff --git a/conreq/_core/pwa/static/conreq/offline.css b/conreq/_core/pwa/static/conreq/offline.css new file mode 100644 index 00000000..1d7e4378 --- /dev/null +++ b/conreq/_core/pwa/static/conreq/offline.css @@ -0,0 +1,101 @@ +.default-box { + display: flex; + flex-direction: column; + align-items: center; +} + +.default-box p { + font-size: 16px; + text-align: center; +} + +.default-box button { + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + +.lds-ellipsis { + display: none; + position: relative; + width: 80px; + height: 55px; +} +.lds-ellipsis div { + position: absolute; + top: 33px; + width: 13px; + height: 13px; + border-radius: 50%; + background: #fff; + -webkit-animation-timing-function: cubic-bezier(0, 1, 1, 0); + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +.lds-ellipsis div:nth-child(1) { + left: 8px; + -webkit-animation: lds-ellipsis1 0.6s infinite; + animation: lds-ellipsis1 0.6s infinite; +} +.lds-ellipsis div:nth-child(2) { + left: 8px; + -webkit-animation: lds-ellipsis2 0.6s infinite; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(3) { + left: 32px; + -webkit-animation: lds-ellipsis2 0.6s infinite; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(4) { + left: 56px; + -webkit-animation: lds-ellipsis3 0.6s infinite; + animation: lds-ellipsis3 0.6s infinite; +} +@-webkit-keyframes lds-ellipsis1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@keyframes lds-ellipsis1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@-webkit-keyframes lds-ellipsis3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } +} +@keyframes lds-ellipsis3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } +} +@-webkit-keyframes lds-ellipsis2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} +@keyframes lds-ellipsis2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} diff --git a/conreq/_core/pwa/templates/conreq/offline.html b/conreq/_core/pwa/templates/conreq/offline.html new file mode 100644 index 00000000..340aabca --- /dev/null +++ b/conreq/_core/pwa/templates/conreq/offline.html @@ -0,0 +1,35 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + +{% block extend_head %} + +{% endblock %} + +{% block title %} +Offline +{% endblock %} + +{% block content %} + +

Could not connect to {{ GeneralSettings.server_name }}.

+

Check your network connection or try again later.

+
+
+
+
+
+
+ +{% endblock %} diff --git a/conreq/_core/pwa/templates/conreq/pwa.html b/conreq/_core/pwa/templates/conreq/pwa.html new file mode 100644 index 00000000..e5f68fd8 --- /dev/null +++ b/conreq/_core/pwa/templates/conreq/pwa.html @@ -0,0 +1,52 @@ +{% load static %} + + + + + + + + + + + + + + + + +{% for icon in pwa.app_icons_apple %} + +{% endfor %} +{% for icon in pwa.app_icons %} + +{% endfor %} + + +{% for splash in pwa.app_splash_screen %} + +{% endfor %} + + + + + + + diff --git a/conreq/_core/pwa/templates/conreq/serviceworker.js b/conreq/_core/pwa/templates/conreq/serviceworker.js new file mode 100644 index 00000000..d51b9c4f --- /dev/null +++ b/conreq/_core/pwa/templates/conreq/serviceworker.js @@ -0,0 +1,51 @@ +/* {% load static %} */ + +var staticCacheName = "django-pwa-v" + new Date().getTime(); +var filesToCache = [ + "{% url 'conreq:offline' %}", + "{% url 'conreq:web_manifest' %}", + "{% static 'conreq/main_slim.css' %}", + "{% static 'conreq/offline.css' %}", + "{% static 'conreq/icons/favicon-32x32.png' %}", + "{% static 'conreq/icons/standard.png' %}", + "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js", + "https://fonts.googleapis.com/css?family=Roboto:300,400,700&display=swap", +]; + +// Cache on install +self.addEventListener("install", (event) => { + this.skipWaiting(); + event.waitUntil( + caches.open(staticCacheName).then((cache) => { + return cache.addAll(filesToCache); + }) + ); +}); + +// Clear cache on activate +self.addEventListener("activate", (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames + .filter((cacheName) => cacheName.startsWith("django-pwa-")) + .filter((cacheName) => cacheName !== staticCacheName) + .map((cacheName) => caches.delete(cacheName)) + ); + }) + ); +}); + +// Serve from Cache +self.addEventListener("fetch", (event) => { + event.respondWith( + caches + .match(event.request) + .then((response) => { + return response || fetch(event.request); + }) + .catch(() => { + return caches.match("{% url 'conreq:offline' %}"); + }) + ); +}); diff --git a/conreq/_core/pwa/templates/conreq/site.webmanifest b/conreq/_core/pwa/templates/conreq/site.webmanifest new file mode 100644 index 00000000..db3ce529 --- /dev/null +++ b/conreq/_core/pwa/templates/conreq/site.webmanifest @@ -0,0 +1,16 @@ +{% load pwa %} +{ + "name": {{ pwa.app_name|jsonify }}, + "short_name": {{ pwa.app_name|jsonify }}, + "description": {{ pwa.app_description|jsonify }}, + "start_url": {{ pwa.app_start_url|jsonify }}, + "display": {{ pwa.app_display|jsonify }}, + "scope": {{ pwa.app_scope|jsonify }}, + "orientation": {{ pwa.app_orientation|jsonify }}, + "background_color": {{ pwa.app_background_color|jsonify }}, + "theme_color": {{ pwa.app_theme_color|jsonify }}, + "status_bar": {{ pwa.app_status_bar_color|jsonify }}, + "icons": {{ pwa.app_icons|jsonify }}, + "dir": {{ pwa.app_dir|jsonify }}, + "lang": {{ pwa.app_lang|jsonify }} +} diff --git a/conreq/core/pwa/migrations/__init__.py b/conreq/_core/pwa/templatetags/__init__.py similarity index 100% rename from conreq/core/pwa/migrations/__init__.py rename to conreq/_core/pwa/templatetags/__init__.py diff --git a/conreq/_core/pwa/templatetags/pwa.py b/conreq/_core/pwa/templatetags/pwa.py new file mode 100644 index 00000000..cae81515 --- /dev/null +++ b/conreq/_core/pwa/templatetags/pwa.py @@ -0,0 +1,26 @@ +import functools +import json + +from django import template +from django.core.serializers.json import DjangoJSONEncoder +from django.utils.safestring import mark_safe + +from conreq._core.pwa.apps import PwaConfig + +register = template.Library() + + +@register.filter(is_safe=True) +def jsonify(obj): + """Transform a python object so it can be safely used in javascript/JSON.""" + if isinstance(obj, str): + json_val = functools.cache(json.dumps)(obj, cls=DjangoJSONEncoder) + else: + json_val = json.dumps(obj, cls=DjangoJSONEncoder) + return mark_safe(json_val) + + +@register.inclusion_tag("conreq/pwa.html", takes_context=True) +def pwa_head_content(context): + # pylint: disable=unused-argument + return {"pwa": PwaConfig.__dict__} diff --git a/conreq/_core/pwa/urls.py b/conreq/_core/pwa/urls.py new file mode 100644 index 00000000..e3ebf4c0 --- /dev/null +++ b/conreq/_core/pwa/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from conreq.config.wrappers import views + +# Serve up serviceworker.js and site.webmanifest at the root +urlpatterns = [ + path("serviceworker.js", views.service_worker, name="service_worker"), + path("site.webmanifest", views.web_manifest, name="web_manifest"), + path("offline/", views.offline, name="offline"), +] diff --git a/conreq/_core/pwa/views.py b/conreq/_core/pwa/views.py new file mode 100644 index 00000000..1a6a8cf7 --- /dev/null +++ b/conreq/_core/pwa/views.py @@ -0,0 +1,25 @@ +from django.shortcuts import render + +from conreq import config +from conreq._core.pwa.apps import PwaConfig + + +def service_worker(request): + return render( + request, + "conreq/serviceworker.js", + content_type="application/javascript", + ) + + +def web_manifest(request): + return render( + request, + "conreq/site.webmanifest", + {"pwa": PwaConfig.__dict__}, + content_type="application/manifest+json", + ) + + +def offline(request): + return render(request, config.templates.offline) diff --git a/conreq/core/pwa/templatetags/__init__.py b/conreq/_core/server_settings/__init__.py similarity index 100% rename from conreq/core/pwa/templatetags/__init__.py rename to conreq/_core/server_settings/__init__.py diff --git a/conreq/_core/server_settings/admin.py b/conreq/_core/server_settings/admin.py new file mode 100644 index 00000000..dc0408e8 --- /dev/null +++ b/conreq/_core/server_settings/admin.py @@ -0,0 +1,23 @@ +from django.contrib import admin + +from conreq._core.server_settings.models import ( + GeneralSettings, + StylingSettings, + WebserverSettings, +) + + +# Register your models here. +@admin.register(GeneralSettings) +class GeneralSettingsAdmin(admin.ModelAdmin): + pass + + +@admin.register(StylingSettings) +class StylingSettingsAdmin(admin.ModelAdmin): + pass + + +@admin.register(WebserverSettings) +class WebserverSettingsAdmin(admin.ModelAdmin): + pass diff --git a/conreq/_core/server_settings/apps.py b/conreq/_core/server_settings/apps.py new file mode 100644 index 00000000..1762da33 --- /dev/null +++ b/conreq/_core/server_settings/apps.py @@ -0,0 +1,18 @@ +from django.apps import AppConfig +from reactpy_django.utils import register_iframe + +from conreq.utils.modules import load + + +class ServerSettingsConfig(AppConfig): + name = "conreq._core.server_settings" + verbose_name = "Server" + + def ready(self): + from . import views + + load("components") + register_iframe(views.GeneralSettingsView) + register_iframe(views.StylingSettingsView) + register_iframe(views.WebserverSettingsView) + register_iframe(views.EmailSettingsView) diff --git a/conreq/_core/server_settings/components.py b/conreq/_core/server_settings/components.py new file mode 100644 index 00000000..6c674010 --- /dev/null +++ b/conreq/_core/server_settings/components.py @@ -0,0 +1,91 @@ +import platform +import sys +from os.path import relpath +from uuid import uuid4 + +import channels +import django +from django.conf import settings +from reactpy import component, html +from reactpy_django.components import view_to_iframe +from reactpy_django.decorators import user_passes_test + +from conreq import config +from conreq._core.components import tabbed_viewport +from conreq._core.server_settings import views + +# TODO: Create generic notification agent API. + +general_settings_vtc = view_to_iframe(views.GeneralSettingsView) +styling_settings_vtc = view_to_iframe(views.StylingSettingsView) +webserver_settings_vtc = view_to_iframe(views.WebserverSettingsView) +email_settings_vtc = view_to_iframe(views.EmailSettingsView) + + +@user_passes_test(lambda user: user.is_staff) +@component +def general_settings(): + return general_settings_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def styling_settings(): + return styling_settings_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def webserver_settings(): + return webserver_settings_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def email_settings(): + return email_settings_vtc() + + +def system_info(): + settings_values = [ + ("Conreq Version", settings.CONREQ_VERSION), + ("Configuration File", relpath(settings.DOTENV_FILE)), + ("Cache Directory", relpath(settings.CACHES["default"]["LOCATION"])), + ("Conreq Log File", relpath(settings.CONREQ_LOG_FILE)), + ("Webserver Log File", relpath(settings.ACCESS_LOG_FILE)), + ("Database File", relpath(settings.DATABASES["default"]["NAME"])), # type: ignore + ("Log Level", settings.LOG_LEVEL), + ("Platform", platform.platform()), + ("CPU Architecture", platform.machine()), + ("System Timezone", settings.TIME_ZONE), + ("Django Version", django.get_version()), + ("Channels Version", channels.__version__), + ("Python Version", platform.python_version()), + ("Python Arguments", " ".join(sys.argv)), + ] + + return html.table( + {"style": {"margin_top": "20px"}}, + [ + html.tr({"key": uuid4().hex}, html.td(f"{name}"), html.td(f"{value}")) + for name, value in settings_values + ], + ) + + +def licenses(): + return html.div( + {"style": {"margin_top": "20px"}}, + "This page is under construction, and will be developed in a later release.", + ) + + +# pylint: disable=protected-access +@component +def server_settings(): + return html._( + tabbed_viewport( + tabs=config.tabs.server_settings.installed, + top_tabs=config._internal_tabs.server_settings, + ) + ) diff --git a/conreq/_core/server_settings/forms.py b/conreq/_core/server_settings/forms.py new file mode 100644 index 00000000..cfbf4ee4 --- /dev/null +++ b/conreq/_core/server_settings/forms.py @@ -0,0 +1,215 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Submit +from django.conf import settings +from django.db.models import TextChoices +from django.forms import CharField, ModelForm +from django_ace import AceWidget + +from conreq._core.email.models import EmailSettings +from conreq._core.forms import ( + EnvBooleanField, + EnvCharField, + EnvChoiceField, + EnvFormMixin, + EnvIntegerField, +) +from conreq._core.server_settings.models import ( + GeneralSettings, + StylingSettings, + WebserverSettings, +) +from conreq.utils.environment import get_home_url + + +class LogLevelChoices(TextChoices): + DEBUG = "DEBUG" + INFO = "INFO" + WARNING = "WARNING" + ERROR = "ERROR" + CRITICAL = "CRITICAL" + + +class GeneralSettingsForm(EnvFormMixin, ModelForm): + debug_mode = EnvBooleanField( + env_name="DEBUG_MODE", + initial=settings.DEBUG, + help_text="Disables security features and adds debugging tools.", + ) + safe_mode = EnvBooleanField( + env_name="SAFE_MODE", + help_text="Disables all installed apps.", + ) + logging_level = EnvChoiceField( + env_name="LOG_LEVEL", + initial=settings.LOG_LEVEL, + choices=LogLevelChoices.choices, + ) + + class Meta: + model = GeneralSettings + fields = ( + "server_name", + "server_description", + "public_url", + "logging_level", + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + + +class StylingSettingsForm(ModelForm): + head_html = CharField( + widget=AceWidget( + mode="html", + theme="twilight", + width="100%", + toolbar=False, + showprintmargin=False, + ), + label="Custom HTML (head)", + required=False, + ) + + class Meta: + model = StylingSettings + fields = "__all__" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + + +class ReferrerPolicy(TextChoices): + NO_REFERRER = "no-referrer" + NO_REFERRER_WHEN_DOWNGRADE = "no-referrer-when-downgrade" + ORIGIN = "origin" + ORIGIN_WHEN_CROSS_ORIGIN = "origin-when-cross-origin" + SAME_ORIGIN = "same-origin" + STRICT_ORIGIN = "strict-origin" + STRICT_ORIGIN_WHEN_CROSS_ORIGIN = "strict-origin-when-cross-origin" + UNSAFE_URL = "unsafe-url" + + +class WebserverSettingsForm(EnvFormMixin, ModelForm): + # Remember to change the default in settings.py if you change these defaults + base_url = EnvCharField( + env_name="BASE_URL", + label="Base URL", + help_text='Appears in all links. A value of "base-url" will result in example.com/base-url.', + ) + home_url = EnvCharField( + env_name="HOME_URL", + label="Home URL", + initial=get_home_url(False, False), + required=True, + help_text='Appears in homepage links. A value of "home-url" will result in example.com/base-url/home-url.', + ) + session_max_age = EnvIntegerField( + env_name="SESSION_COOKIE_AGE", + initial=settings.SESSION_COOKIE_AGE, + required=True, + help_text="Maximum time in seconds for a user session to last.", + ) + secure_referrer_policy = EnvChoiceField( + env_name="SECURE_REFERRER_POLICY", + initial=ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN, + choices=ReferrerPolicy.choices, + required=True, + help_text="The HTTP referrer policy to apply.", + ) + allowed_hosts = EnvCharField( + env_name="ALLOWED_HOSTS", + initial=", ".join(settings.ALLOWED_HOSTS), + required=True, + help_text="Comma separated list of IPs or domains the webserver is allowed to \ + serve (ex. example.com, 127.0.0.1). Wildcards (*) are allowed within the URLs.", + ) + allowed_forwarding_ips = EnvCharField( + env_name="ALLOWED_FORWARDING_IPS", + label="Allowed forwarding IPs", + initial=", ".join(settings.ALLOWED_FORWARDING_IPS), + required=False, + help_text="Comma separated list of IPs to trust with reverse proxy headers \ + (ex. 192.168.86.25, 10.0.0.51).", + ) + csrf_trusted_origins = EnvCharField( + env_name="CSRF_TRUSTED_ORIGINS", + label="CSRF trusted origins", + initial=", ".join(settings.CSRF_TRUSTED_ORIGINS), + help_text='Comma separated list of qualified URLs trusted for \ + \ + CSRF protection (ex. https://example.com). Wildcards (*) are allowed within the URLs.
If this field \ + is empty, URLs will be automatically generated based on "Allowed Domains".', + ) + rotate_secret_key = EnvBooleanField( + env_name="ROTATE_SECRET_KEY", + help_text="Invalidates user sessions upon every server restart.", + ) + host_ip = EnvCharField( + env_name="HOST_IP", + label="Host IP", + initial="0.0.0.0", + required=True, + help_text="Networking address to bind to. For all hosts, use 0.0.0.0", + ) + host_port = EnvIntegerField( + env_name="HOST_PORT", + initial=7575, + max_value=65535, + required=True, + help_text="Port number to bind to.", + ) + worker_processes = EnvIntegerField( + env_name="WEBSERVER_WORKERS", + initial=settings.WEBSERVER_WORKERS, + required=True, + help_text="Number of parallel processes for the webserver to use. Improves performance, but each worker uses ~80MB of RAM.", + ) + webserver_debug = EnvBooleanField( + env_name="WEBSERVER_DEBUG", + help_text="Enable extra webserver logging and checks.", + ) + + class Meta: + model = WebserverSettings + fields = [ + "base_url", + "home_url", + "host_ip", + "host_port", + "session_max_age", + "rotate_secret_key", + "secure_referrer_policy", + "allowed_hosts", + "allowed_forwarding_ips", + "csrf_trusted_origins", + "worker_processes", + "ssl_certificate", + "ssl_key", + "ssl_ca_certificate", + "webserver_debug", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + + +class EmailSettingsForm(ModelForm): + class Meta: + model = EmailSettings + fields = "__all__" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) diff --git a/conreq/_core/server_settings/migrations/0001_initial.py b/conreq/_core/server_settings/migrations/0001_initial.py new file mode 100644 index 00000000..2aa30595 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0001_initial.py @@ -0,0 +1,82 @@ +# Generated by Django 3.1.5 on 2021-01-16 11:38 + +import encrypted_fields.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="ConreqConfig", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("conreq_api_key", models.CharField(default="", max_length=100)), + ("conreq_secret_key", models.CharField(default="", max_length=100)), + ("conreq_app_name", models.CharField(default="Conreq", max_length=100)), + ("conreq_language", models.CharField(default="", max_length=100)), + ("conreq_app_logo", models.ImageField(upload_to="")), + ("conreq_app_url", models.URLField(default="")), + ("conreq_custom_css", models.URLField(default="")), + ("conreq_custom_js", models.URLField(default="")), + ("conreq_simple_posters", models.BooleanField(default=False)), + ("conreq_auto_resolve_issues", models.BooleanField(default=True)), + ("conreq_guest_login", models.BooleanField(default=False)), + ("conreq_dark_theme", models.BooleanField(default=False)), + ("sonarr_url", models.URLField(default="")), + ("sonarr_api_key", models.CharField(default="", max_length=100)), + ( + "sonarr_anime_quality_profile", + models.PositiveIntegerField(default=1), + ), + ("sonarr_anime_folder", models.FilePathField(default="")), + ("sonarr_tv_quality_profile", models.PositiveIntegerField(default=1)), + ("sonarr_tv_folder", models.FilePathField(default="")), + ("sonarr_enabled", models.BooleanField(default=False)), + ("sonarr_season_folders", models.BooleanField(default=True)), + ("radarr_url", models.URLField(default="")), + ("radarr_api_key", models.CharField(default="", max_length=100)), + ( + "radarr_anime_quality_profile", + models.PositiveIntegerField(default=1), + ), + ("radarr_anime_folder", models.FilePathField(default="")), + ( + "radarr_movies_quality_profile", + models.PositiveIntegerField(default=1), + ), + ("radarr_movies_folder", models.FilePathField(default="")), + ("radarr_enabled", models.BooleanField(default=False)), + ("email_smtp_server", models.URLField(default="")), + ("email_smtp_port", models.PositiveIntegerField(default=587)), + ( + "email_username", + encrypted_fields.fields.EncryptedCharField( + default="", max_length=100 + ), + ), + ( + "email_password", + encrypted_fields.fields.EncryptedCharField( + default="", max_length=100 + ), + ), + ("email_sender_name", models.CharField(default="", max_length=50)), + ("email_enable_tls", models.BooleanField(default=True)), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0002_auto_20210118_2004.py b/conreq/_core/server_settings/migrations/0002_auto_20210118_2004.py new file mode 100644 index 00000000..e71ac704 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0002_auto_20210118_2004.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.5 on 2021-01-19 04:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="radarr_anime_folder", + field=models.PositiveIntegerField(default=1), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_movies_folder", + field=models.PositiveIntegerField(default=1), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_anime_folder", + field=models.PositiveIntegerField(default=1), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_tv_folder", + field=models.PositiveIntegerField(default=1), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py b/conreq/_core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py new file mode 100644 index 00000000..5dc4b810 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.5 on 2021-01-19 08:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0002_auto_20210118_2004"), + ] + + operations = [ + migrations.AddField( + model_name="conreqconfig", + name="conreq_initialized", + field=models.BooleanField(default=False), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0004_auto_20210119_1742.py b/conreq/_core/server_settings/migrations/0004_auto_20210119_1742.py new file mode 100644 index 00000000..135ab202 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0004_auto_20210119_1742.py @@ -0,0 +1,91 @@ +# Generated by Django 3.1.5 on 2021-01-20 01:42 + +import encrypted_fields.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0003_conreqconfig_conreq_initialized"), + ] + + operations = [ + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_secret_key", + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_api_key", + field=models.CharField(blank=True, default="", max_length=100), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_app_logo", + field=models.ImageField(blank=True, upload_to=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_app_url", + field=models.URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_css", + field=models.URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_js", + field=models.URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_language", + field=models.CharField(default="en", max_length=100), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_password", + field=encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=100 + ), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_sender_name", + field=models.CharField(blank=True, default="", max_length=50), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_smtp_server", + field=models.URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_username", + field=encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=100 + ), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_api_key", + field=models.CharField(blank=True, default="", max_length=100), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_url", + field=models.URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_api_key", + field=models.CharField(blank=True, default="", max_length=100), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_url", + field=models.URLField(blank=True, default=""), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0005_auto_20210127_0107.py b/conreq/_core/server_settings/migrations/0005_auto_20210127_0107.py new file mode 100644 index 00000000..9b53aabe --- /dev/null +++ b/conreq/_core/server_settings/migrations/0005_auto_20210127_0107.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.5 on 2021-01-27 09:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0004_auto_20210119_1742"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_dark_theme", + field=models.BooleanField(default=True), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0006_auto_20210130_0236.py b/conreq/_core/server_settings/migrations/0006_auto_20210130_0236.py new file mode 100644 index 00000000..c81a602a --- /dev/null +++ b/conreq/_core/server_settings/migrations/0006_auto_20210130_0236.py @@ -0,0 +1,22 @@ +# Generated by Django 3.1.5 on 2021-01-30 10:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0005_auto_20210127_0107"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_css", + field=models.CharField(blank=True, default="", max_length=100), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_js", + field=models.CharField(blank=True, default="", max_length=100), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py b/conreq/_core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py new file mode 100644 index 00000000..461063bf --- /dev/null +++ b/conreq/_core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.5 on 2021-02-02 12:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0006_auto_20210130_0236"), + ] + + operations = [ + migrations.AddField( + model_name="conreqconfig", + name="conreq_http_header_auth", + field=models.BooleanField(default=False), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0008_auto_20210203_0053.py b/conreq/_core/server_settings/migrations/0008_auto_20210203_0053.py new file mode 100644 index 00000000..20171682 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0008_auto_20210203_0053.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.5 on 2021-02-03 08:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0007_conreqconfig_conreq_http_header_auth"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_simple_posters", + field=models.BooleanField(default=True), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0009_auto_20210204_1938.py b/conreq/_core/server_settings/migrations/0009_auto_20210204_1938.py new file mode 100644 index 00000000..d47f28f1 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0009_auto_20210204_1938.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.5 on 2021-02-05 03:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0008_auto_20210203_0053"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_app_url", + field=models.CharField(blank=True, default="", max_length=255), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_smtp_server", + field=models.CharField(blank=True, default="", max_length=255), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_url", + field=models.CharField(blank=True, default="", max_length=255), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_url", + field=models.CharField(blank=True, default="", max_length=255), + ), + ] diff --git a/conreq/core/server_settings/migrations/0010_auto_20210205_2326.py b/conreq/_core/server_settings/migrations/0010_auto_20210205_2326.py similarity index 76% rename from conreq/core/server_settings/migrations/0010_auto_20210205_2326.py rename to conreq/_core/server_settings/migrations/0010_auto_20210205_2326.py index a4f8c714..77b6133f 100644 --- a/conreq/core/server_settings/migrations/0010_auto_20210205_2326.py +++ b/conreq/_core/server_settings/migrations/0010_auto_20210205_2326.py @@ -1,11 +1,11 @@ # Generated by Django 3.1.5 on 2021-02-06 07:26 -import conreq.core.base.fields from django.db import migrations, models +import conreq._core.fields -class Migration(migrations.Migration): +class Migration(migrations.Migration): dependencies = [ ("server_settings", "0009_auto_20210204_1938"), ] @@ -19,11 +19,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="conreqconfig", name="radarr_url", - field=conreq.core.base.fields.ExtendedURLField(blank=True, default=""), + field=conreq._core.fields.HostnameOrURLField(blank=True, default=""), ), migrations.AlterField( model_name="conreqconfig", name="sonarr_url", - field=conreq.core.base.fields.ExtendedURLField(blank=True, default=""), + field=conreq._core.fields.HostnameOrURLField(blank=True, default=""), ), ] diff --git a/conreq/_core/server_settings/migrations/0011_auto_20210205_2343.py b/conreq/_core/server_settings/migrations/0011_auto_20210205_2343.py new file mode 100644 index 00000000..e75226ac --- /dev/null +++ b/conreq/_core/server_settings/migrations/0011_auto_20210205_2343.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.5 on 2021-02-06 07:43 + +from django.db import migrations +from django.db.models.fields import URLField + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0010_auto_20210205_2326"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_css", + field=URLField(blank=True, default=""), + ), + migrations.AlterField( + model_name="conreqconfig", + name="conreq_custom_js", + field=URLField(blank=True, default=""), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0012_auto_20210209_2144.py b/conreq/_core/server_settings/migrations/0012_auto_20210209_2144.py new file mode 100644 index 00000000..f19bf359 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0012_auto_20210209_2144.py @@ -0,0 +1,42 @@ +# Generated by Django 3.1.5 on 2021-02-10 05:44 + +import encrypted_fields.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0011_auto_20210205_2343"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="conreq_api_key", + field=models.CharField(blank=True, default="", max_length=255), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_password", + field=encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=255 + ), + ), + migrations.AlterField( + model_name="conreqconfig", + name="email_username", + field=encrypted_fields.fields.EncryptedCharField( + blank=True, default="", max_length=255 + ), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_api_key", + field=models.CharField(blank=True, default="", max_length=255), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_api_key", + field=models.CharField(blank=True, default="", max_length=255), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py b/conreq/_core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py new file mode 100644 index 00000000..c361e80c --- /dev/null +++ b/conreq/_core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.7 on 2021-03-13 09:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0012_auto_20210209_2144"), + ] + + operations = [ + migrations.AddField( + model_name="conreqconfig", + name="conreq_allow_tv_specials", + field=models.BooleanField(default=True), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0014_auto_20210313_0231.py b/conreq/_core/server_settings/migrations/0014_auto_20210313_0231.py new file mode 100644 index 00000000..73ed84aa --- /dev/null +++ b/conreq/_core/server_settings/migrations/0014_auto_20210313_0231.py @@ -0,0 +1,28 @@ +# Generated by Django 3.1.7 on 2021-03-13 10:31 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0013_conreqconfig_conreq_allow_tv_specials"), + ] + + operations = [ + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_app_logo", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_app_url", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_guest_login", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_language", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py b/conreq/_core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py new file mode 100644 index 00000000..17b5158f --- /dev/null +++ b/conreq/_core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py @@ -0,0 +1,16 @@ +# Generated by Django 3.1.7 on 2021-03-21 09:02 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0014_auto_20210313_0231"), + ] + + operations = [ + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_app_name", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0016_alter_conreqconfig_id.py b/conreq/_core/server_settings/migrations/0016_alter_conreqconfig_id.py new file mode 100644 index 00000000..a42b2aeb --- /dev/null +++ b/conreq/_core/server_settings/migrations/0016_alter_conreqconfig_id.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2 on 2021-04-13 05:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0015_remove_conreqconfig_conreq_app_name"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py b/conreq/_core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py new file mode 100644 index 00000000..5083d6cd --- /dev/null +++ b/conreq/_core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2 on 2021-04-26 04:01 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0016_alter_conreqconfig_id"), + ] + + operations = [ + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_dark_theme", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0018_auto_20210428_2039.py b/conreq/_core/server_settings/migrations/0018_auto_20210428_2039.py new file mode 100644 index 00000000..0c9b5db3 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0018_auto_20210428_2039.py @@ -0,0 +1,52 @@ +# Generated by Django 3.2 on 2021-04-29 03:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0017_remove_conreqconfig_conreq_dark_theme"), + ] + + operations = [ + migrations.AlterField( + model_name="conreqconfig", + name="radarr_anime_folder", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_anime_quality_profile", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_movies_folder", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="radarr_movies_quality_profile", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_anime_folder", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_anime_quality_profile", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_tv_folder", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="conreqconfig", + name="sonarr_tv_quality_profile", + field=models.PositiveIntegerField(default=0), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py b/conreq/_core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py new file mode 100644 index 00000000..23967157 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.2 on 2021-05-10 02:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0018_auto_20210428_2039"), + ] + + operations = [ + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_api_key", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0020_auto_20210824_0029.py b/conreq/_core/server_settings/migrations/0020_auto_20210824_0029.py new file mode 100644 index 00000000..53bf3262 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0020_auto_20210824_0029.py @@ -0,0 +1,144 @@ +# Generated by Django 3.2.6 on 2021-08-24 07:29 + +from django.db import migrations, models + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0019_remove_conreqconfig_conreq_api_key"), + ] + + operations = [ + migrations.RenameField( + model_name="conreqconfig", + old_name="conreq_custom_css", + new_name="custom_css_url", + ), + migrations.RenameField( + model_name="conreqconfig", + old_name="conreq_custom_js", + new_name="custom_js_url", + ), + migrations.RenameField( + model_name="conreqconfig", + old_name="conreq_initialized", + new_name="initialized", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_allow_tv_specials", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_auto_resolve_issues", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_http_header_auth", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="conreq_simple_posters", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_enable_tls", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_password", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_sender_name", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_smtp_port", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_smtp_server", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="email_username", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_anime_folder", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_anime_quality_profile", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_api_key", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_enabled", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_movies_folder", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_movies_quality_profile", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="radarr_url", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_anime_folder", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_anime_quality_profile", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_api_key", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_enabled", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_season_folders", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_tv_folder", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_tv_quality_profile", + ), + migrations.RemoveField( + model_name="conreqconfig", + name="sonarr_url", + ), + migrations.AddField( + model_name="conreqconfig", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField(blank=True, default=""), + ), + migrations.AddField( + model_name="conreqconfig", + name="custom_css", + field=models.TextField(blank=True, default=""), + ), + migrations.AddField( + model_name="conreqconfig", + name="custom_js", + field=models.TextField(blank=True, default=""), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0021_alter_conreqconfig_options.py b/conreq/_core/server_settings/migrations/0021_alter_conreqconfig_options.py new file mode 100644 index 00000000..872ecdb5 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0021_alter_conreqconfig_options.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.6 on 2021-08-24 08:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0020_auto_20210824_0029"), + ] + + operations = [ + migrations.AlterModelOptions( + name="conreqconfig", + options={ + "verbose_name": "Configuration", + "verbose_name_plural": "Configuration", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0022_rename_conreqconfig_serverconfig.py b/conreq/_core/server_settings/migrations/0022_rename_conreqconfig_serverconfig.py new file mode 100644 index 00000000..8acbb031 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0022_rename_conreqconfig_serverconfig.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.6 on 2021-08-25 15:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0021_alter_conreqconfig_options"), + ] + + operations = [ + migrations.RenameModel( + old_name="ConreqConfig", + new_name="ServerConfig", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0023_alter_serverconfig_options.py b/conreq/_core/server_settings/migrations/0023_alter_serverconfig_options.py new file mode 100644 index 00000000..f26e006e --- /dev/null +++ b/conreq/_core/server_settings/migrations/0023_alter_serverconfig_options.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.7 on 2021-09-19 08:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0022_rename_conreqconfig_serverconfig"), + ] + + operations = [ + migrations.AlterModelOptions( + name="serverconfig", + options={ + "verbose_name": "Server Settings", + "verbose_name_plural": "Server Settings", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0024_alter_serverconfig_options.py b/conreq/_core/server_settings/migrations/0024_alter_serverconfig_options.py new file mode 100644 index 00000000..b53658e4 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0024_alter_serverconfig_options.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.9 on 2021-11-23 23:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0023_alter_serverconfig_options"), + ] + + operations = [ + migrations.AlterModelOptions( + name="serverconfig", + options={ + "verbose_name": "Server settings", + "verbose_name_plural": "Server settings", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0025_serverconfig_rotate_secret_key.py b/conreq/_core/server_settings/migrations/0025_serverconfig_rotate_secret_key.py new file mode 100644 index 00000000..12f93cff --- /dev/null +++ b/conreq/_core/server_settings/migrations/0025_serverconfig_rotate_secret_key.py @@ -0,0 +1,20 @@ +# Generated by Django 4.0 on 2021-12-15 20:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0024_alter_serverconfig_options"), + ] + + operations = [ + migrations.AddField( + model_name="serverconfig", + name="rotate_secret_key", + field=models.BooleanField( + default=False, + help_text="Invalidates all active web sessions upon server restart.", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0026_serverconfig_server_description_and_more.py b/conreq/_core/server_settings/migrations/0026_serverconfig_server_description_and_more.py new file mode 100644 index 00000000..eaa2a208 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0026_serverconfig_server_description_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.0 on 2021-12-15 20:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0025_serverconfig_rotate_secret_key"), + ] + + operations = [ + migrations.AddField( + model_name="serverconfig", + name="server_description", + field=models.URLField( + blank=True, + help_text="This will be shown on search results and in hyperlink previews.", + ), + ), + migrations.AddField( + model_name="serverconfig", + name="server_name", + field=models.URLField(default="Conreq"), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0027_rename_serverconfig_generalsettings_and_more.py b/conreq/_core/server_settings/migrations/0027_rename_serverconfig_generalsettings_and_more.py new file mode 100644 index 00000000..1cabf830 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0027_rename_serverconfig_generalsettings_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.0 on 2021-12-15 20:59 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0026_serverconfig_server_description_and_more"), + ] + + operations = [ + migrations.RenameModel( + old_name="ServerConfig", + new_name="GeneralSettings", + ), + migrations.AlterModelOptions( + name="generalsettings", + options={ + "verbose_name": "General settings", + "verbose_name_plural": "General settings", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0028_remove_generalsettings_custom_css_and_more.py b/conreq/_core/server_settings/migrations/0028_remove_generalsettings_custom_css_and_more.py new file mode 100644 index 00000000..eb9dab36 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0028_remove_generalsettings_custom_css_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.0 on 2021-12-15 21:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0027_rename_serverconfig_generalsettings_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="generalsettings", + name="custom_css", + ), + migrations.RemoveField( + model_name="generalsettings", + name="custom_css_url", + ), + migrations.RemoveField( + model_name="generalsettings", + name="custom_js", + ), + migrations.RemoveField( + model_name="generalsettings", + name="custom_js_url", + ), + migrations.RemoveField( + model_name="generalsettings", + name="rotate_secret_key", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0029_stylingsettings_webserversettings.py b/conreq/_core/server_settings/migrations/0029_stylingsettings_webserversettings.py new file mode 100644 index 00000000..7e36a3a7 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0029_stylingsettings_webserversettings.py @@ -0,0 +1,60 @@ +# Generated by Django 4.0 on 2021-12-15 21:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0028_remove_generalsettings_custom_css_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="StylingSettings", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("custom_css_url", models.URLField(blank=True, default="")), + ("custom_js_url", models.URLField(blank=True, default="")), + ("custom_js", models.TextField(blank=True, default="")), + ("custom_css", models.TextField(blank=True, default="")), + ("initialized", models.BooleanField(default=False)), + ], + options={ + "verbose_name": "Styling settings", + "verbose_name_plural": "Styling settings", + }, + ), + migrations.CreateModel( + name="WebserverSettings", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "rotate_secret_key", + models.BooleanField( + default=False, + help_text="Invalidates all active web sessions upon server restart.", + ), + ), + ], + options={ + "verbose_name": "Webserver settings", + "verbose_name_plural": "Webserver settings", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0030_stylingsettings_accent_color_and_more.py b/conreq/_core/server_settings/migrations/0030_stylingsettings_accent_color_and_more.py new file mode 100644 index 00000000..9e1cab07 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0030_stylingsettings_accent_color_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.0 on 2021-12-15 21:14 + +import colorfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0029_stylingsettings_webserversettings"), + ] + + operations = [ + migrations.AddField( + model_name="stylingsettings", + name="accent_color", + field=colorfield.fields.ColorField( + default="#FF0000", max_length=18, samples=None + ), + ), + migrations.AlterField( + model_name="generalsettings", + name="server_name", + field=models.URLField( + default="Conreq", + help_text="This will be shown on the page title, search results, and in hyperlink previews.", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0031_alter_stylingsettings_accent_color.py b/conreq/_core/server_settings/migrations/0031_alter_stylingsettings_accent_color.py new file mode 100644 index 00000000..19b1278c --- /dev/null +++ b/conreq/_core/server_settings/migrations/0031_alter_stylingsettings_accent_color.py @@ -0,0 +1,20 @@ +# Generated by Django 4.0 on 2021-12-15 21:15 + +import colorfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0030_stylingsettings_accent_color_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="stylingsettings", + name="accent_color", + field=colorfield.fields.ColorField( + default="258a6d", max_length=18, samples=None + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0032_alter_generalsettings_app_store_url.py b/conreq/_core/server_settings/migrations/0032_alter_generalsettings_app_store_url.py new file mode 100644 index 00000000..91fbc83e --- /dev/null +++ b/conreq/_core/server_settings/migrations/0032_alter_generalsettings_app_store_url.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0 on 2021-12-15 21:20 + +from django.db import migrations + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0031_alter_stylingsettings_accent_color"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField( + blank=True, help_text="Set automatically on Conreq updates." + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0033_alter_generalsettings_app_store_url.py b/conreq/_core/server_settings/migrations/0033_alter_generalsettings_app_store_url.py new file mode 100644 index 00000000..28f40ac0 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0033_alter_generalsettings_app_store_url.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0 on 2021-12-15 21:49 + +from django.db import migrations + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0032_alter_generalsettings_app_store_url"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField( + blank=True, help_text="Changes automatically on Conreq updates." + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0034_alter_generalsettings_server_description_and_more.py b/conreq/_core/server_settings/migrations/0034_alter_generalsettings_server_description_and_more.py new file mode 100644 index 00000000..c5b9de8c --- /dev/null +++ b/conreq/_core/server_settings/migrations/0034_alter_generalsettings_server_description_and_more.py @@ -0,0 +1,30 @@ +# Generated by Django 4.0 on 2021-12-15 22:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0033_alter_generalsettings_app_store_url"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="server_description", + field=models.CharField( + blank=True, + help_text="This will be shown on search results and in hyperlink previews.", + max_length=70, + ), + ), + migrations.AlterField( + model_name="generalsettings", + name="server_name", + field=models.CharField( + default="Conreq", + help_text="This will be shown on the page title, search results, and in hyperlink previews.", + max_length=60, + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0035_remove_stylingsettings_initialized.py b/conreq/_core/server_settings/migrations/0035_remove_stylingsettings_initialized.py new file mode 100644 index 00000000..dea36bf6 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0035_remove_stylingsettings_initialized.py @@ -0,0 +1,16 @@ +# Generated by Django 4.0 on 2021-12-17 01:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0034_alter_generalsettings_server_description_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="stylingsettings", + name="initialized", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0036_remove_generalsettings_initialized.py b/conreq/_core/server_settings/migrations/0036_remove_generalsettings_initialized.py new file mode 100644 index 00000000..a16af56d --- /dev/null +++ b/conreq/_core/server_settings/migrations/0036_remove_generalsettings_initialized.py @@ -0,0 +1,16 @@ +# Generated by Django 4.0 on 2021-12-20 19:08 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0035_remove_stylingsettings_initialized"), + ] + + operations = [ + migrations.RemoveField( + model_name="generalsettings", + name="initialized", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0037_delete_webserversettings.py b/conreq/_core/server_settings/migrations/0037_delete_webserversettings.py new file mode 100644 index 00000000..dc64818e --- /dev/null +++ b/conreq/_core/server_settings/migrations/0037_delete_webserversettings.py @@ -0,0 +1,15 @@ +# Generated by Django 4.0.1 on 2022-01-06 06:54 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0036_remove_generalsettings_initialized"), + ] + + operations = [ + migrations.DeleteModel( + name="WebserverSettings", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0038_alter_generalsettings_app_store_url_and_more.py b/conreq/_core/server_settings/migrations/0038_alter_generalsettings_app_store_url_and_more.py new file mode 100644 index 00000000..29fb5e1e --- /dev/null +++ b/conreq/_core/server_settings/migrations/0038_alter_generalsettings_app_store_url_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 4.0.1 on 2022-01-06 19:18 + +from django.db import migrations, models + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0037_delete_webserversettings"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField( + blank=True, + help_text="Changes automatically on Conreq updates.", + verbose_name="App store URL", + ), + ), + migrations.AlterField( + model_name="stylingsettings", + name="custom_css", + field=models.TextField( + blank=True, default="", verbose_name="Custom JavaScript" + ), + ), + migrations.AlterField( + model_name="stylingsettings", + name="custom_css_url", + field=models.URLField( + blank=True, default="", verbose_name="Custom CSS URL" + ), + ), + migrations.AlterField( + model_name="stylingsettings", + name="custom_js", + field=models.TextField(blank=True, default="", verbose_name="Custom CSS"), + ), + migrations.AlterField( + model_name="stylingsettings", + name="custom_js_url", + field=models.URLField( + blank=True, default="", verbose_name="Custom JavaScript URL" + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0039_webserversettings.py b/conreq/_core/server_settings/migrations/0039_webserversettings.py new file mode 100644 index 00000000..1a27c980 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0039_webserversettings.py @@ -0,0 +1,46 @@ +# Generated by Django 4.0.1 on 2022-01-06 23:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0038_alter_generalsettings_app_store_url_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="WebserverSettings", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "ssl_ca_certificate", + models.FileField( + blank=True, upload_to="", verbose_name="SSL CA certificate" + ), + ), + ( + "ssl_certificate", + models.FileField( + blank=True, upload_to="", verbose_name="SSL certificate" + ), + ), + ( + "ssl_key", + models.FileField(blank=True, upload_to="", verbose_name="SSL key"), + ), + ], + options={ + "verbose_name": "Webserver settings", + "verbose_name_plural": "Webserver settings", + }, + ), + ] diff --git a/conreq/_core/server_settings/migrations/0040_generalsettings_public_url.py b/conreq/_core/server_settings/migrations/0040_generalsettings_public_url.py new file mode 100644 index 00000000..215b6e67 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0040_generalsettings_public_url.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.1 on 2022-01-07 07:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0039_webserversettings"), + ] + + operations = [ + migrations.AddField( + model_name="generalsettings", + name="public_url", + field=models.URLField( + blank=True, + help_text="Can be used by apps to construct meaningful URLs, such as in emails.", + verbose_name="Public URL", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0041_alter_stylingsettings_custom_css_url_and_more.py b/conreq/_core/server_settings/migrations/0041_alter_stylingsettings_custom_css_url_and_more.py new file mode 100644 index 00000000..0a6424ac --- /dev/null +++ b/conreq/_core/server_settings/migrations/0041_alter_stylingsettings_custom_css_url_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.0.1 on 2022-01-08 01:43 + +from django.db import migrations + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0040_generalsettings_public_url"), + ] + + operations = [ + migrations.AlterField( + model_name="stylingsettings", + name="custom_css_url", + field=conreq._core.fields.URLOrRelativeURLField( + blank=True, default="", verbose_name="Custom CSS URL" + ), + ), + migrations.AlterField( + model_name="stylingsettings", + name="custom_js_url", + field=conreq._core.fields.URLOrRelativeURLField( + blank=True, default="", verbose_name="Custom JavaScript URL" + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0042_remove_stylingsettings_custom_css_and_more.py b/conreq/_core/server_settings/migrations/0042_remove_stylingsettings_custom_css_and_more.py new file mode 100644 index 00000000..b55d1f80 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0042_remove_stylingsettings_custom_css_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.0.1 on 2022-01-08 02:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0041_alter_stylingsettings_custom_css_url_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="stylingsettings", + name="custom_css", + ), + migrations.RemoveField( + model_name="stylingsettings", + name="custom_js", + ), + migrations.AddField( + model_name="stylingsettings", + name="custom_html", + field=models.TextField( + blank=True, + help_text="Contents within this textbox are put into the HTML Head.", + verbose_name="Custom HTML", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0043_alter_stylingsettings_custom_html.py b/conreq/_core/server_settings/migrations/0043_alter_stylingsettings_custom_html.py new file mode 100644 index 00000000..90b2dc36 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0043_alter_stylingsettings_custom_html.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.1 on 2022-01-08 02:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0042_remove_stylingsettings_custom_css_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="stylingsettings", + name="custom_html", + field=models.TextField(blank=True, verbose_name="Custom HTML (head)"), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0044_remove_stylingsettings_custom_css_url_and_more.py b/conreq/_core/server_settings/migrations/0044_remove_stylingsettings_custom_css_url_and_more.py new file mode 100644 index 00000000..4a2de266 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0044_remove_stylingsettings_custom_css_url_and_more.py @@ -0,0 +1,50 @@ +# Generated by Django 4.0.1 on 2022-01-08 03:50 + +import colorfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0043_alter_stylingsettings_custom_html"), + ] + + operations = [ + migrations.RemoveField( + model_name="stylingsettings", + name="custom_css_url", + ), + migrations.RemoveField( + model_name="stylingsettings", + name="custom_js_url", + ), + migrations.AlterField( + model_name="generalsettings", + name="server_description", + field=models.CharField( + blank=True, + help_text="This will be shown on search results and hyperlink previews.", + max_length=70, + ), + ), + migrations.AlterField( + model_name="generalsettings", + name="server_name", + field=models.CharField( + default="Conreq", + help_text="This will be shown on the page title, search results, and hyperlink previews.", + max_length=60, + ), + ), + migrations.AlterField( + model_name="stylingsettings", + name="accent_color", + field=colorfield.fields.ColorField( + default="258a6d", + help_text="Default: #258a6d", + image_field=None, + max_length=18, + samples=None, + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0045_rename_custom_html_stylingsettings_head_html.py b/conreq/_core/server_settings/migrations/0045_rename_custom_html_stylingsettings_head_html.py new file mode 100644 index 00000000..5491c478 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0045_rename_custom_html_stylingsettings_head_html.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.1 on 2022-01-08 03:58 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0044_remove_stylingsettings_custom_css_url_and_more"), + ] + + operations = [ + migrations.RenameField( + model_name="stylingsettings", + old_name="custom_html", + new_name="head_html", + ), + ] diff --git a/conreq/_core/server_settings/migrations/0046_alter_stylingsettings_accent_color.py b/conreq/_core/server_settings/migrations/0046_alter_stylingsettings_accent_color.py new file mode 100644 index 00000000..2c356d31 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0046_alter_stylingsettings_accent_color.py @@ -0,0 +1,24 @@ +# Generated by Django 4.0.2 on 2022-02-12 01:05 + +import colorfield.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0045_rename_custom_html_stylingsettings_head_html"), + ] + + operations = [ + migrations.AlterField( + model_name="stylingsettings", + name="accent_color", + field=colorfield.fields.ColorField( + default="#258A6D", + help_text="Default: #258a6d", + image_field=None, + max_length=18, + samples=None, + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0047_alter_generalsettings_app_store_url_and_more.py b/conreq/_core/server_settings/migrations/0047_alter_generalsettings_app_store_url_and_more.py new file mode 100644 index 00000000..eb4c32de --- /dev/null +++ b/conreq/_core/server_settings/migrations/0047_alter_generalsettings_app_store_url_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.0.4 on 2022-06-22 02:28 + +from django.db import migrations, models + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0046_alter_stylingsettings_accent_color"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField( + blank=True, + help_text="Set this to override the default app store.", + verbose_name="Custom app store URL", + ), + ), + migrations.AlterField( + model_name="generalsettings", + name="public_url", + field=models.URLField( + blank=True, + help_text="Can be used by apps to construct meaningful URLs, such as in emails or invite links.", + verbose_name="Public URL", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0048_alter_generalsettings_app_store_url.py b/conreq/_core/server_settings/migrations/0048_alter_generalsettings_app_store_url.py new file mode 100644 index 00000000..24438939 --- /dev/null +++ b/conreq/_core/server_settings/migrations/0048_alter_generalsettings_app_store_url.py @@ -0,0 +1,23 @@ +# Generated by Django 4.0.6 on 2022-07-29 02:11 + +from django.db import migrations + +import conreq._core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0047_alter_generalsettings_app_store_url_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="generalsettings", + name="app_store_url", + field=conreq._core.fields.HostnameOrURLField( + blank=True, + help_text="Set this to override the default app store.", + verbose_name="App store URL", + ), + ), + ] diff --git a/conreq/_core/server_settings/migrations/0049_remove_generalsettings_app_store_url.py b/conreq/_core/server_settings/migrations/0049_remove_generalsettings_app_store_url.py new file mode 100644 index 00000000..0fa3266c --- /dev/null +++ b/conreq/_core/server_settings/migrations/0049_remove_generalsettings_app_store_url.py @@ -0,0 +1,16 @@ +# Generated by Django 4.2 on 2023-05-04 08:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("server_settings", "0048_alter_generalsettings_app_store_url"), + ] + + operations = [ + migrations.RemoveField( + model_name="generalsettings", + name="app_store_url", + ), + ] diff --git a/conreq/core/search/__init__.py b/conreq/_core/server_settings/migrations/__init__.py similarity index 100% rename from conreq/core/search/__init__.py rename to conreq/_core/server_settings/migrations/__init__.py diff --git a/conreq/_core/server_settings/models.py b/conreq/_core/server_settings/models.py new file mode 100644 index 00000000..ddf34ef4 --- /dev/null +++ b/conreq/_core/server_settings/models.py @@ -0,0 +1,66 @@ +from colorfield.fields import ColorField +from django.db import models +from django.db.models.fields import CharField, URLField +from solo.models import SingletonModel + + +class GeneralSettings(SingletonModel): + def __str__(self): + return "General Settings" + + class Meta: + verbose_name = "General settings" + verbose_name_plural = verbose_name + + server_name = CharField( + default="Conreq", + max_length=60, + help_text="This will be shown on the page title, search results, and hyperlink previews.", + ) + server_description = CharField( + blank=True, + max_length=70, + help_text="This will be shown on search results and hyperlink previews.", + ) + public_url = URLField( + help_text="Can be used by apps to construct meaningful URLs, such as in emails or invite links.", + verbose_name="Public URL", + blank=True, + ) + + +class StylingSettings(SingletonModel): + def __str__(self): + return "Styling Settings" + + class Meta: + verbose_name = "Styling settings" + verbose_name_plural = verbose_name + + accent_color = ColorField(default="#258A6D", help_text="Default: #258a6d") + head_html = models.TextField( + verbose_name="Custom HTML (head)", + blank=True, + ) + + +class WebserverSettings(SingletonModel): + def __str__(self): + return "Webserver Settings" + + class Meta: + verbose_name = "Webserver settings" + verbose_name_plural = verbose_name + + ssl_ca_certificate = models.FileField( + verbose_name="SSL CA certificate", + blank=True, + ) + ssl_certificate = models.FileField( + verbose_name="SSL certificate", + blank=True, + ) + ssl_key = models.FileField( + verbose_name="SSL key", + blank=True, + ) diff --git a/conreq/_core/server_settings/views.py b/conreq/_core/server_settings/views.py new file mode 100644 index 00000000..52657b78 --- /dev/null +++ b/conreq/_core/server_settings/views.py @@ -0,0 +1,45 @@ +from django.contrib.auth.decorators import user_passes_test +from django.utils.decorators import method_decorator + +from conreq._core.email.models import EmailSettings +from conreq._core.server_settings.forms import ( + EmailSettingsForm, + GeneralSettingsForm, + StylingSettingsForm, + WebserverSettingsForm, +) +from conreq._core.server_settings.models import ( + GeneralSettings, + StylingSettings, + WebserverSettings, +) +from conreq._core.views import SingletonUpdateView + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class GeneralSettingsView(SingletonUpdateView): + form_class = GeneralSettingsForm + model = GeneralSettings + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class StylingSettingsView(SingletonUpdateView): + form_class = StylingSettingsForm + model = StylingSettings + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class WebserverSettingsView(SingletonUpdateView): + form_class = WebserverSettingsForm + model = WebserverSettings + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["success_message"] = "Restart for changes to take effect." + return context + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class EmailSettingsView(SingletonUpdateView): + form_class = EmailSettingsForm + model = EmailSettings diff --git a/conreq/core/search/migrations/__init__.py b/conreq/_core/sign_in/__init__.py similarity index 100% rename from conreq/core/search/migrations/__init__.py rename to conreq/_core/sign_in/__init__.py diff --git a/conreq/_core/sign_in/apps.py b/conreq/_core/sign_in/apps.py new file mode 100644 index 00000000..880f0397 --- /dev/null +++ b/conreq/_core/sign_in/apps.py @@ -0,0 +1,10 @@ +from django.apps import AppConfig + +from conreq.utils.modules import load + + +class SignInConfig(AppConfig): + name = "conreq._core.sign_in" + + def ready(self): + load("views") diff --git a/conreq/_core/sign_in/templates/conreq/sign_in.html b/conreq/_core/sign_in/templates/conreq/sign_in.html new file mode 100644 index 00000000..739d441c --- /dev/null +++ b/conreq/_core/sign_in/templates/conreq/sign_in.html @@ -0,0 +1,47 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + +{% block extend_head %} + +{% endblock %} + +{% block title %} +Sign In +{% endblock %} + +{% block content %} + +
+ +
+ +
+ {% csrf_token %} + + {{ form.non_field_errors }} + + + + + + +
+ + +{% endblock %} diff --git a/conreq/_core/sign_in/views.py b/conreq/_core/sign_in/views.py new file mode 100644 index 00000000..db71dfc9 --- /dev/null +++ b/conreq/_core/sign_in/views.py @@ -0,0 +1,7 @@ +from django.contrib.auth.views import LoginView + +from conreq import config + + +def sign_in(request): + return LoginView.as_view(template_name=config.templates.sign_in)(request) diff --git a/conreq/core/server_settings/__init__.py b/conreq/_core/sign_out/__init__.py similarity index 100% rename from conreq/core/server_settings/__init__.py rename to conreq/_core/sign_out/__init__.py diff --git a/conreq/_core/sign_out/components.py b/conreq/_core/sign_out/components.py new file mode 100644 index 00000000..24af0af9 --- /dev/null +++ b/conreq/_core/sign_out/components.py @@ -0,0 +1,7 @@ +from django.urls import reverse +from reactpy import component, html + + +@component +def sign_out(): + return html.script(f"location.href = '{reverse('conreq:sign_out')}';") diff --git a/conreq/core/server_settings/migrations/__init__.py b/conreq/_core/sign_up/__init__.py similarity index 100% rename from conreq/core/server_settings/migrations/__init__.py rename to conreq/_core/sign_up/__init__.py diff --git a/conreq/_core/sign_up/admin.py b/conreq/_core/sign_up/admin.py new file mode 100644 index 00000000..b2340545 --- /dev/null +++ b/conreq/_core/sign_up/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin + +from conreq._core.sign_up.models import InviteCode + + +# Register your models here. +@admin.register(InviteCode) +class InviteCodes(admin.ModelAdmin): + list_display = ("created_at", "email", "code", "is_valid") diff --git a/conreq/_core/sign_up/apps.py b/conreq/_core/sign_up/apps.py new file mode 100644 index 00000000..35482672 --- /dev/null +++ b/conreq/_core/sign_up/apps.py @@ -0,0 +1,12 @@ +from django.apps import AppConfig + +from conreq.utils.modules import load + + +class SignUpConfig(AppConfig): + name = "conreq._core.sign_up" + verbose_name = "Registration" + + def ready(self): + load("views") + load("components") diff --git a/conreq/_core/sign_up/components.py b/conreq/_core/sign_up/components.py new file mode 100644 index 00000000..5d78746f --- /dev/null +++ b/conreq/_core/sign_up/components.py @@ -0,0 +1,28 @@ +from channels.db import database_sync_to_async +from reactpy import component, hooks, html + +from conreq._core.sign_up.models import InviteCode + + +@component +def lock_invite_code(code_id: int): + locked, set_locked = hooks.use_state(False) + + @database_sync_to_async + def _lock_invite_code(_event): + code = InviteCode.objects.get(id=code_id) + code.locked = True + code.full_clean() + code.save() + set_locked(True) + + return ( + None + if locked + else html.button( + {"class_name": "btn btn-sm", "on_click": _lock_invite_code}, + html.span( + {"class_name": "glyphicon glyphicon-lock", "aria-hidden": "true"} + ), + ) + ) diff --git a/conreq/core/sign_up/forms.py b/conreq/_core/sign_up/forms.py similarity index 100% rename from conreq/core/sign_up/forms.py rename to conreq/_core/sign_up/forms.py diff --git a/conreq/_core/sign_up/migrations/0001_initial.py b/conreq/_core/sign_up/migrations/0001_initial.py new file mode 100644 index 00000000..ca6bae13 --- /dev/null +++ b/conreq/_core/sign_up/migrations/0001_initial.py @@ -0,0 +1,57 @@ +# Generated by Django 3.2.9 on 2021-11-23 05:54 + +import uuid + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + +import conreq._core.sign_up.models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="InviteCode", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "code", + models.UUIDField(default=uuid.uuid4, editable=False, unique=True), + ), + ("username", models.CharField(max_length=100)), + ("email", models.EmailField(max_length=254)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "expires_at", + models.DateTimeField( + default=conreq._core.sign_up.models._expiration + ), + ), + ("used_at", models.DateTimeField(blank=True, null=True)), + ( + "used_by", + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/conreq/_core/sign_up/migrations/0002_alter_invitecode_expires_at.py b/conreq/_core/sign_up/migrations/0002_alter_invitecode_expires_at.py new file mode 100644 index 00000000..3e12298a --- /dev/null +++ b/conreq/_core/sign_up/migrations/0002_alter_invitecode_expires_at.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.9 on 2021-11-23 07:29 + +from django.db import migrations, models + +import conreq._core.sign_up.models + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="invitecode", + name="expires_at", + field=models.DateTimeField( + default=conreq._core.sign_up.models._expiration, null=True + ), + ), + ] diff --git a/conreq/_core/sign_up/migrations/0003_alter_invitecode_code.py b/conreq/_core/sign_up/migrations/0003_alter_invitecode_code.py new file mode 100644 index 00000000..181d2959 --- /dev/null +++ b/conreq/_core/sign_up/migrations/0003_alter_invitecode_code.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.9 on 2021-11-23 07:44 + +import uuid + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0002_alter_invitecode_expires_at"), + ] + + operations = [ + migrations.AlterField( + model_name="invitecode", + name="code", + field=models.CharField( + default=uuid.uuid4, editable=False, max_length=30, unique=True + ), + ), + ] diff --git a/conreq/_core/sign_up/migrations/0004_alter_invitecode_used_by.py b/conreq/_core/sign_up/migrations/0004_alter_invitecode_used_by.py new file mode 100644 index 00000000..37177f3e --- /dev/null +++ b/conreq/_core/sign_up/migrations/0004_alter_invitecode_used_by.py @@ -0,0 +1,24 @@ +# Generated by Django 4.0 on 2022-01-02 02:45 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ("sign_up", "0003_alter_invitecode_code"), + ] + + operations = [ + migrations.AlterField( + model_name="invitecode", + name="used_by", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="auth.user", + ), + ), + ] diff --git a/conreq/_core/sign_up/migrations/0005_alter_invitecode_code.py b/conreq/_core/sign_up/migrations/0005_alter_invitecode_code.py new file mode 100644 index 00000000..d6a2e590 --- /dev/null +++ b/conreq/_core/sign_up/migrations/0005_alter_invitecode_code.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0 on 2022-01-02 02:48 + +import uuid + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0004_alter_invitecode_used_by"), + ] + + operations = [ + migrations.AlterField( + model_name="invitecode", + name="code", + field=models.CharField( + default=uuid.uuid4, editable=False, max_length=50, unique=True + ), + ), + ] diff --git a/conreq/_core/sign_up/migrations/0006_rename_username_invitecode_name.py b/conreq/_core/sign_up/migrations/0006_rename_username_invitecode_name.py new file mode 100644 index 00000000..79403d3c --- /dev/null +++ b/conreq/_core/sign_up/migrations/0006_rename_username_invitecode_name.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.3 on 2022-04-08 21:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0005_alter_invitecode_code"), + ] + + operations = [ + migrations.RenameField( + model_name="invitecode", + old_name="username", + new_name="name", + ), + ] diff --git a/conreq/_core/sign_up/migrations/0007_invitecode_locked.py b/conreq/_core/sign_up/migrations/0007_invitecode_locked.py new file mode 100644 index 00000000..4148c0b5 --- /dev/null +++ b/conreq/_core/sign_up/migrations/0007_invitecode_locked.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.6 on 2022-07-08 00:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0006_rename_username_invitecode_name"), + ] + + operations = [ + migrations.AddField( + model_name="invitecode", + name="locked", + field=models.BooleanField(default=False), + ), + ] diff --git a/conreq/_core/sign_up/migrations/0008_alter_invitecode_expires_at.py b/conreq/_core/sign_up/migrations/0008_alter_invitecode_expires_at.py new file mode 100644 index 00000000..d595ca71 --- /dev/null +++ b/conreq/_core/sign_up/migrations/0008_alter_invitecode_expires_at.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.3 on 2022-12-05 16:34 + +from django.db import migrations, models + +import conreq._core.sign_up.models + + +class Migration(migrations.Migration): + dependencies = [ + ("sign_up", "0007_invitecode_locked"), + ] + + operations = [ + migrations.AlterField( + model_name="invitecode", + name="expires_at", + field=models.DateTimeField(default=conreq._core.sign_up.models._expiration), + ), + ] diff --git a/conreq/core/sign_up/__init__.py b/conreq/_core/sign_up/migrations/__init__.py similarity index 100% rename from conreq/core/sign_up/__init__.py rename to conreq/_core/sign_up/migrations/__init__.py diff --git a/conreq/_core/sign_up/models.py b/conreq/_core/sign_up/models.py new file mode 100644 index 00000000..58884665 --- /dev/null +++ b/conreq/_core/sign_up/models.py @@ -0,0 +1,50 @@ +import uuid +from datetime import timedelta + +from django.contrib.auth import get_user_model +from django.db import models +from django.utils import timezone + + +def _expiration(): + return timezone.now() + timedelta(weeks=2) + + +class InviteCode(models.Model): + def __str__(self): + return str(self.code) + + code = models.CharField( + default=uuid.uuid4, editable=False, unique=True, max_length=50 + ) + name = models.CharField(max_length=100) + email = models.EmailField() + + created_at = models.DateTimeField(auto_now_add=True) + expires_at = models.DateTimeField(default=_expiration) + used_at = models.DateTimeField(blank=True, null=True) + locked = models.BooleanField(default=False) + + used_by = models.OneToOneField( + get_user_model(), on_delete=models.SET_NULL, blank=True, null=True + ) + + @property + def is_expired(self): + """Checks if the code has expired.""" + return timezone.now() > self.expires_at + + @property + def is_used(self): + """Checks if the code has been used.""" + return self.used_by is not None or self.used_at is not None + + @property + def is_locked(self): + """Checks if the code has been used.""" + return self.locked + + @property + def is_valid(self): + """Checks if the code is not used, expired, or locked.""" + return not self.is_expired and not self.is_used and not self.is_locked diff --git a/conreq/_core/sign_up/templates/conreq/sign_up.html b/conreq/_core/sign_up/templates/conreq/sign_up.html new file mode 100644 index 00000000..fc9b3cc0 --- /dev/null +++ b/conreq/_core/sign_up/templates/conreq/sign_up.html @@ -0,0 +1,41 @@ +{% extends 'conreq/centered_box.html' %} +{% load static %} + + +{% block title %} +Sign Up +{% endblock %} + +{% block content %} +
+ +
+ + +

REGISTRATION

+

Create your new {{ GeneralSettings.server_name }} account!

+ +
+ {% csrf_token %} + + {{ form.email.errors }} + + + {{ form.username.errors }} + + + {{ form.password2.errors }} + + + + + +
+{% endblock %} diff --git a/conreq/_core/sign_up/urls.py b/conreq/_core/sign_up/urls.py new file mode 100644 index 00000000..af5cfc14 --- /dev/null +++ b/conreq/_core/sign_up/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from conreq.config.wrappers import views + +urlpatterns = [ + path("", views.sign_up, name="sign_up"), + path("/", views.sign_up, name="sign_up_invite"), +] diff --git a/conreq/_core/sign_up/views.py b/conreq/_core/sign_up/views.py new file mode 100644 index 00000000..29788a76 --- /dev/null +++ b/conreq/_core/sign_up/views.py @@ -0,0 +1,59 @@ +from django.conf import settings +from django.contrib.auth import authenticate, login +from django.shortcuts import redirect, render +from django.utils import timezone + +from conreq import config +from conreq._core.sign_up.forms import UserForm +from conreq._core.sign_up.models import InviteCode + +LOGIN_REDIRECT_URL = getattr(settings, "LOGIN_REDIRECT_URL") + + +# TODO: Add page for invalid invite codes +def sign_up(request, invite_code=None): + # No invite code was provided + if not invite_code: + return redirect("conreq:landing") + + # Check if the invite code is valid + try: + code: InviteCode = InviteCode.objects.get(code=invite_code) + if not code.is_valid: + # TODO: This should give a meaningful error message + return redirect("conreq:landing") + except ( + InviteCode.DoesNotExist, # pylint: disable=no-member + InviteCode.MultipleObjectsReturned, # pylint: disable=no-member + ): + return redirect("conreq:landing") + + # User submitted the registration form + if request.method == "POST": + # Check if form submission is clean + form = UserForm(request.POST) + + # Submission wasn't valid, so return the error codes + if not form.is_valid(): + return render( + request, + config.templates.sign_up, + {"form": form, "initial_email": code.email}, + ) + + # Create and login the user + form.full_clean() + form.save() + user = authenticate( + username=form.cleaned_data.get("username"), + password=form.cleaned_data.get("password1"), + ) + code.used_by = user # type: ignore + code.used_at = timezone.now() + code.full_clean() + code.save() + login(request, user) + return redirect(LOGIN_REDIRECT_URL) + + # User needs to fill out registration form + return render(request, config.templates.sign_up, {"initial_email": code.email}) diff --git a/conreq/core/sign_up/migrations/__init__.py b/conreq/_core/user_management/__init__.py similarity index 100% rename from conreq/core/sign_up/migrations/__init__.py rename to conreq/_core/user_management/__init__.py diff --git a/conreq/_core/user_management/apps.py b/conreq/_core/user_management/apps.py new file mode 100644 index 00000000..bd2cfdfe --- /dev/null +++ b/conreq/_core/user_management/apps.py @@ -0,0 +1,19 @@ +from django.apps import AppConfig +from reactpy_django.utils import register_iframe + +from conreq.utils.modules import load + + +class ManageUsersConfig(AppConfig): + name = "conreq._core.user_management" + verbose_name = "User Management" + + def ready(self): + from . import views + + load("components") + register_iframe(views.EditUserView) + register_iframe(views.DeleteUserView) + register_iframe(views.manage_users) + register_iframe(views.manage_invites) + register_iframe(views.CreateInvite) diff --git a/conreq/_core/user_management/components.py b/conreq/_core/user_management/components.py new file mode 100644 index 00000000..4e599b24 --- /dev/null +++ b/conreq/_core/user_management/components.py @@ -0,0 +1,143 @@ +from django.urls import reverse +from reactpy import component, hooks, html +from reactpy_django.components import view_to_iframe +from reactpy_django.decorators import user_passes_test +from reactpy_django.hooks import use_mutation, use_scope + +from conreq import config +from conreq._core.components import tabbed_viewport +from conreq._core.sign_up.models import InviteCode +from conreq._core.user_management import views + +# TODO: Create SimpleTable and SimpleForm that use Conreq templates +# TODO: Figure out some way to integrate user invites into this + +edit_user_vtc = view_to_iframe(views.EditUserView) +delete_user_vtc = view_to_iframe(views.DeleteUserView) +manage_users_vtc = view_to_iframe(views.manage_users) +manage_invites_vtc = view_to_iframe(views.manage_invites) +create_invite_vtc = view_to_iframe(views.CreateInvite) + + +@user_passes_test(lambda user: user.is_staff) +@component +def edit_user(): + return edit_user_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def delete_user(): + return delete_user_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def manage_users(): + return manage_users_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def manage_invites(): + return manage_invites_vtc() + + +@user_passes_test(lambda user: user.is_staff) +@component +def create_invite(): + return create_invite_vtc() + + +def _send_email_invite(invite_code: str, scope: dict): + # pylint: disable=import-outside-toplevel + from conreq._core.server_settings.models import GeneralSettings + from conreq.app.services.email import Email, send_email + + general_settings: GeneralSettings = GeneralSettings.get_solo() + origin = general_settings.public_url or get_origin_header(scope) + + invite = InviteCode.objects.get(code=invite_code) + path = reverse("conreq:sign_up_invite", kwargs={"invite_code": invite.code}) + + # TODO: Add email template for user invites. Probably have configuration settings within the user management subtabs? + email = Email( + subject=f"{general_settings.server_name} Invite", + message=f"Hello {invite.name}!\n\n" + f"You have been invited to join {general_settings.server_name}. Please click the link below to sign up.\n" + f"Your invite link is: {origin.rstrip('/')}{path}\n\n" + "If you did not request this invite, please ignore this email.", + recipient_list=[str(invite.email)], + ) + send_email(email, immediate=True) + + +def get_origin_header(scope) -> str: + return next( + ( + header[1].decode("utf-8") + for header in scope["headers"] + if header[0] == b"origin" + ), + "", + ) + + +@user_passes_test(lambda user: user.is_staff) +@component +def send_email_invite_btn(invite_code: str): + send_email = use_mutation(_send_email_invite, lambda *x: None) + btn_clicked, set_btn_clicked = hooks.use_state(False) + scope = use_scope() + + def send_email_invite(_): + set_btn_clicked(True) + send_email.execute(invite_code, scope) + + def retry(_): + set_btn_clicked(False) + send_email.reset() + send_email_invite(None) + + if not btn_clicked: + return html.button( + { + "type": "button", + "class_name": "btn btn-primary", + "on_click": send_email_invite, + }, + html.i({"class_name": "fas fa-paper-plane"}), + " Send Email", + ) + + if send_email.loading: + return html.button( + {"type": "button", "class_name": "btn btn-primary", "disabled": True}, + html.i({"class_name": "fas fa-spinner fa-spin"}), + " Sending...", + ) + + if send_email.error: + return html.button( + {"type": "button", "class_name": "btn btn-danger", "on_click": retry}, + html.i({"class_name": "fas fa-redo"}), + " Error! Try again?", + ) + + return html.button( + {"type": "button", "class_name": "btn btn-success"}, + html.i({"class_name": "fas fa-check"}), + " Sent!", + ) + + +# pylint: disable=protected-access +@user_passes_test(lambda user: user.is_staff) +@component +def user_management(): + return html._( + tabbed_viewport( + tabs=config.tabs.user_management.installed, + top_tabs=config._internal_tabs.user_management, + ) + ) diff --git a/conreq/_core/user_management/forms.py b/conreq/_core/user_management/forms.py new file mode 100644 index 00000000..e4f45fc2 --- /dev/null +++ b/conreq/_core/user_management/forms.py @@ -0,0 +1,46 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Button, Submit +from django.contrib.auth import get_user_model +from django.forms import ModelForm +from django.urls import reverse_lazy + +from conreq._core.sign_up.models import InviteCode + + +class UserEditForm(ModelForm): + class Meta: + model = get_user_model() + fields = ( + "username", + "email", + "first_name", + "last_name", + "is_staff", + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + self.helper.add_input( + Button( + "delete", + "Delete", + css_class="btn-danger", + onclick=f"location.href = '{reverse_lazy('conreq:delete_user')}?id=' + new URLSearchParams(window.location.search).get('id')", + ) + ) + self.helper.add_input(Button("back", "Back", onclick="history.back()")) + + +class CreateInviteForm(ModelForm): + class Meta: + model = InviteCode + fields = ("name", "email") + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Create Invite")) diff --git a/conreq/_core/user_management/static/conreq/form.css b/conreq/_core/user_management/static/conreq/form.css new file mode 100644 index 00000000..7e36a651 --- /dev/null +++ b/conreq/_core/user_management/static/conreq/form.css @@ -0,0 +1,64 @@ +body { + background: transparent; + color: rgba(255, 255, 255, 0.75); +} + +select { + color: #000; +} + +a { + color: #4499e3; + text-decoration: none !important; +} + +a:hover, +a:focus { + color: #44a9ff; +} + +.form-control { + background: rgb(20 20 20); + color: rgb(255 255 255 / 0.75); + transition: none; + border-color: #ffffff3b; +} + +.form-control:disabled, +.form-control[readonly] { + background: rgb(20 20 20); + border-color: #ffffff3b; + color: rgb(255 255 255 / 0.35); +} + +.form-select { + background: rgb(20 20 20) + url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23ffffff' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") + no-repeat right 0.75rem center; + background-size: 8px 10px; + color: rgb(255 255 255 / 0.75); + border-color: #ffffff3b; +} + +.form-select:focus { + background: #fff + url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23000000' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") + no-repeat right 0.75rem center; + color: #495057; + background-size: 8px 10px; +} + +.custom-file-label { + background: transparent; + border-color: #ffffff3b; +} + +.input-group-text { + background: rgba(255, 255, 255, 0.15); + color: #fff; + border-color: #ffffff3b; +} + +.text-muted { + text-shadow: 0 0 2px #000000; +} diff --git a/conreq/_core/user_management/static/conreq/table.css b/conreq/_core/user_management/static/conreq/table.css new file mode 100644 index 00000000..0d75b13b --- /dev/null +++ b/conreq/_core/user_management/static/conreq/table.css @@ -0,0 +1,68 @@ +a:hover, +a:focus { + color: #44a9ff; +} + +table > thead { + background: var(--accent-color); +} + +table > thead a, +table > thead th, +table > thead td, +table > thead th:hover, +table > thead td:hover { + color: rgba(255, 255, 255, 0.85); +} + +table > thead a:hover, +table > thead a:focus { + color: #fff; +} + +.table, +table { + margin-bottom: 0; + background: #fff; + border-bottom: none; + border-radius: 8px; + color: #333; + margin-bottom: 20px; +} + +th:first-of-type { + border-top-left-radius: 5px; +} + +th:last-of-type { + border-top-right-radius: 5px; +} + +.pagination { + margin-bottom: 0; +} + +.table > tbody > tr > td, +.table > tbody > tr > th, +.table > tfoot > tr > td, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > thead > tr > th { + vertical-align: middle; +} + +.table > thead > tr > td, +.table > thead > tr > th { + padding: 15px 15px; +} + +.table > tbody > tr > td, +.table > tbody > tr > th, +.table > tfoot > tr > td, +.table > tfoot > tr > th { + padding: 10px 15px; +} + +tr.odd { + background: rgba(0, 0, 0, 0.02); +} diff --git a/conreq/_core/user_management/static/conreq/table_iframe.css b/conreq/_core/user_management/static/conreq/table_iframe.css new file mode 100644 index 00000000..219aa674 --- /dev/null +++ b/conreq/_core/user_management/static/conreq/table_iframe.css @@ -0,0 +1,8 @@ +body { + background: transparent; + color: #ffffff; +} + +select { + color: #000000; +} diff --git a/conreq/_core/user_management/tables.py b/conreq/_core/user_management/tables.py new file mode 100644 index 00000000..7e862605 --- /dev/null +++ b/conreq/_core/user_management/tables.py @@ -0,0 +1,47 @@ +from django.contrib.auth import get_user_model +from django_tables2 import Table, TemplateColumn + +from conreq._core.sign_up.models import InviteCode + + +class UsersTable(Table): + edit = TemplateColumn( + template_name="conreq/manage_users/edit_btn.html", + orderable=False, + ) + + class Meta: + model = get_user_model() + # TODO: PR a template for Bootstrap 5 + template_name = "django_tables2/bootstrap-responsive.html" + fields = ( + "username", + "email", + "date_joined", + "last_login", + "is_staff", + "edit", + ) + order_by = "date_joined" + + +class UserInviteTable(Table): + lock = TemplateColumn( + template_name="conreq/manage_invites/lock_btn.html", + orderable=False, + ) + + class Meta: + model = InviteCode + template_name = "django_tables2/bootstrap-responsive.html" + fields = ( + "code", + "name", + "email", + "created_at", + "expires_at", + "used_at", + "used_by", + "lock", + ) + order_by = "-created_at" diff --git a/conreq/_core/user_management/templates/conreq/create_invite_success.html b/conreq/_core/user_management/templates/conreq/create_invite_success.html new file mode 100644 index 00000000..172b4261 --- /dev/null +++ b/conreq/_core/user_management/templates/conreq/create_invite_success.html @@ -0,0 +1,86 @@ +{% load static %} +{% load reactpy %} +{% load bootstrap %} + + + + + {% block head %} + + + + {% bootstrap_5 %} + + + + + {% endblock %} + + + +
+
+
+ +
+

Invite Code Successfully Created!

+ +
+
+ +
+ +
+ {% component 'conreq._core.user_management.components.send_email_invite_btn' class='inline-block' invite_code=invite_code %} + + + +
+
+
+ + + + + diff --git a/conreq/_core/user_management/templates/conreq/manage_invites/lock_btn.html b/conreq/_core/user_management/templates/conreq/manage_invites/lock_btn.html new file mode 100644 index 00000000..06f96d1a --- /dev/null +++ b/conreq/_core/user_management/templates/conreq/manage_invites/lock_btn.html @@ -0,0 +1,4 @@ +{% if record.is_valid %} +{% load reactpy %} +{% component "conreq._core.sign_up.components.lock_invite_code" code_id=record.id %} +{% endif %} diff --git a/conreq/_core/user_management/templates/conreq/manage_users/edit_btn.html b/conreq/_core/user_management/templates/conreq/manage_users/edit_btn.html new file mode 100644 index 00000000..e0b73aef --- /dev/null +++ b/conreq/_core/user_management/templates/conreq/manage_users/edit_btn.html @@ -0,0 +1,5 @@ + + + diff --git a/conreq/_core/user_management/urls.py b/conreq/_core/user_management/urls.py new file mode 100644 index 00000000..9221ffd7 --- /dev/null +++ b/conreq/_core/user_management/urls.py @@ -0,0 +1,13 @@ +from django.urls import path + +from conreq.config.wrappers import views + +urlpatterns = [ + path("edit-user/", views.edit_user, name="edit_user"), + path("delete-user/", views.delete_user, name="delete_user"), + path( + "create-invite-success//", + views.create_invite_success, + name="create_invite_success", + ), +] diff --git a/conreq/_core/user_management/views.py b/conreq/_core/user_management/views.py new file mode 100644 index 00000000..5fd26e82 --- /dev/null +++ b/conreq/_core/user_management/views.py @@ -0,0 +1,78 @@ +from django.contrib.auth import get_user_model +from django.contrib.auth.decorators import user_passes_test +from django.shortcuts import render +from django.urls import reverse +from django.utils.decorators import method_decorator +from django.views.generic import TemplateView +from django.views.generic.edit import CreateView, DeleteView, UpdateView +from django_tables2 import RequestConfig + +from conreq import config +from conreq._core.sign_up.models import InviteCode +from conreq._core.user_management.forms import CreateInviteForm, UserEditForm +from conreq._core.user_management.tables import UserInviteTable, UsersTable +from conreq.utils.views import ( + CurrentUserOrAdminMixin, + ObjectInParamsMixin, + SuccessCurrentUrlMixin, +) + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class EditUserView( + SuccessCurrentUrlMixin, ObjectInParamsMixin, CurrentUserOrAdminMixin, UpdateView +): + template_name = config.templates.edit_user + form_class = UserEditForm + model = get_user_model() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["form_title"] = "Edit User" + return context + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class DeleteUserView( + SuccessCurrentUrlMixin, ObjectInParamsMixin, CurrentUserOrAdminMixin, DeleteView +): + template_name = config.templates.delete_user + model = get_user_model() + + +@user_passes_test(lambda u: u.is_superuser) +def manage_users(request, per_page=25, page=1): + table = UsersTable(get_user_model().objects.all()) + RequestConfig( + request, + paginate={"per_page": per_page, "page": page}, + ).configure(table) + return render(request, "conreq/table.html", {"table": table}) + + +@user_passes_test(lambda u: u.is_superuser) +def manage_invites(request, per_page=25, page=1): + table = UserInviteTable(InviteCode.objects.all()) + RequestConfig( + request, + paginate={"per_page": per_page, "page": page}, + ).configure(table) + return render(request, "conreq/table.html", {"table": table}) + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class CreateInvite(SuccessCurrentUrlMixin, CurrentUserOrAdminMixin, CreateView): + template_name = config.templates.create_invite + model = InviteCode + form_class = CreateInviteForm + + def get_success_url(self): + invite_code: InviteCode = getattr(self, "object") + return reverse( + "conreq:create_invite_success", kwargs={"invite_code": invite_code.code} + ) + + +@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch") +class CreateInviteSuccess(TemplateView): + template_name = config.templates.create_invite_success diff --git a/conreq/core/tmdb/__init__.py b/conreq/_core/user_settings/__init__.py similarity index 100% rename from conreq/core/tmdb/__init__.py rename to conreq/_core/user_settings/__init__.py diff --git a/conreq/_core/user_settings/apps.py b/conreq/_core/user_settings/apps.py new file mode 100644 index 00000000..b9623a71 --- /dev/null +++ b/conreq/_core/user_settings/apps.py @@ -0,0 +1,19 @@ +from django.apps import AppConfig +from reactpy_django.utils import register_iframe + +from conreq.utils.modules import load + + +class ServerSettingsConfig(AppConfig): + name = "conreq._core.user_settings" + verbose_name = "User Settings" + + def ready(self): + from . import views + + load("components") + register_iframe(views.UserSettingsView) + register_iframe(views.ChangePasswordView) + register_iframe(views.DeleteMyAccountView) + register_iframe(views.DeleteMyAccountConfirmView) + register_iframe(views.delete_my_account_success) diff --git a/conreq/_core/user_settings/components.py b/conreq/_core/user_settings/components.py new file mode 100644 index 00000000..b800cd44 --- /dev/null +++ b/conreq/_core/user_settings/components.py @@ -0,0 +1,56 @@ +from reactpy import component, html +from reactpy_django.components import view_to_iframe +from reactpy_django.decorators import user_passes_test + +from conreq import config +from conreq._core.components import tabbed_viewport +from conreq._core.user_settings import views + +user_settings_vtc = view_to_iframe(views.UserSettingsView) +change_password_vtc = view_to_iframe(views.ChangePasswordView) +delete_my_account_vtc = view_to_iframe(views.DeleteMyAccountView) +delete_my_account_confirm_vtc = view_to_iframe(views.DeleteMyAccountConfirmView) +delete_my_account_success_vtc = view_to_iframe(views.delete_my_account_success) + + +@user_passes_test(lambda user: user.is_active) +@component +def general(): + return user_settings_vtc() + + +@user_passes_test(lambda user: user.is_active) +@component +def change_password(): + return change_password_vtc() + + +@user_passes_test(lambda user: user.is_active) +@component +def delete_my_account(): + return delete_my_account_vtc() + + +@user_passes_test(lambda user: user.is_active) +@component +def delete_my_account_confirm(): + return delete_my_account_confirm_vtc() + + +@user_passes_test(lambda user: user.is_active) +@component +def delete_my_account_success(): + return delete_my_account_success_vtc() + + +# pylint: disable=protected-access +@user_passes_test(lambda user: user.is_active) +@component +def user_settings(): + return html._( + tabbed_viewport( + tabs=config.tabs.user_settings.installed, + top_tabs=config._internal_tabs.user_settings_top, + bottom_tabs=config._internal_tabs.user_settings_bottom, + ) + ) diff --git a/conreq/_core/user_settings/forms.py b/conreq/_core/user_settings/forms.py new file mode 100644 index 00000000..220452ac --- /dev/null +++ b/conreq/_core/user_settings/forms.py @@ -0,0 +1,67 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Submit +from django.contrib.auth import get_user_model +from django.contrib.auth.forms import PasswordChangeForm +from django.contrib.auth.hashers import check_password +from django.forms import CharField, ModelForm, PasswordInput +from django.urls import reverse_lazy + + +class UserSettingsForm(ModelForm): + class Meta: + model = get_user_model() + fields = ( + "username", + "email", + "first_name", + "last_name", + # TODO: Fetch more settings via conreq.config object + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + + +class ChangePasswordForm(PasswordChangeForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input(Submit("submit", "Save")) + + +class DeleteMyAccountForm(ModelForm): + password = CharField(widget=PasswordInput()) + confirm_password = CharField(widget=PasswordInput()) + success_url = reverse_lazy("conreq:delete_my_account_confirm") + + class Meta: + model = get_user_model() + fields = ("password",) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.form_method = "post" + self.helper.add_input( + Submit("submit", "Delete My Account", css_class="btn btn-danger") + ) + + def clean(self): + cleaned_data = super().clean() + + if not cleaned_data: + self.add_error("password", "Invalid data.") + return + + password = cleaned_data.get("password") + confirm_password = cleaned_data.get("confirm_password") + + if password != confirm_password: + self.add_error("confirm_password", "Password does not match.") + + if not check_password(password, self.instance.password): + self.add_error("password", "Incorrect password.") diff --git a/conreq/_core/user_settings/views.py b/conreq/_core/user_settings/views.py new file mode 100644 index 00000000..5ad18817 --- /dev/null +++ b/conreq/_core/user_settings/views.py @@ -0,0 +1,52 @@ +from django.contrib.auth.decorators import user_passes_test +from django.contrib.auth.views import PasswordChangeView +from django.shortcuts import render +from django.urls.base import reverse_lazy +from django.utils.decorators import method_decorator +from django.views.generic.edit import DeleteView, FormView, UpdateView + +from conreq._core.user_settings.forms import ( + ChangePasswordForm, + DeleteMyAccountForm, + UserSettingsForm, +) +from conreq.utils.views import SuccessCurrentUrlMixin, UserInstanceMixin + + +@method_decorator(user_passes_test(lambda u: u.is_authenticated), name="dispatch") +class UserSettingsView(UserInstanceMixin, SuccessCurrentUrlMixin, UpdateView): + template_name = "conreq/form.html" + form_class = UserSettingsForm + + +@method_decorator(user_passes_test(lambda u: u.is_authenticated), name="dispatch") +class ChangePasswordView(SuccessCurrentUrlMixin, PasswordChangeView): + template_name = "conreq/form.html" + form_class = ChangePasswordForm + + +@method_decorator(user_passes_test(lambda u: u.is_authenticated), name="dispatch") +class DeleteMyAccountView(UserInstanceMixin, FormView): + template_name = "conreq/form.html" + form_class = DeleteMyAccountForm + success_url = reverse_lazy("conreq:delete_my_account_confirm") + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["form_subtitle"] = "Confirm your password to delete your account." + return context + + +@method_decorator(user_passes_test(lambda u: u.is_authenticated), name="dispatch") +class DeleteMyAccountConfirmView(UserInstanceMixin, DeleteView): + template_name = "conreq/delete_confirm.html" + success_url = reverse_lazy("conreq:delete_my_account_success") + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["form_title"] = "Are you sure you want to delete your account?" + return context + + +def delete_my_account_success(request): + return render(request, "conreq/refresh_parent_frame.html") diff --git a/conreq/_core/validators.py b/conreq/_core/validators.py new file mode 100644 index 00000000..1c31fb14 --- /dev/null +++ b/conreq/_core/validators.py @@ -0,0 +1,47 @@ +import re + +from django.core.validators import URLValidator +from django.utils.deconstruct import deconstructible +from django.utils.regex_helper import _lazy_re_compile + + +@deconstructible +class HostnameOrURLValidator(URLValidator): + """URL validator that supports hostnames (ex. https://sonarr:8000) + as well as normal URLs""" + + # pylint: disable=too-few-public-methods + ul = URLValidator.ul + ipv4_re = URLValidator.ipv4_re + ipv6_re = URLValidator.ipv6_re + hostname_re = URLValidator.hostname_re + domain_re = URLValidator.domain_re + + tld_re = ( + r"\.?" # OPTIONAL dot (allows for hostnames) + r"(?!-)" # can't start with a dash + r"(?:[a-z" + ul + "-]{2,63}" # domain label + r"|xn--[a-z0-9]{1,59})" # or punycode label + r"(? Callable: + """Decorates an ReactPy component. Tab is added to the sidebar and is rendered when clicked. + By default, the function decorated will be rendered to the viewport. The `on_click` event + can be overridden to change this behavior.""" + # TODO: Implement auth level + # TODO: URL support (Requires ReactPy to support URL routing) + + def decorator(component: ComponentConstructor | Callable[..., Component]): + if config.homepage.sidebar_tabs and group not in config.homepage.sidebar_tabs: + config.homepage.sidebar_tabs.add(group) + + for nav_group in config.homepage.sidebar_tabs: + if group == nav_group: + nav_group.tabs.add( + SidebarTab( + name=name, + viewport=Viewport( + component=component, + html_class=html_class, + padding=padding, + ), + on_click=on_click, + auth=auth, + ) + ) + break + + return component + + return decorator + + +def sidebar_group(group: NavGroup): + """Creates a nav group and/or sets the group icon.""" + for nav_group in config.homepage.sidebar_tabs: + if group == nav_group: + nav_group.icon = group.icon + return + + config.homepage.sidebar_tabs.add(group) + + +def css(file_link: CSS): + if file_link.local: + config.homepage.local_stylesheets.append(file_link) + else: + config.homepage.remote_stylesheets.append(file_link) + + +def scss(file_link: SCSS): + config.homepage.scss_stylesheets.append(file_link) + + +def javascript(file_link: JavaScript): + if file_link.local: + config.homepage.local_scripts.append(file_link) + else: + config.homepage.remote_scripts.append(file_link) + + +def head_content(template: HTMLTemplate): + config.homepage.head_content.append(template) diff --git a/conreq/app/register/http.py b/conreq/app/register/http.py new file mode 100644 index 00000000..365c652c --- /dev/null +++ b/conreq/app/register/http.py @@ -0,0 +1,59 @@ +from django.urls import path, re_path + +# TODO: Implement WSGI middleware register function, probably not here though +# TODO: Have app API for conreq._core.api.permissions.HasAPIKey +# pylint: disable=import-outside-toplevel + + +def url( + url_pattern: str, + name: str | None = None, + use_regex: bool = False, +): + """Decorates a Django view function or view class.""" + + def decorator(view): + from conreq.urls import external_urls + + _register_view(view, url_pattern, external_urls, name, use_regex) + + return view + + return decorator + + +def api( + url_pattern: str, + version: int = 1, + name: str | None = None, + use_regex: bool = False, +): + """Decorates a DRF view function or view class.""" + + def decorator(view): + from conreq._core.api.urls import urlpatterns + + _register_view(view, f"v{version}/{url_pattern}", urlpatterns, name, use_regex) + + return view + + return decorator + + +def csrf_origin(url: str): + # TODO: Implement this later + return None + + +def _register_view(view, url_pattern, url_patterns, name, use_regex): + registered_view = view.as_view() if hasattr(view, "as_view") else view + dotted_path = f"{view.__module__}.{view.__name__}".replace("<", "").replace(">", "") + + if use_regex: + url_patterns.append( + re_path(url_pattern, registered_view, name=name or dotted_path) + ) + else: + url_patterns.append( + path(url_pattern, registered_view, name=name or dotted_path) + ) diff --git a/conreq/app/register/notifications.py b/conreq/app/register/notifications.py new file mode 100644 index 00000000..fc859026 --- /dev/null +++ b/conreq/app/register/notifications.py @@ -0,0 +1,8 @@ +# TODO: Create generic user notification agents +# Should be a class with some pre-designed endpoints for sending +# Probaby something like send(user:User, message) and mass_send(user:list[User], message) +# Need some other generic construct for non-user based notification agents + + +def agent(): + pass diff --git a/conreq/app/register/startup.py b/conreq/app/register/startup.py new file mode 100644 index 00000000..d2af95af --- /dev/null +++ b/conreq/app/register/startup.py @@ -0,0 +1,28 @@ +"""Modifies the start behavior of Conreq, primarily related to conreq/settings.py.""" + +import logging +from multiprocessing import Process + +from conreq import config + +_logger = logging.getLogger(__name__) + + +def function(func): + """Decorates any function that needs to be run prior to the webserver being up.""" + config.startup.functions.add(func) + return func + + +def process(process: Process, no_warn: bool = False): + """Any `Process` that needs to be run separately from Conreq during startup. + Only one process will be created, regardless of how many webserver workers exist. + """ + if not process.daemon and not no_warn: + _logger.warning( + "\033[93m" + 'Process "%s" is not a daemon, and thus may become a zombie if not properly handled.' + "\033[0m", + process.name, + ) + config.startup.processes.add(process) diff --git a/conreq/app/register/tabs.py b/conreq/app/register/tabs.py new file mode 100644 index 00000000..9f025b88 --- /dev/null +++ b/conreq/app/register/tabs.py @@ -0,0 +1,32 @@ +from conreq import config +from conreq.types import SubTab + + +def user_settings(name: str): + """Decorates an ReactPy component. Tabs are added to the user settings page.""" + + def decorator(func): + config.tabs.user_settings.installed.append(SubTab(name=name, component=func)) + return func + + return decorator + + +def manage_users(name: str): + """Decorates an ReactPy component. Tabs are added to the manage users page.""" + + def decorator(func): + config.tabs.user_management.installed.append(SubTab(name=name, component=func)) + return func + + return decorator + + +def server_settings(name: str): + """Decorates an ReactPy component. Tabs are added to the user server settings page.""" + + def decorator(func): + config.tabs.server_settings.installed.append(SubTab(name=name, component=func)) + return func + + return decorator diff --git a/conreq/app/register/templates.py b/conreq/app/register/templates.py new file mode 100644 index 00000000..782e3d5b --- /dev/null +++ b/conreq/app/register/templates.py @@ -0,0 +1,41 @@ +from conreq import config + + +def landing(template: str): + """Changes the landing HTML template.""" + config.templates.landing = template + + +def home(template: str): + """Changes the home HTML template.""" + config.templates.home = template + + +def sign_up(template: str): + """Changes the sign up HTML template.""" + config.templates.sign_up = template + + +def sign_in(template: str): + """Changes the sign in HTML template.""" + config.templates.sign_in = template + + +def password_reset(template: str): + """Changes the password reset HTML template.""" + config.templates.password_reset = template + + +def password_reset_sent(template: str): + """Changes the password reset HTML template.""" + config.templates.password_reset_sent = template + + +def password_reset_confirm(template: str): + """Changes the password reset HTML template.""" + config.templates.password_reset_confirm = template + + +def offline(template: str): + """Changes the offline HTML template.""" + config.templates.offline = template diff --git a/conreq/app/register/views.py b/conreq/app/register/views.py new file mode 100644 index 00000000..0357bbaa --- /dev/null +++ b/conreq/app/register/views.py @@ -0,0 +1,76 @@ +from conreq import config +from conreq.utils.profiling import profiled_view + +# pylint: disable=import-outside-toplevel + + +def landing(view): + """Changes the home view.""" + config.views.landing = profiled_view(view) + return view + + +def home(view): + """Changes the home view.""" + config.views.home = profiled_view(view) + return view + + +def sign_up(view): + """Changes the sign up view.""" + config.views.sign_up = profiled_view(view) + return view + + +def sign_in(view): + """Changes the sign in view.""" + config.views.sign_in = profiled_view(view) + return view + + +def edit_user(view): + """Changes the delete user view.""" + config.views.edit_user = profiled_view(view) + return view + + +def delete_user(view): + """Changes the delete user view.""" + config.views.delete_user = profiled_view(view) + return view + + +def password_reset(view): + """Changes the password reset view.""" + config.views.password_reset = profiled_view(view) + return view + + +def password_reset_sent(view): + """Changes the password reset sent view.""" + config.views.password_reset_sent = profiled_view(view) + return view + + +def password_reset_confirm(view): + """Changes the password reset confirm view.""" + config.views.password_reset_confirm = profiled_view(view) + return view + + +def offline(view): + """Changes the offline view.""" + config.views.offline = profiled_view(view) + return view + + +def service_worker(view): + """Changes the service worker view.""" + config.views.service_worker = profiled_view(view) + return view + + +def web_manifest(view): + """Changes the web manifest view.""" + config.views.web_manifest = profiled_view(view) + return view diff --git a/conreq/app/register/websockets.py b/conreq/app/register/websockets.py new file mode 100644 index 00000000..ebba46c4 --- /dev/null +++ b/conreq/app/register/websockets.py @@ -0,0 +1,21 @@ +from channels.consumer import AsyncConsumer +from django import urls + +from conreq import config +from conreq.utils.environment import get_base_url + +BASE_URL = get_base_url(prepend_slash=False, empty_if_unset=True) + + +def websocket(path: str, use_regex: bool = False): + """Decorates a websocket consumer class.""" + + def decorator(consumer: AsyncConsumer): + websockets = config.asgi.websockets + if not use_regex: + websockets.append(urls.path(BASE_URL + path, consumer.as_asgi())) + else: + websockets.append(urls.re_path(BASE_URL + path, consumer.as_asgi())) + return consumer + + return decorator diff --git a/conreq/core/user_requests/migrations/__init__.py b/conreq/app/services/__init__.py similarity index 100% rename from conreq/core/user_requests/migrations/__init__.py rename to conreq/app/services/__init__.py diff --git a/conreq/app/services/email.py b/conreq/app/services/email.py new file mode 100644 index 00000000..9e168a4d --- /dev/null +++ b/conreq/app/services/email.py @@ -0,0 +1,118 @@ +""" +Tools for sending email. +""" + +import logging +from typing import Sequence + +from django.core.exceptions import ImproperlyConfigured +from django.core.mail import send_mail as django_send_email +from django.core.mail.backends import smtp + +from conreq._core.email import tasks +from conreq._core.email.types import Email, EmailBackend +from conreq._core.email.utils import get_from_name +from conreq._core.email.utils import send_mass_email as _send_mass_email +from conreq.app.models import AuthEncryption, EmailSettings +from conreq.utils.generic import DoNothingWith + +__all__ = [ + "Email", + "EmailBackend", + "get_from_name", + "send_email", + "send_mass_email", +] + +_logger = logging.getLogger(__name__) + + +def _get_mail_backend(email_config: EmailSettings | None = None, lock: bool = False): + config: EmailSettings = email_config or EmailSettings.get_solo() + backend = smtp.EmailBackend( + host=config.server, + port=config.port, + username=config.username, + password=config.password, + use_tls=config.auth_encryption == AuthEncryption.TLS, + use_ssl=config.auth_encryption == AuthEncryption.SSL, + timeout=config.timeout, + ) + # Note: A new backend connection needs to be formed every task run + # since threading.rlock is not serializable by Huey + if not lock: + backend._lock = DoNothingWith() # type: ignore # pylint: disable=protected-access + return backend + + +def send_email( + email: Email, + immediate: bool = False, +): + """ + Sends a single message to list of recipients. All members of the list + will see the other recipients in the 'To' field. + + Emails can either be send out immediately, or sent in the background. + """ + email_config: EmailSettings = EmailSettings.get_solo() + + if not email_config.enabled: + try: + raise ImproperlyConfigured("Email is not enabled.") + except Exception as exception: + _logger.exception("Email is not enabled.", stack_info=True) + raise exception + + return ( + django_send_email( + email.subject, + email.message, + get_from_name(email_config), + email.recipient_list, + html_message=email.html_message, + connection=_get_mail_backend(email_config, lock=True), + ) + if immediate + else tasks.send_email( + email.subject, + email.message, + get_from_name(email_config), + email.recipient_list, + html_message=email.html_message, + connection=_get_mail_backend(email_config), + ) + ) + + +def send_mass_email( + emails: Sequence[Email], + immediate: bool = False, +): + """ + Sends out multiple emails while reusing one SMTP connection. + + Emails can either be send out immediately, or sent in the background. + """ + email_config: EmailSettings = EmailSettings.get_solo() + + if not email_config.enabled: + try: + raise ImproperlyConfigured("Email is not enabled.") + except Exception as exception: + _logger.exception("Email is not enabled.", stack_info=True) + raise exception + + return ( + _send_mass_email( + connection=_get_mail_backend(email_config, lock=True), + emails=emails, + email_config=email_config, + ) + if immediate + else tasks.send_mass_email( + connection=_get_mail_backend(email_config), + emails=emails, + email_config=email_config, + ) + ) diff --git a/conreq/app/validators.py b/conreq/app/validators.py new file mode 100644 index 00000000..034cee42 --- /dev/null +++ b/conreq/app/validators.py @@ -0,0 +1,9 @@ +from conreq._core.validators import ( + HostnameOrURLValidator, + url_or_relative_url_validator, +) + +__all__ = [ + "HostnameOrURLValidator", + "url_or_relative_url_validator", +] diff --git a/conreq/app/views.py b/conreq/app/views.py new file mode 100644 index 00000000..d3676e46 --- /dev/null +++ b/conreq/app/views.py @@ -0,0 +1,5 @@ +from conreq._core.views import SingletonUpdateView + +__all__ = [ + "SingletonUpdateView", +] diff --git a/conreq/app/widgets.py b/conreq/app/widgets.py new file mode 100644 index 00000000..5125ed12 --- /dev/null +++ b/conreq/app/widgets.py @@ -0,0 +1,5 @@ +from conreq._core.widgets import URLOrRelativeURLInput + +__all__ = [ + "URLOrRelativeURLInput", +] diff --git a/conreq/app_template/app_name/app.json b/conreq/app_template/app_name/app.json deleted file mode 100644 index 2789a949..00000000 --- a/conreq/app_template/app_name/app.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "app_name": "", - "app_version": "", - "description": "", - "notice_msg": "", - "gh_author": "", - "repository_url": "", - "homepage_url": "", - "support_url": "", - "donation_url": "", - "env_variables": [], - "categories": [], - "development_stage": "", - "mobile_compatible": false, - "min_conreq_version": "", - "tested_conreq_version": "", - "max_conreq_version": "", - "optional_apps": [""], - "required_apps": [""], - "incompatible_apps": [""], - "incompatible_app_categories": [] -} diff --git a/conreq/app_template/app_name/config.py b/conreq/app_template/app_name/config.py deleted file mode 100644 index 15a66071..00000000 --- a/conreq/app_template/app_name/config.py +++ /dev/null @@ -1,8 +0,0 @@ -# App configuration parameters used by Conreq -HEAD_TEMPLATES = [] -BODY_TEMPLATES = [] -INIT_COMMANDS = [] -PRECONFIGURE_COMMANDS = [] -SPLASH_TEMPLATE = "" -LOGIN_TEMPLATE = "" -BASE_TEMPLATE = "" diff --git a/conreq/app_template/app_name/main/admin.py b/conreq/app_template/app_name/main/admin.py deleted file mode 100644 index 8c38f3f3..00000000 --- a/conreq/app_template/app_name/main/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/conreq/app_template/app_name/main/apps.py b/conreq/app_template/app_name/main/apps.py deleted file mode 100644 index fcdbc065..00000000 --- a/conreq/app_template/app_name/main/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class {{ camel_case_app_name }}Config(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = '{{ app_name }}.main' diff --git a/conreq/app_template/app_name/main/models.py b/conreq/app_template/app_name/main/models.py deleted file mode 100644 index 71a83623..00000000 --- a/conreq/app_template/app_name/main/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/conreq/app_template/app_name/main/tests.py b/conreq/app_template/app_name/main/tests.py deleted file mode 100644 index 7ce503c2..00000000 --- a/conreq/app_template/app_name/main/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/conreq/app_template/app_name/main/urls.py b/conreq/app_template/app_name/main/urls.py deleted file mode 100644 index 1b825538..00000000 --- a/conreq/app_template/app_name/main/urls.py +++ /dev/null @@ -1,2 +0,0 @@ -app_name = "{{ app_name }}" -urlpattern = [] diff --git a/conreq/app_template/app_name/main/views.py b/conreq/app_template/app_name/main/views.py deleted file mode 100644 index 91ea44a2..00000000 --- a/conreq/app_template/app_name/main/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/conreq/app_template/app_name/navtabs.py b/conreq/app_template/app_name/navtabs.py deleted file mode 100644 index 6ec29d80..00000000 --- a/conreq/app_template/app_name/navtabs.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.urls import reverse - -USER_NAVTABS = [] -ADMIN_NAVTABS = [] -CUSTOM_NAVTABS = {} -SETTINGS_TABS = [] diff --git a/conreq/app_template/app_name/requirements.txt b/conreq/app_template/app_name/requirements.txt deleted file mode 100644 index 7bdf1f43..00000000 --- a/conreq/app_template/app_name/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -# Any requirements in here will be automatically installed by Conreq \ No newline at end of file diff --git a/conreq/app_template/app_name/settings.py b/conreq/app_template/app_name/settings.py deleted file mode 100644 index 429be68b..00000000 --- a/conreq/app_template/app_name/settings.py +++ /dev/null @@ -1,4 +0,0 @@ -# CAUTION: Anything in here will get automatically added into Conreq's Django settings file. -# For more information, see the following docs: -# https://docs.djangoproject.com/en/3.2/topics/settings/ -# https://github.com/sobolevn/django-split-settings diff --git a/conreq/asgi.py b/conreq/asgi.py index 208a2cf2..e2bcaaea 100644 --- a/conreq/asgi.py +++ b/conreq/asgi.py @@ -6,45 +6,24 @@ For more information on this file, see https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ """ -# pylint: disable=wrong-import-position +import os + from django.core.asgi import get_asgi_application -from django.urls import path + +# This is required if running the webserver via terminal +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conreq.settings") # Fetch ASGI application before importing dependencies that require ORM models. django_asgi_app = get_asgi_application() -from channels.auth import AuthMiddlewareStack -from channels.routing import ProtocolTypeRouter, URLRouter -from channels.security.websocket import AllowedHostsOriginValidator - -from conreq.core.websockets.consumers import CommandConsumer -from conreq.utils.environment import get_base_url - -BASE_URL = get_base_url() -if BASE_URL: - BASE_URL = BASE_URL[1:] +# pylint: disable=wrong-import-position +from channels.auth import AuthMiddlewareStack # noqa: E402 +from channels.routing import ProtocolTypeRouter, URLRouter # noqa: E402 +from channels.security.websocket import AllowedHostsOriginValidator # noqa: E402 +from channels.sessions import SessionMiddlewareStack # noqa: E402 -class LifespanApp: - # pylint: disable=too-few-public-methods - """ - Temporary shim for https://github.com/django/channels/issues/1216 - Needed so that hypercorn doesn't display an error. - """ - - def __init__(self, scope): - self.scope = scope - - async def __call__(self, receive, send): - if self.scope["type"] == "lifespan": - while True: - message = await receive() - if message["type"] == "lifespan.startup": - await send({"type": "lifespan.startup.complete"}) - elif message["type"] == "lifespan.shutdown": - await send({"type": "lifespan.shutdown.complete"}) - return - +from conreq import config # noqa: E402 application = ProtocolTypeRouter( { @@ -52,10 +31,9 @@ async def __call__(self, receive, send): # See https://github.com/django/channels/issues/1587 "http": django_asgi_app, "websocket": AllowedHostsOriginValidator( - AuthMiddlewareStack( - URLRouter([path(BASE_URL, CommandConsumer().as_asgi())]) + SessionMiddlewareStack( + AuthMiddlewareStack(URLRouter(config.asgi.websockets)) ) ), - "lifespan": LifespanApp, } ) diff --git a/conreq/config/__init__.py b/conreq/config/__init__.py new file mode 100644 index 00000000..b33128eb --- /dev/null +++ b/conreq/config/__init__.py @@ -0,0 +1,44 @@ +from conreq.config.types import ( + AsgiConfig, + ComponentConfig, + HomepageConfig, + StartupConfig, + TabConfig, + TemplateConfig, + ViewConfig, + WsgiConfig, + _InternalHomepageConfig, + _InternalTabConfig, +) + +asgi = AsgiConfig() +components = ComponentConfig() +homepage = HomepageConfig() +_homepage = _InternalHomepageConfig() +startup = StartupConfig() +tabs = TabConfig() +_internal_tabs = _InternalTabConfig() +templates = TemplateConfig() +views = ViewConfig() +wsgi = WsgiConfig() + +__all__ = [ + "asgi", + "components", + "homepage", + "_homepage", + "startup", + "tabs", + "_internal_tabs", + "templates", + "views", + "wsgi", +] + + +def load_default_tabs(): + # pylint: disable=import-outside-toplevel, unused-import + from conreq.config import default_tabs # noqa: F401 + + +load_default_tabs() diff --git a/conreq/config/default_tabs.py b/conreq/config/default_tabs.py new file mode 100644 index 00000000..b56c6d74 --- /dev/null +++ b/conreq/config/default_tabs.py @@ -0,0 +1,122 @@ +from conreq import config +from conreq.config.utils import tab_constructor +from conreq.config.wrappers.components import ( + app_store, + server_settings, + server_settings_email, + server_settings_general, + server_settings_licenses, + server_settings_styling, + server_settings_system_info, + server_settings_webserver, + sign_out, + user_management, + user_management_create_invite, + user_management_manage_invites, + user_management_manage_users, + user_settings, + user_settings_change_password, + user_settings_delete_account, + user_settings_general, +) +from conreq.types import SubTab + +# Register the component wrappers to be referenced by apps to change tabs +# Register the tabs and sidebar navtabs +# pylint: disable=protected-access +config.tabs.user_settings.main = tab_constructor("Settings", user_settings) +config._homepage.user_sidebar_tabs.append(config.tabs.user_settings.main) + + +config.tabs.sign_out.main = tab_constructor("Sign Out", sign_out) +config._homepage.user_sidebar_tabs.append(config.tabs.sign_out.main) + + +config.tabs.user_management.main = tab_constructor("User Management", user_management) +config._homepage.admin_sidebar_tabs.append(config.tabs.user_management.main) + + +config.tabs.app_store.main = tab_constructor( + "App Store", app_store, html_class="app-store", padding=False +) +config._homepage.admin_sidebar_tabs.append(config.tabs.app_store.main) + + +config.tabs.server_settings.main = tab_constructor("Server Settings", server_settings) +config._homepage.admin_sidebar_tabs.append(config.tabs.server_settings.main) + + +config.tabs.user_settings.general = SubTab( + name="General", component=user_settings_general +) +config._internal_tabs.user_settings_top.append(config.tabs.user_settings.general) + + +config.tabs.user_settings.change_password = SubTab( + name="Change Password", component=user_settings_change_password +) +config._internal_tabs.user_settings_top.append( + config.tabs.user_settings.change_password +) + + +config.tabs.user_settings.delete_account = SubTab( + name="Delete My Account", component=user_settings_delete_account +) +config._internal_tabs.user_settings_bottom.append( + config.tabs.user_settings.delete_account +) + + +config.tabs.user_management.manage_users = SubTab( + name="Manage Users", component=user_management_manage_users +) +config._internal_tabs.user_management.append(config.tabs.user_management.manage_users) + + +config.tabs.user_management.manage_invites = SubTab( + name="Manage Invites", component=user_management_manage_invites +) +config._internal_tabs.user_management.append(config.tabs.user_management.manage_invites) + + +config.tabs.user_management.create_invite = SubTab( + name="Create Invite", component=user_management_create_invite +) +config._internal_tabs.user_management.append(config.tabs.user_management.create_invite) + + +config.tabs.server_settings.general = SubTab( + name="General", component=server_settings_general +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.general) + + +config.tabs.server_settings.styling = SubTab( + name="Styling", component=server_settings_styling +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.styling) + + +config.tabs.server_settings.webserver = SubTab( + name="Webserver", component=server_settings_webserver +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.webserver) + + +config.tabs.server_settings.email = SubTab( + name="Email", component=server_settings_email +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.email) + + +config.tabs.server_settings.system_info = SubTab( + name="System Info", component=server_settings_system_info +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.system_info) + + +config.tabs.server_settings.licenses = SubTab( + name="Licenses", component=server_settings_licenses +) +config._internal_tabs.server_settings.append(config.tabs.server_settings.licenses) diff --git a/conreq/config/types.py b/conreq/config/types.py new file mode 100644 index 00000000..5e38767a --- /dev/null +++ b/conreq/config/types.py @@ -0,0 +1,266 @@ +"""Conreq's configuration values.""" + +from dataclasses import dataclass, field +from multiprocessing import Process +from typing import Callable + +from django.views import View +from reactpy.html import div, span +from reactpy.types import ComponentConstructor, VdomDict +from sortedcontainers import SortedList + +from conreq.types import CSS, SCSS, HTMLTemplate, JavaScript, SidebarTab, SubTab + +# pylint: disable=too-many-instance-attributes + + +# Component Configuration + + +@dataclass +class _UserSettingsComponents: + """Used to store user-defined components.""" + + main: ComponentConstructor | None = None + general: ComponentConstructor | None = None + change_password: ComponentConstructor | None = None + delete_account: ComponentConstructor | None = None + + +@dataclass +class _SignOutComponents: + """Used to store user-defined components.""" + + main: ComponentConstructor | None = None + event: Callable | None = None + + +@dataclass +class _UserManagementComponents: + """Used to store user-defined components.""" + + main: ComponentConstructor | None = None + manage_users: ComponentConstructor | None = None + edit_user: ComponentConstructor | None = None + delete_user: ComponentConstructor | None = None + manage_invites: ComponentConstructor | None = None + create_invite: ComponentConstructor | None = None + + +@dataclass +class _ServerSettingsComponents: + """Used to store user-defined components.""" + + main: ComponentConstructor | None = None + general: ComponentConstructor | None = None + styling: ComponentConstructor | None = None + webserver: ComponentConstructor | None = None + email: ComponentConstructor | None = None + system_info: ComponentConstructor | None = None + + +@dataclass +class _LoadingAnimationComponents: + """Used to store user-defined components.""" + + large: VdomDict = field( + default_factory=lambda: div( + {"class_name": "spinner-border loading-animation lg", "role": "status"}, + span({"class_name": "sr-only"}, "Loading..."), + ), + ) + small: VdomDict = field( + default_factory=lambda: div( + {"class_name": "spinner-border loading-animation", "role": "status"}, + span({"class_name": "sr-only"}, "Loading..."), + ), + ) + + +@dataclass +class _AppStoreComponents: + """Used to store user-defined components.""" + + main: ComponentConstructor | None = None + + +# Tab Configuration + + +@dataclass +class _UserSettingsTabs: + """Used to store NavTab/Tab objects for the default sidebar categories.""" + + main: SidebarTab | None = None + general: SubTab | None = None + change_password: SubTab | None = None + delete_account: SubTab | None = None + + installed: SortedList = field(default_factory=SortedList) + + +@dataclass +class _SignOutTabs: + """Used to store NavTab/Tab objects for the default sidebar categories.""" + + main: SidebarTab | None = None + + +@dataclass +class _UserManagementTabs: + """Used to store NavTab/Tab objects for the default sidebar categories.""" + + main: SidebarTab | None = None + manage_users: SubTab | None = None + manage_invites: SubTab | None = None + create_invite: SubTab | None = None + + installed: SortedList = field(default_factory=SortedList) + + +@dataclass +class _AppStoreTabs: + """Used to store NavTab/Tab objects for the default sidebar categories.""" + + main: SidebarTab | None = None + + +@dataclass +class _ServerSettingsTabs: + """Used to store NavTab/Tab objects for the default sidebar categories.""" + + main: SidebarTab | None = None + general: SubTab | None = None + styling: SubTab | None = None + webserver: SubTab | None = None + email: SubTab | None = None + system_info: SubTab | None = None + licenses: SubTab | None = None + + installed: SortedList = field(default_factory=SortedList) + + +# Top level configuration + + +@dataclass +class StartupConfig: + functions: set[Callable[[], None]] = field(default_factory=set) + processes: set[Process] = field(default_factory=set) + + +@dataclass +class ViewConfig: + landing: Callable | View | None = None + home: Callable | View | None = None + sign_up: Callable | View | None = None + sign_in: Callable | View | None = None + edit_user: Callable | View | None = None + delete_user: Callable | View | None = None + create_invite_success: Callable | View | None = None + password_reset: Callable | View | None = None + password_reset_sent: Callable | View | None = None + password_reset_confirm: Callable | View | None = None + offline: Callable | View | None = None + service_worker: Callable | View | None = None + web_manifest: Callable | View | None = None + + +@dataclass +class TemplateConfig: + # FIXME: Some of these don't respect the settings change + landing: str = "" + home: str = "conreq/home.html" + sign_up: str = "conreq/sign_up.html" + sign_in: str = "conreq/sign_in.html" + edit_user: str = "conreq/form.html" + create_invite: str = "conreq/form.html" + create_invite_success: str = "conreq/create_invite_success.html" + delete_user: str = "conreq/delete_confirm.html" + password_reset: str = "conreq/password_reset.html" + password_reset_sent: str = "conreq/password_reset_sent.html" + password_reset_confirm: str = "conreq/password_reset_confirm.html" + offline: str = "conreq/offline.html" + + +@dataclass +class ComponentConfig: + homepage: Callable | None = None + user_settings: _UserSettingsComponents = field( + default_factory=_UserSettingsComponents, + ) + sign_out: _SignOutComponents = field( + default_factory=_SignOutComponents, + ) + user_management: _UserManagementComponents = field( + default_factory=_UserManagementComponents, + ) + app_store: _AppStoreComponents = field( + default_factory=_AppStoreComponents, + ) + server_settings: _ServerSettingsComponents = field( + default_factory=_ServerSettingsComponents, + ) + loading_animation: _LoadingAnimationComponents = field( + default_factory=_LoadingAnimationComponents + ) + + +@dataclass +class TabConfig: + user_settings: _UserSettingsTabs = field( + default_factory=_UserSettingsTabs, + ) + sign_out: _SignOutTabs = field( + default_factory=_SignOutTabs, + ) + user_management: _UserManagementTabs = field( + default_factory=_UserManagementTabs, + ) + app_store: _AppStoreTabs = field( + default_factory=_AppStoreTabs, + ) + server_settings: _ServerSettingsTabs = field( + default_factory=_ServerSettingsTabs, + ) + + +@dataclass +class _InternalTabConfig: + user_settings_top: list[SubTab] = field(default_factory=list) + user_settings_bottom: list[SubTab] = field(default_factory=list) + user_management: list[SubTab] = field(default_factory=list) + server_settings: list[SubTab] = field(default_factory=list) + + +@dataclass +class WsgiConfig: + # TODO: Implement WSGI middleware + middleware: set[dict] = field(default_factory=set) + + +@dataclass +class AsgiConfig: + websockets: list[Callable] = field(default_factory=list) + # TODO: Implement ASGI middleware + middleware: set[dict] = field(default_factory=set) + + +@dataclass +class HomepageConfig: + sidebar_tabs: SortedList = field(default_factory=SortedList) + default_sidebar_tab: SidebarTab | None = None + # TODO: Implement CSS and JS registration + local_stylesheets: list[CSS] = field(default_factory=list) + remote_stylesheets: list[CSS] = field(default_factory=list) + scss_stylesheets: list[SCSS] = field(default_factory=list) + local_scripts: list[JavaScript] = field(default_factory=list) + remote_scripts: list[JavaScript] = field(default_factory=list) + head_content: list[HTMLTemplate] = field(default_factory=list) + + +@dataclass +class _InternalHomepageConfig: + user_sidebar_tabs: list[SidebarTab] = field(default_factory=list) + admin_sidebar_tabs: list[SidebarTab] = field(default_factory=list) + debug_sidebar_tabs: list[SidebarTab] = field(default_factory=list) diff --git a/conreq/config/utils.py b/conreq/config/utils.py new file mode 100644 index 00000000..a0cee6a0 --- /dev/null +++ b/conreq/config/utils.py @@ -0,0 +1,25 @@ +from typing import Callable + +from reactpy.core.component import Component + +from conreq.types import AuthLevel, SidebarTab, Viewport + + +def tab_constructor( + name: str, + component: Callable[..., Component], + on_click: Callable | None = None, + padding: bool = True, + auth: str = AuthLevel.user, + html_class: str = "", +) -> SidebarTab: + return SidebarTab( + name=name, + viewport=Viewport( + component=component, + html_class=html_class, + padding=padding, + ), + on_click=on_click, + auth=auth, + ) diff --git a/conreq/core/websockets/__init__.py b/conreq/config/wrappers/__init__.py similarity index 100% rename from conreq/core/websockets/__init__.py rename to conreq/config/wrappers/__init__.py diff --git a/conreq/config/wrappers/components.py b/conreq/config/wrappers/components.py new file mode 100644 index 00000000..00590ab5 --- /dev/null +++ b/conreq/config/wrappers/components.py @@ -0,0 +1,206 @@ +from inspect import iscoroutinefunction + +from reactpy import component, html + +from conreq import config + + +# pylint: disable=import-outside-toplevel +@component +def homepage(*args, **kwargs): + _component = config.components.homepage + if _component is None: + from conreq._core.home import components + + return html._(components.homepage(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_settings(*args, **kwargs): + _component = config.components.user_settings.main + if _component is None: + from conreq._core.user_settings import components + + return html._(components.user_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_settings_general(*args, **kwargs): + _component = config.components.user_settings.general + if _component is None: + from conreq._core.user_settings import components + + return html._(components.general(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_settings_change_password(*args, **kwargs): + _component = config.components.user_settings.change_password + if _component is None: + from conreq._core.user_settings import components + + return html._(components.change_password(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_settings_delete_account(*args, **kwargs): + _component = config.components.user_settings.delete_account + if _component is None: + from conreq._core.user_settings import components + + return html._(components.delete_my_account(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def sign_out(*args, **kwargs): + _component = config.components.sign_out.main + if _component is None: + from conreq._core.sign_out import components + + return html._(components.sign_out(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management(*args, **kwargs): + _component = config.components.user_management.main + if _component is None: + from conreq._core.user_management import components + + return html._(components.user_management(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management_manage_users(*args, **kwargs): + _component = config.components.user_management.manage_users + if _component is None: + from conreq._core.user_management import components + + return html._(components.manage_users(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management_edit_user(*args, **kwargs): + _component = config.components.user_management.edit_user + if _component is None: + from conreq._core.user_management import components + + return html._(components.edit_user(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management_delete_user(*args, **kwargs): + _component = config.components.user_management.delete_user + if _component is None: + from conreq._core.user_management import components + + return html._(components.delete_user(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management_manage_invites(*args, **kwargs): + _component = config.components.user_management.manage_invites + if _component is None: + from conreq._core.user_management import components + + return html._(components.manage_invites(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def user_management_create_invite(*args, **kwargs): + _component = config.components.user_management.create_invite + if _component is None: + from conreq._core.user_management import components + + return html._(components.create_invite(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def app_store(*args, **kwargs): + _component = config.components.app_store.main + if _component is None: + from conreq._core.app_store import components + + return html._(components.app_store(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings(*args, **kwargs): + _component = config.components.server_settings.main + if _component is None: + from conreq._core.server_settings import components + + return html._(components.server_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_general(*args, **kwargs): + _component = config.components.server_settings.general + if _component is None: + from conreq._core.server_settings import components + + return html._(components.general_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_styling(*args, **kwargs): + _component = config.components.server_settings.styling + if _component is None: + from conreq._core.server_settings import components + + return html._(components.styling_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_webserver(*args, **kwargs): + _component = config.components.server_settings.webserver + if _component is None: + from conreq._core.server_settings import components + + return html._(components.webserver_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_email(*args, **kwargs): + _component = config.components.server_settings.email + if _component is None: + from conreq._core.server_settings import components + + return html._(components.email_settings(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_system_info(*args, **kwargs): + _component = config.components.server_settings.system_info + if _component is None: + from conreq._core.server_settings import components + + return html._(components.system_info(*args, **kwargs)) + return _component(*args, **kwargs) + + +@component +def server_settings_licenses(*args, **kwargs): + _component = config.components.server_settings.system_info + if _component is None: + from conreq._core.server_settings import components + + return html._(components.licenses(*args, **kwargs)) + return _component(*args, **kwargs) diff --git a/conreq/config/wrappers/views.py b/conreq/config/wrappers/views.py new file mode 100644 index 00000000..60de2bcc --- /dev/null +++ b/conreq/config/wrappers/views.py @@ -0,0 +1,155 @@ +from inspect import iscoroutinefunction + +from channels.db import database_sync_to_async as convert_to_async + +from conreq import config + +# pylint: disable=import-outside-toplevel + +# TODO: All the default views in core will need to be made async, after more broad Django async support. +# Specifically, Django support for async decorators, template rendering, and ORM queries. + + +async def _render_view(view, request, *args, **kwargs): + # Async Class View + if getattr(view, "view_is_async", False): + return await view.as_view()(request, *args, **kwargs) + # Sync Class View + if hasattr(view, "as_view"): + async_cbv = convert_to_async(view.as_view()) + return await async_cbv(request, *args, **kwargs) + # Async Function View + if iscoroutinefunction(view): + return await view(request, *args, **kwargs) + # Sync Function View + return await convert_to_async(view)(request, *args, **kwargs) + + +async def landing(request, *args, **kwargs): + """Configurable landing view.""" + view = config.views.landing + if view is None: + from conreq._core.landing import views + + view = views.landing + return await _render_view(view, request, *args, **kwargs) + + +async def home(request, *args, **kwargs): + """Configurable home view.""" + view = config.views.home + if view is None: + from conreq._core.home import views + + view = views.home + return await _render_view(view, request, *args, **kwargs) + + +async def sign_up(request, *args, **kwargs): + """Configurable sign up view.""" + view = config.views.sign_up + if view is None: + from conreq._core.sign_up import views + + view = views.sign_up + return await _render_view(view, request, *args, **kwargs) + + +async def sign_in(request, *args, **kwargs): + """Configurable sign in view.""" + view = config.views.sign_in + if view is None: + from conreq._core.sign_in import views + + view = views.sign_in + return await _render_view(view, request, *args, **kwargs) + + +async def edit_user(request, *args, **kwargs): + """Configurable edit user view.""" + view = config.views.edit_user + if view is None: + from conreq._core.user_management import views + + view = views.EditUserView + return await _render_view(view, request, *args, **kwargs) + + +async def delete_user(request, *args, **kwargs): + """Configurable edit user view.""" + view = config.views.delete_user + if view is None: + from conreq._core.user_management import views + + view = views.DeleteUserView + return await _render_view(view, request, *args, **kwargs) + + +async def create_invite_success(request, *args, **kwargs): + """Configurable create invite success view.""" + view = config.views.create_invite_success + if view is None: + from conreq._core.user_management import views + + view = views.CreateInviteSuccess + return await _render_view(view, request, *args, **kwargs) + + +async def password_reset(request, *args, **kwargs): + """Configurable password reset view.""" + view = config.views.password_reset + if view is None: + from conreq._core.password_reset import views + + view = views.PasswordResetView + return await _render_view(view, request, *args, **kwargs) + + +async def password_reset_sent(request, *args, **kwargs): + """Configurable password reset sent view.""" + view = config.views.password_reset_sent + if view is None: + from conreq._core.password_reset import views + + view = views.PassWordResetSentView + return await _render_view(view, request, *args, **kwargs) + + +async def password_reset_confirm(request, *args, **kwargs): + """Configurable password reset confirmation view.""" + view = config.views.password_reset_confirm + if view is None: + from conreq._core.password_reset import views + + view = views.PasswordResetConfirmView + return await _render_view(view, request, *args, **kwargs) + + +async def offline(request, *args, **kwargs): + """Configurable offline view.""" + view = config.views.offline + if view is None: + from conreq._core.pwa import views + + view = views.offline + return await _render_view(view, request, *args, **kwargs) + + +async def service_worker(request, *args, **kwargs): + """Configurable service worker view.""" + view = config.views.service_worker + if view is None: + from conreq._core.pwa import views + + view = views.service_worker + return await _render_view(view, request, *args, **kwargs) + + +async def web_manifest(request, *args, **kwargs): + """Configurable web manifest view.""" + view = config.views.web_manifest + if view is None: + from conreq._core.pwa import views + + view = views.web_manifest + return await _render_view(view, request, *args, **kwargs) diff --git a/conreq/core/api/apps.py b/conreq/core/api/apps.py deleted file mode 100644 index 59903295..00000000 --- a/conreq/core/api/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class ApiConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "conreq.core.api" diff --git a/conreq/core/api/models.py b/conreq/core/api/models.py deleted file mode 100644 index f98221ca..00000000 --- a/conreq/core/api/models.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.contrib.auth import get_user_model -from django.db.models.signals import post_save -from django.dispatch import receiver -from rest_framework.authtoken.models import Token - -User = get_user_model() - -# Create your models here. -@receiver(post_save, sender=User) -def create_auth_token( - sender, instance=None, created=False, **kwargs -): # pylint: disable=unused-argument - # Create the token if it doesn't exist - if not hasattr(instance, "auth_token"): - Token.objects.create(user=instance) diff --git a/conreq/core/api/permissions.py b/conreq/core/api/permissions.py deleted file mode 100644 index 5bbfe33b..00000000 --- a/conreq/core/api/permissions.py +++ /dev/null @@ -1,18 +0,0 @@ -import typing - -from django.http import HttpRequest -from rest_framework_api_key.models import APIKey -from rest_framework_api_key.permissions import BaseHasAPIKey, KeyParser - - -class HasAPIKey(BaseHasAPIKey): - model = APIKey - key_parser = KeyParser() - - def get_key(self, request: HttpRequest) -> typing.Optional[str]: - # Prefer key in header - header_key = self.key_parser.get(request) - if header_key: - return header_key - # Fallback to key in URL parameters - return request.GET.get("apikey") diff --git a/conreq/core/api/serializers.py b/conreq/core/api/serializers.py deleted file mode 100644 index 85d43391..00000000 --- a/conreq/core/api/serializers.py +++ /dev/null @@ -1,33 +0,0 @@ -from django.contrib.auth import get_user_model -from rest_framework import serializers - -from conreq.core.manage_users.models import Profile - - -class UserProfileSerializer(serializers.ModelSerializer): - class Meta: - model = Profile - fields = ["language", "externally_authenticated"] - - -class UserSerializer(serializers.ModelSerializer): - profile = UserProfileSerializer(required=True) - - class Meta: - model = get_user_model() - fields = [ - "id", - "last_login", - "is_superuser", - "username", - "first_name", - "last_name", - "email", - "is_staff", - "is_active", - "date_joined", - "groups", - "user_permissions", - "profile", - "auth_token", - ] diff --git a/conreq/core/api/urls.py b/conreq/core/api/urls.py deleted file mode 100644 index 930916ec..00000000 --- a/conreq/core/api/urls.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.urls import path -from rest_framework.authtoken.views import ObtainAuthToken - -from . import views - -urlpatterns = [ - # Default Endpoints - path("user", views.stub), # GET/PUT - path("user/me", views.stub), # GET/PUT - path("user/", views.stub), # GET/PUT/DELETE - path("auth/local", views.LocalAuthentication.as_view()), # POST - path("auth/local/token", ObtainAuthToken.as_view()), # POST/DELETE - path("system", views.stub), # GET - path("system/settings", views.stub), # GET/POST - # TMDB Requests App - path("tmdb/request", views.stub), # GET - path("tmdb/request/", views.stub), # GET/DELETE - path("tmdb/request/tv/", views.RequestTv.as_view()), # POST - path("tmdb/request/movie/", views.RequestMovie.as_view()), # POST - path("tmdb/issue", views.stub), # GET/POST - path("tmdb/issue/", views.stub), # GET/DELETE - path("user//tmdb/issues", views.stub), # GET - path("user//tmdb/requests", views.stub), # GET - # Sonarr/Radarr Connection App - path("sonarr/library", views.stub), # GET - path("sonarr/settings", views.stub), # GET/POST - path("radarr/library", views.stub), # GET - path("radarr/settings", views.stub), # GET/POST - path("system/settings/sonarr", views.stub), # GET/POST - path("system/settings/radarr", views.stub), # GET/POST - # TMDB Connection App - path("tmdb/discover", views.stub), # GET - path("tmdb/discover/tv", views.stub), # GET - path("tmdb/discover/tv/filters", views.stub), # GET - path("tmdb/discover/tv/filters/", views.stub), # GET - path("tmdb/discover/movies", views.stub), # GET - path("tmdb/discover/movies/filters", views.stub), # GET - path("tmdb/discover/movies/filters/", views.stub), # GET - path("tmdb/search", views.stub), # GET - path("tmdb/search/tv", views.stub), # GET - path("tmdb/search/movie", views.stub), # GET - path("tmdb/tv/", views.stub), # GET - path("tmdb/tv//recommendations", views.stub), # GET - path("tmdb/tv/genres", views.stub), # GET - path("tmdb/movie/", views.stub), # GET - path("tmdb/movie//recommendations", views.stub), # GET - path("tmdb/movie/genres", views.stub), # GET - path("tmdb/person/", views.stub), # GET - path("tmdb/regions", views.stub), # GET - path("tmdb/languages", views.stub), # GET - path("tmdb/studio/", views.stub), # GET - path("tmdb/network/", views.stub), # GET - path("tmdb/collection/", views.stub), # GET -] diff --git a/conreq/core/api/views.py b/conreq/core/api/views.py deleted file mode 100644 index 6512e1a5..00000000 --- a/conreq/core/api/views.py +++ /dev/null @@ -1,189 +0,0 @@ -import json - -from django.contrib.auth import authenticate, login -from drf_yasg import openapi -from drf_yasg.utils import swagger_auto_schema -from rest_framework import status -from rest_framework.decorators import api_view -from rest_framework.response import Response -from rest_framework.views import APIView - -from conreq.core.tmdb.discovery import TmdbDiscovery -from conreq.core.user_requests.helpers import radarr_request, sonarr_request - -from .serializers import UserSerializer - - -# Create your views here. -class RequestTv(APIView): - """Request a TV show by TMDB ID.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.msg = {"success": True, "detail": None} - - @swagger_auto_schema( - request_body=openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "seasons": openapi.Schema( - type=openapi.TYPE_ARRAY, - items=openapi.Items(type=openapi.TYPE_INTEGER), - ), - "episodes": openapi.Schema( - type=openapi.TYPE_ARRAY, - items=openapi.Items(type=openapi.TYPE_INTEGER), - ), - }, - ), - responses={ - status.HTTP_200_OK: openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "success": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - "detail": openapi.Schema( - type=openapi.TYPE_STRING, - ), - }, - ), - }, - ) - def post(self, request, tmdb_id): - """Request a TV show by TMDB ID. Optionally, you can request specific seasons or episodes.""" - tvdb_id = TmdbDiscovery().get_external_ids(tmdb_id, "tv") - request_parameters = json.loads(request.body.decode("utf-8")) - - # Request the show by the TVDB ID - if tvdb_id: - sonarr_request( - tvdb_id["tvdb_id"], - tmdb_id, - request, - request_parameters, - ) - return Response(self.msg) - return Response({"success": False, "detail": "Could not determine TVDB ID."}) - - -class RequestMovie(APIView): - """Request a movie by TMDB ID.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.msg = {"success": True, "detail": None} - - @swagger_auto_schema( - responses={ - status.HTTP_200_OK: openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "success": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - "detail": openapi.Schema( - type=openapi.TYPE_STRING, - ), - }, - ), - }, - ) - def post(self, request, tmdb_id): - """Request a movie by TMDB ID.""" - - # Request the show by the TMDB ID - radarr_request(tmdb_id, request) - return Response(self.msg) - - -class LocalAuthentication(APIView): - """Sign in to an account.""" - - @swagger_auto_schema( - request_body=openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "username": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "password": openapi.Schema( - type=openapi.TYPE_STRING, - ), - }, - ), - responses={ - status.HTTP_200_OK: openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "id": openapi.Schema( - type=openapi.TYPE_INTEGER, - ), - "last_login": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "is_superuser": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - "username": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "first_name": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "last_name": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "email": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "is_staff": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - "is_active": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - "date_joined": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "groups": openapi.Schema( - type=openapi.TYPE_ARRAY, - items=openapi.Items(type=openapi.TYPE_INTEGER), - ), - "user_permissions": openapi.Schema( - type=openapi.TYPE_ARRAY, - items=openapi.Items(type=openapi.TYPE_INTEGER), - ), - "profile": openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "language": openapi.Schema( - type=openapi.TYPE_STRING, - ), - "externally_authenticated": openapi.Schema( - type=openapi.TYPE_BOOLEAN, - ), - }, - ), - "auth_token": openapi.Schema( - type=openapi.TYPE_STRING, - ), - }, - ), - }, - ) - def post(self, request): - """Authenticate a session using a `username` and `password`. - Requires CSRF tokens on all further insecure requests (POST, PUT, DELETE, PATCH).""" - username = request.data.get("username") - password = request.data.get("password") - user = authenticate(request, username=username, password=password) - if user is not None: - login(request, user) - return Response(UserSerializer(user).data) - - -@api_view(["GET"]) -def stub(request): - """This is a stub for an endpoint that has not yet been developed.""" - return Response({}) diff --git a/conreq/core/arrs/base.py b/conreq/core/arrs/base.py deleted file mode 100644 index 1a93cad3..00000000 --- a/conreq/core/arrs/base.py +++ /dev/null @@ -1,105 +0,0 @@ -"""Conreq Content Manager: Talks with Sonarr/Radarr in order to add/remove content.""" - -# Days, Hours, Minutes, Seconds -# Library is refreshed every minute as a background task -# This value is just a fail-safe. -ARR_LIBRARY_CACHE_TIMEOUT = 24 * 60 * 60 - - -class ArrBase: - """Adds and removes content from Sonarr and Radarr, and can return the request state.""" - - # pylint: disable=too-few-public-methods - @staticmethod - def _set_content_attributes(content_type, content_source, results): - # Set a list of results - if isinstance(results, list): - for result in results: - result["content_type"] = content_type - result["content_source"] = content_source - # # Set a single media item - else: - results["content_type"] = content_type - results["content_source"] = content_source - - @staticmethod - def _check_availability(content): - """Checks the availability of one item. For use within check_availability()""" - # TODO: Rewrite this - ##################### - ### "Unavailable" ### - ##################### - # Check if an individual movie or episode does not exist (Sonarr and Radarr) - try: - if not content["hasFile"]: - content["availability"] = "Unavailable" - return content - except Exception: - pass - - # Check if a season or series is completely unavailable (Sonarr) - try: - if content["episodeFileCount"] == 0: - content["availability"] = "Unavailable" - return content - except Exception: - pass - - ################# - ### "Partial" ### - ################# - # Check if season or series is partially downloaded (Sonarr) - try: - # Series - if content.__contains__("lastInfoSync"): - if ( - content["episodeFileCount"] != 0 - and content["episodeFileCount"] < content["episodeCount"] - ): - content["availability"] = "Partial" - return content - - # Season - elif ( - content["episodeFileCount"] != 0 - and content["totalEpisodeCount"] > content["episodeCount"] - ): - content["availability"] = "Partial" - return content - except Exception: - pass - - ################### - ### "Available" ### - ################### - # Check if a season is fully downloaded (Sonarr) - try: - # Series - if content.__contains__("lastInfoSync"): - if ( - content["episodeFileCount"] != 0 - and content["episodeFileCount"] >= content["episodeCount"] - ): - content["availability"] = "Available" - return content - - # Season - elif ( - content["episodeFileCount"] != 0 - and content["totalEpisodeCount"] <= content["episodeCount"] - ): - content["availability"] = "Available" - return content - except Exception: - pass - - # Check if an individual movie or individual episode exists (Sonarr & Radarr) - try: - if content["hasFile"]: - content["availability"] = "Available" - return content - except Exception: - pass - - content["availability"] = "Unknown" - return content diff --git a/conreq/core/arrs/helpers.py b/conreq/core/arrs/helpers.py deleted file mode 100644 index cb21de99..00000000 --- a/conreq/core/arrs/helpers.py +++ /dev/null @@ -1,19 +0,0 @@ -from conreq.core.arrs.sonarr import SonarrManager - - -def wait_for_series_info(tvdb_id, max_retries=10): - """Keeps attempting to fetch a series from Sonarr until it becomes available""" - sonarr_manager = SonarrManager() - series = sonarr_manager.get( - tvdb_id=tvdb_id, obtain_season_info=True, force_update_cache=True - ) - if series is None: - series_fetch_retries = 0 - while series is None: - if series_fetch_retries > max_retries: - break - series_fetch_retries = series_fetch_retries + 1 - series = sonarr_manager.get( - tvdb_id=tvdb_id, obtain_season_info=True, force_update_cache=True - ) - return series diff --git a/conreq/core/arrs/radarr.py b/conreq/core/arrs/radarr.py deleted file mode 100644 index c14279e1..00000000 --- a/conreq/core/arrs/radarr.py +++ /dev/null @@ -1,276 +0,0 @@ -"""Conreq Content Manager: Talks with Radarr in order to add/remove content.""" -from pyarr import RadarrAPI - -from conreq.core.server_settings.models import ConreqConfig -from conreq.utils import cache, log - -from .base import ARR_LIBRARY_CACHE_TIMEOUT, ArrBase - -_logger = log.get_logger(__name__) - - -class RadarrManager(ArrBase): - """Adds and removes content from Radarr, and can return the request state.""" - - def __init__(self): - # Database values - self.conreq_config = ConreqConfig.get_solo() - - # Connection to Radarr - self.__radarr = RadarrAPI( - self.conreq_config.radarr_url.rstrip("/"), self.conreq_config.radarr_api_key - ) - - # Set values if DB still contains default values - self.check_radarr_defaults() - - def get(self, tmdb_id, force_update_cache=False): - """Gets content information and computes the availability of movies within the Radarr collection. - - Args: - force_update_cache: Boolean. If True, arr library cache is force updated before returning results. - tmdb_id: A string containing the TMDB ID. - - Returns: - 1) JSON response containing the existing content, filled with availability key-value pairs. - The availability has three available states: "Unavailable", "Partial", and "Available". - """ - try: - # Search for the TMDB ID within Radarr. - # Get Radarr's collection - results = cache.handler( - "radarr library", - function=self.get_radarr_library, - cache_duration=ARR_LIBRARY_CACHE_TIMEOUT, - force_update_cache=force_update_cache, - ) - - # Find our TMDB ID within Radarr - if isinstance(results, dict) and results.__contains__(str(tmdb_id)): - return results[str(tmdb_id)] - - # Couldn't find the movie - log.handler( - "Movie with TMDB ID " + str(tmdb_id) + " not found within Radarr.", - log.INFO, - _logger, - ) - - except KeyError: - log.handler( - "Content not ready yet!", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to get content!", - log.ERROR, - _logger, - ) - return None - - def add(self, tmdb_id, quality_profile_id, root_dir): - """Adds a new movie using Radarr. - Will not work for content that already exists. - This does NOT mark content as monitored or perform a search. - - Args: - quality_profile_id: An integer containing the quality profile ID (required). - root_dir: A string containing the root directory (required). - tmdb_id: A string containing the TMDB ID. - - Returns: - JSON response of adding the content. - """ - try: - # Add a movie with a specific TMDB ID to Radarr. - return self.__radarr.add_movie( - tmdb_id, - quality_profile_id, - root_dir, - search_for_movie=False, - ) - - except Exception: - log.handler( - "Failed to add content!", - log.ERROR, - _logger, - ) - return None - - def request(self, radarr_id): - """Monitors and searches for an existing movie using Radarr. - - Args: - radarr_id: An integer containing the Radarr ID. - - Returns: - Dict containing movie_update_results and movie_search_results - - """ - try: - # Search for a movie with a specific Radarr ID. - response = { - "movie_update_results": [], - "movie_search_results": [], - } - - # Get the movie - movie = self.__radarr.get_movie_by_movie_id(radarr_id) - - # Set the movie as monitored - movie["monitored"] = True - - # Save the changes to Radarr - response["movie_update_results"] = self.__radarr.upd_movie( - movie, move_files=True - ) - - # Search for the movie - response["movie_search_results"] = self.__radarr.post_command( - name="MoviesSearch", movieIds=[radarr_id] - ) - - return response - - except Exception: - log.handler( - "Failed to request content!", - log.ERROR, - _logger, - ) - return None - - def delete(self, radarr_id): - """Deletes an existing movie using Radarr. - - Args: - radarr_id: An integer string containing the Radarr ID. - - Returns: - JSON response of removing the content. - """ - # TODO: Need to blacklist deleted content. - try: - # Remove a movie with a specific Radarr ID. - return self.__radarr.del_movie(radarr_id, delete_files=True) - - except Exception: - log.handler( - "Failed to delete content!", - log.ERROR, - _logger, - ) - return None - - def check_radarr_defaults(self): - """Will configure default root dirs and quality profiles (if unset)""" - if self.conreq_config.radarr_enabled: - radarr_movies_folder = self.conreq_config.radarr_movies_folder - radarr_anime_folder = self.conreq_config.radarr_anime_folder - radarr_movies_quality_profile = ( - self.conreq_config.radarr_movies_quality_profile - ) - radarr_anime_quality_profile = ( - self.conreq_config.radarr_anime_quality_profile - ) - - # Root dirs - if not radarr_movies_folder or not radarr_anime_folder: - default_dir = self.radarr_root_dirs()[0]["id"] - if not radarr_movies_folder: - self.conreq_config.radarr_movies_folder = default_dir - if not radarr_anime_folder: - self.conreq_config.radarr_anime_folder = default_dir - - # Qualtiy Profiles - if not radarr_movies_quality_profile or not radarr_anime_quality_profile: - default_profile = self.radarr_quality_profiles()[0]["id"] - if not radarr_movies_quality_profile: - self.conreq_config.radarr_movies_quality_profile = default_profile - if not radarr_anime_quality_profile: - self.conreq_config.radarr_anime_quality_profile = default_profile - - # Save to DB - if self.conreq_config.tracker.changed(): - self.conreq_config.clean_fields() - self.conreq_config.save() - - def radarr_root_dirs(self): - """Returns the root dirs available within Radarr""" - try: - return self.__radarr.get_root_folder() - - except Exception: - log.handler( - "Failed to get radarr root dirs!", - log.ERROR, - _logger, - ) - return None - - def radarr_quality_profiles(self): - """Returns the quality profiles available within Radarr""" - try: - return self.__radarr.get_quality_profile() - - except Exception: - log.handler( - "Failed to get radarr quality profiles!", - log.ERROR, - _logger, - ) - return None - - def refresh_library(self): - """Refreshes our local copy of Radarr's library""" - try: - if self.conreq_config.radarr_enabled: - cache.handler( - "radarr library", - function=self.get_radarr_library, - cache_duration=ARR_LIBRARY_CACHE_TIMEOUT, - force_update_cache=True, - ) - except Exception: - log.handler( - "Failed to refresh radarr!", - log.WARNING, - _logger, - ) - - def get_radarr_library(self): - """Fetches everything within Radarr's library""" - try: - if self.conreq_config.radarr_enabled: - if self.conreq_config.radarr_url and self.conreq_config.radarr_api_key: - # Get the latest list of Radarr's collection - results = self.__radarr.get_movie() - - # Set up a dictionary of results with IDs as keys - results_with_ids = {} - for movie in results: - if movie.__contains__("tmdbId"): - self._check_availability(movie) - self._set_content_attributes("movie", "radarr", movie) - results_with_ids[str(movie["tmdbId"])] = movie - - # Return all movies - return results_with_ids - - log.handler( - "Radarr URL or API key is unset!", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Could not get movies!", - log.ERROR, - _logger, - ) - return None diff --git a/conreq/core/arrs/sonarr.py b/conreq/core/arrs/sonarr.py deleted file mode 100644 index 599396dc..00000000 --- a/conreq/core/arrs/sonarr.py +++ /dev/null @@ -1,395 +0,0 @@ -"""Conreq Content Manager: Talks with Sonarr in order to add/remove content.""" -from pyarr import SonarrAPI - -from conreq.core.server_settings.models import ConreqConfig -from conreq.utils import cache, log - -from .base import ARR_LIBRARY_CACHE_TIMEOUT, ArrBase - -_logger = log.get_logger(__name__) - - -class SonarrManager(ArrBase): - """Adds and removes content from Sonarr, and can return the request state.""" - - def __init__(self): - # Database values - self.conreq_config = ConreqConfig.get_solo() - - # Connections to Sonarr - self.__sonarr = SonarrAPI( - self.conreq_config.sonarr_url.rstrip("/"), self.conreq_config.sonarr_api_key - ) - - # Set values if DB still contains default values - self.check_sonarr_defaults() - - def get(self, tvdb_id, obtain_season_info=False, force_update_cache=False): - """Gets content information and computes the availability of series, seasons, and episodes within the Sonarr collection. - - Args: - tvdb_id: A string containing the TVDB ID. - obtain_season_info: Boolean. If True, return season/episode information. - force_update_cache: Boolean. If True, arr library cache is force updated before returning results. - - Returns: - JSON response containing the existing content, filled with availability key-value pairs. - The availability has three available states: "Unavailable", "Partial", and "Available". - """ - try: - # Get Sonarr's collection - results = cache.handler( - "sonarr library", - function=self.get_sonarr_library, - cache_duration=ARR_LIBRARY_CACHE_TIMEOUT, - force_update_cache=force_update_cache, - ) - - # Find our TVDB ID within Sonarr - if isinstance(results, dict) and results.__contains__(str(tvdb_id)): - series = results[str(tvdb_id)] - - # Obtain season information if needed - if obtain_season_info: - # Set the season and episode availability - self._season_episode_availability(series) - - return series - - # Couldn't find the series - log.handler( - "Series with TVDB ID " + str(tvdb_id) + " not found within Sonarr.", - log.INFO, - _logger, - ) - - except KeyError: - log.handler( - "Content not ready yet!", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to get content!", - log.ERROR, - _logger, - ) - return None - - def add( - self, tvdb_id, quality_profile_id, root_dir, series_type, season_folders=True - ): - """Adds a new series using Sonarr. - Will not work for content that already exists. - This does NOT mark content as monitored or perform a search. - - Args: - tvdb_id: A string containing the TVDB ID. - quality_profile_id: An integer containing the quality profile ID (required). - root_dir: A string containing the root directory (required). - series_type: String containing Standard/Anime/Daily (required). - season_folders: Boolean whether to use season folders - - Returns: - JSON response of adding the content. - """ - try: - # Add the show to Sonarr's collection - series_id = self.__sonarr.add_series( - tvdb_id, - quality_profile_id, - root_dir, - season_folder=season_folders, - monitored=False, - ignore_episodes_with_files=True, - ignore_episodes_without_files=True, - )["id"] - - # Obtain all information that Sonarr collected about the series - new_series = self.__sonarr.get_series(series_id) - - # Set the series type - new_series["seriesType"] = series_type.lower().capitalize() - return self.__sonarr.upd_series(new_series) - - except Exception: - log.handler( - "Failed to add content!", - log.ERROR, - _logger, - ) - return None - - def request(self, sonarr_id, seasons=None, episode_ids=None): - """Monitors and searches for an existing series, season(s), and/or episode(s) using Sonarr. - - Args: - sonarr_id: An integer containing the Sonarr ID. - seasons: A list of integers containing the specific season numbers values (optional). - episode_ids: A list of integers containing the specific "episodeId" values (optional). - - Returns: - Dict containing - "season_update_results", - "episode_update_results", - "show_search_results", - "season_search_results", - "episode_search_results" - """ - try: - # Search for a show with a specific Sonarr ID. - response = { - "season_update_results": [], - "episode_update_results": [], - "show_search_results": [], - "season_search_results": [], - "episode_search_results": [], - } - - # Set the series as monitored - series = self.__sonarr.get_series(sonarr_id) - series["monitored"] = True - - for season in series["seasons"]: - # Set specific seasons as monitored - if seasons and season["seasonNumber"] in seasons: - season["monitored"] = True - - # Set every season as monitored if "select all" was used - elif not seasons and not episode_ids and season["seasonNumber"] != 0: - season["monitored"] = True - - # Save the season changes to Sonarr - response["season_update_results"] = self.__sonarr.upd_series(series) - - # Get the episodes - episodes = self.__sonarr.get_episodes_by_series_id(sonarr_id) - modified_episodes = [] - response["episode_update_results"] = [] - - for episode in episodes: - # Set every episode as monitored if "select all" was used - if not episode_ids and not seasons: - if episode["seasonNumber"] != 0: - episode["monitored"] = True - modified_episodes.append(episode) - - # Set episodes as monitored if they are contained within a requested season - elif episode["seasonNumber"] in seasons: - if episode["seasonNumber"] != 0: - episode["monitored"] = True - modified_episodes.append(episode) - - # Set specific episodes as monitored - elif episode_ids and episode["id"] in episode_ids: - episode["monitored"] = True - modified_episodes.append(episode) - - # Save the episode changes to Sonarr - for episode in modified_episodes: - response["episode_update_results"].append( - self.__sonarr.upd_episode(episode) - ) - - # Search for the whole show - if not seasons and not episode_ids: - response["show_search_results"] = self.__sonarr.post_command( - name="SeriesSearch", seriesId=sonarr_id - ) - return response - - # Search for specific seasons - if seasons: - response["season_search_results"] = [] - for season in seasons: - response["season_search_results"].append( - self.__sonarr.post_command( - name="SeasonSearch", - seriesId=sonarr_id, - seasonNumber=season, - ) - ) - - # Search for specific episodes - if episode_ids: - response["episode_search_results"] = self.__sonarr.post_command( - name="EpisodeSearch", - episodeIds=episode_ids, - ) - - return response - - except Exception: - log.handler( - "Failed to request content!", - log.ERROR, - _logger, - ) - return None - - def delete(self, sonarr_id): - """Deletes an existing series using Sonarr. - - Args: - sonarr_id: An integer containing the Sonarr show ID. - - Returns: - JSON response of removing the content. - """ - # TODO: Need to blacklist deleted content. - try: - # Remove a show with a specific Sonarr ID. - return self.__sonarr.del_series(sonarr_id, delete_files=True) - - except Exception: - log.handler( - "Failed to delete series!", - log.ERROR, - _logger, - ) - return None - - def delete_episode(self, episode_file_id): - """Deletes episode(s) using Sonarr. - - Args: - episode_file_id: Integer containing the specific "episodeFileId" value. - - Returns: - JSON response of removing the content. - """ - # TODO: Need to blacklist deleted content. - try: - return self.__sonarr.del_episode_file(episode_file_id) - - except Exception: - log.handler( - "Failed to delete episode!", - log.ERROR, - _logger, - ) - return None - - def check_sonarr_defaults(self): - """Will configure default root dirs and quality profiles (if unset)""" - if self.conreq_config.sonarr_enabled: - sonarr_tv_folder = self.conreq_config.sonarr_tv_folder - sonarr_anime_folder = self.conreq_config.sonarr_anime_folder - sonarr_tv_quality_profile = self.conreq_config.sonarr_tv_quality_profile - sonarr_anime_quality_profile = ( - self.conreq_config.sonarr_anime_quality_profile - ) - - # Root dirs - if not sonarr_tv_folder or not sonarr_anime_folder: - default_dir = self.sonarr_root_dirs()[0]["id"] - if not sonarr_tv_folder: - self.conreq_config.sonarr_tv_folder = default_dir - if not sonarr_anime_folder: - self.conreq_config.sonarr_anime_folder = default_dir - - # Qualtiy Profiles - if not sonarr_tv_quality_profile or not sonarr_anime_quality_profile: - default_profile = self.sonarr_quality_profiles()[0]["id"] - if not sonarr_tv_quality_profile: - self.conreq_config.sonarr_tv_quality_profile = default_profile - if not sonarr_anime_quality_profile: - self.conreq_config.sonarr_anime_quality_profile = default_profile - - # Save to DB - if self.conreq_config.tracker.changed(): - self.conreq_config.clean_fields() - self.conreq_config.save() - - def sonarr_root_dirs(self): - """Returns the root dirs available within Sonarr""" - try: - return self.__sonarr.get_root_folder() - - except Exception: - log.handler( - "Failed to get sonarr root dirs!", - log.ERROR, - _logger, - ) - return None - - def sonarr_quality_profiles(self): - """Returns the quality profiles available within Sonarr""" - try: - return self.__sonarr.get_quality_profile() - - except Exception: - log.handler( - "Failed to get sonarr quality profiles!", - log.ERROR, - _logger, - ) - return None - - def refresh_library(self): - """Refreshes our local copy of Sonarr's library""" - try: - if self.conreq_config.sonarr_enabled: - cache.handler( - "sonarr library", - function=self.get_sonarr_library, - cache_duration=ARR_LIBRARY_CACHE_TIMEOUT, - force_update_cache=True, - ) - except Exception: - log.handler( - "Failed to refresh sonarr!", - log.WARNING, - _logger, - ) - - def get_sonarr_library(self): - """Fetches everything within Sonarr's library""" - try: - if self.conreq_config.sonarr_enabled: - if self.conreq_config.sonarr_url and self.conreq_config.sonarr_api_key: - # Get the latest list of Sonarr's collection - results = self.__sonarr.get_series() - - # Set up a dictionary of results with IDs as keys - results_with_ids = {} - for series in results: - if series.__contains__("tvdbId"): - self._check_availability(series) - self._set_content_attributes("tv", "sonarr", series) - results_with_ids[str(series["tvdbId"])] = series - - # Return all series - return results_with_ids - - log.handler( - "Sonarr URL or API key is unset!", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Could not get series!", - log.ERROR, - _logger, - ) - return None - - def _season_episode_availability(self, series): - """Checks the availability of seasons.""" - # Obtain the episodes - episodes = self.__sonarr.get_episodes_by_series_id(series["id"]) - for season in series["seasons"]: - # Set the season availability - self._check_availability(season["statistics"]) - - # Set the episode availability - season["episodes"] = [] - for episode in episodes: - if episode["seasonNumber"] == season["seasonNumber"]: - self._check_availability(episode) - season["episodes"].append(episode) diff --git a/conreq/core/arrs/tasks.py b/conreq/core/arrs/tasks.py deleted file mode 100644 index a939722a..00000000 --- a/conreq/core/arrs/tasks.py +++ /dev/null @@ -1,21 +0,0 @@ -from huey import crontab -from huey.contrib.djhuey import db_periodic_task - -from conreq.utils.environment import get_str_from_env - -from .radarr import RadarrManager -from .sonarr import SonarrManager - -ARR_REFRESH_INTERNAL = get_str_from_env("ARR_REFRESH_INTERNAL", "*/1") - - -@db_periodic_task(crontab(minute=ARR_REFRESH_INTERNAL, strict=True)) -def refresh_radarr_library(): - """Checks Radarr for new entries.""" - RadarrManager().refresh_library() - - -@db_periodic_task(crontab(minute=ARR_REFRESH_INTERNAL, strict=True)) -def refresh_sonarr_library(): - """Checks Sonarr for new entries.""" - SonarrManager().refresh_library() diff --git a/conreq/core/base/apps.py b/conreq/core/base/apps.py deleted file mode 100644 index 49b695bb..00000000 --- a/conreq/core/base/apps.py +++ /dev/null @@ -1,29 +0,0 @@ -from sqlite3 import Connection - -from django.apps import AppConfig -from django.db.backends.signals import connection_created - - -class BaseConfig(AppConfig): - name = "conreq.core.base" - - -# pylint: disable=unused-argument -@connection_created.connect -def sqlite_connect(sender, connection: Connection, **kwargs): - """Enable integrity constraint with sqlite.""" - if connection.vendor == "sqlite": - cursor = connection.cursor() - cursor.execute("PRAGMA journal_mode = WAL;") - cursor.execute("PRAGMA synchronous = NORMAL;") - cursor.execute("PRAGMA temp_store = MEMORY;") - cursor.execute("PRAGMA foreign_keys = ON;") - - -@connection_created.disconnect -def sqlite_disconnect(sender, connection: Connection, **kwargs): - """Enable integrity constraint with sqlite.""" - if connection.vendor == "sqlite": - cursor = connection.cursor() - cursor.execute("PRAGMA analysis_limit = 400;") - cursor.execute("PRAGMA optimize;") diff --git a/conreq/core/base/fields.py b/conreq/core/base/fields.py deleted file mode 100644 index 02c5b494..00000000 --- a/conreq/core/base/fields.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.db.models import URLField - -from . import forms, validators - - -class ExtendedURLField(URLField): - """URL field that supports hostnames (ex. https://sonarr:8000)""" - default_validators = [validators.ExtendedURLValidator()] - - def formfield(self, **kwargs): - # As with CharField, this will cause URL validation to be performed - # twice. - return super().formfield( - **{ - "form_class": forms.ExtendedURLField, - **kwargs, - } - ) diff --git a/conreq/core/base/forms.py b/conreq/core/base/forms.py deleted file mode 100644 index 1aaaa468..00000000 --- a/conreq/core/base/forms.py +++ /dev/null @@ -1,23 +0,0 @@ -from django import forms -from django.contrib.auth import get_user_model -from django.contrib.auth.forms import UserCreationForm -from django.forms import URLField - -from . import validators - - -class ExtendedURLField(URLField): - """URL field that supports hostnames (ex. https://sonarr:8000)""" - - default_validators = [validators.ExtendedURLValidator()] - - -class InitializationForm(UserCreationForm): - sonarr_url = ExtendedURLField(max_length=255, required=False) - sonarr_api_key = forms.CharField(max_length=255, required=False) - radarr_url = ExtendedURLField(max_length=255, required=False) - radarr_api_key = forms.CharField(max_length=255, required=False) - - class Meta: - model = get_user_model() - fields = ("username", "email", "password1", "password2") diff --git a/conreq/core/base/helpers.py b/conreq/core/base/helpers.py deleted file mode 100644 index cb91d656..00000000 --- a/conreq/core/base/helpers.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Helpers for Base""" - - -def initialize_conreq(conreq_config, form): - """Sets up the initial database values during Conreq's first run sequence.""" - # Obtain the sonarr/radarr parameters - conreq_config.sonarr_url = form.cleaned_data.get("sonarr_url") - conreq_config.sonarr_api_key = form.cleaned_data.get("sonarr_api_key") - conreq_config.radarr_url = form.cleaned_data.get("radarr_url") - conreq_config.radarr_api_key = form.cleaned_data.get("radarr_api_key") - - # Enable Sonarr if URL and API key is configured - if conreq_config.sonarr_url and conreq_config.sonarr_api_key: - conreq_config.sonarr_enabled = True - - # Enable Radarr if URL and API key is configured - if conreq_config.radarr_url and conreq_config.radarr_api_key: - conreq_config.radarr_enabled = True - - # Remember that the database has been initialized - conreq_config.conreq_initialized = True - conreq_config.save() diff --git a/conreq/core/base/management/commands/preconfig_conreq.py b/conreq/core/base/management/commands/preconfig_conreq.py deleted file mode 100644 index 12124cc0..00000000 --- a/conreq/core/base/management/commands/preconfig_conreq.py +++ /dev/null @@ -1,120 +0,0 @@ -import os -import shutil -import sqlite3 -import sys - -from django.conf import settings -from django.core.management import call_command -from django.core.management.base import BaseCommand - -from conreq.utils.environment import get_database_type, get_debug - -DEBUG = get_debug() -BASE_DIR = getattr(settings, "BASE_DIR") -DATA_DIR = getattr(settings, "DATA_DIR") -DATABASES = getattr(settings, "DATABASES") -HUEY_FILENAME = getattr(settings, "HUEY_FILENAME") - - -class Command(BaseCommand): - """Executes functions that may require admin privileges, - since it is expected that run_conreq is executed as a user.""" - - help = "Runs code that may be required prior to run_conreq Conreq." - - def handle(self, *args, **options): - uid = options["uid"] - gid = options["gid"] - no_perms = options["no_perms"] - - print("Preconfiguring Conreq...") - - # Django database - if get_database_type() == "SQLITE3": - database = DATABASES["default"]["NAME"] - self.setup_sqlite_database(database, "Conreq", uid, gid, no_perms) - - # Background task database - if HUEY_FILENAME: - self.setup_sqlite_database( - HUEY_FILENAME, "Background Task", uid, gid, no_perms - ) - - if DEBUG: - # Migrate silk due to their wonky dev choices - call_command("makemigrations", "silk") - - if not no_perms and sys.platform == "linux": - # Conreq data dir - self.recursive_chown(DATA_DIR, uid, gid) - - # Conreq core dir - self.recursive_chown(BASE_DIR, uid, gid) - - def add_arguments(self, parser): - parser.add_argument( - "uid", - nargs="?", - help="User ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", - type=int, - default=0, - ) - parser.add_argument( - "gid", - nargs="?", - help="Group ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", - type=int, - default=0, - ) - - parser.add_argument( - "--no-perms", - action="store_true", - help="Prevent Conreq from setting permissions.", - ) - - @staticmethod - def setup_sqlite_database(path, name, uid, gid, no_perms): - print(name.rstrip(" ") + " Database") - if not os.path.exists(path): - print("> Creating database") - with sqlite3.connect(path) as cursor: - print("> Vacuuming database") - cursor.execute("VACUUM") - print("> Configuring database") - cursor.execute("PRAGMA journal_mode = WAL;") - if not no_perms and (uid != -1 or gid != -1) and sys.platform == "linux": - # pylint: disable=no-member - print("> Applying permissions") - new_uid = uid or os.getuid() - new_gid = gid or os.getgid() - os.chown(path, new_uid, new_gid) - print("> Complete") - - @staticmethod - def recursive_chown(path, uid, gid): - print('Recursively applying permissions to "' + path + '"') - new_uid = uid if uid != -1 else None - new_gid = gid if gid != -1 else None - if uid != -1 or gid != -1: - # pylint: disable=unused-variable - for dirpath, dirnames, filenames in os.walk(path): - try: - shutil.chown(dirpath, new_uid, new_gid) - try: - for filename in filenames: - shutil.chown( - os.path.join(dirpath, filename), new_uid, new_gid - ) - except FileNotFoundError: - print( - 'Unable to apply permissions to "' - + os.path.join(dirpath, filename) - + '". File not found.' - ) - except PermissionError: - print( - 'Unable to apply permissions to "' - + dirpath - + '". Permission denied.' - ) diff --git a/conreq/core/base/management/commands/run_conreq.py b/conreq/core/base/management/commands/run_conreq.py deleted file mode 100644 index 9f36fe6f..00000000 --- a/conreq/core/base/management/commands/run_conreq.py +++ /dev/null @@ -1,134 +0,0 @@ -import os -import sqlite3 -from multiprocessing import Process - -import django -from django.conf import settings -from django.core.cache import cache -from django.core.management import call_command -from django.core.management.base import BaseCommand -from hypercorn.config import Config as HypercornConfig -from hypercorn.run import run as run_hypercorn - -from conreq.utils.environment import get_debug - -HYPERCORN_TOML = os.path.join(getattr(settings, "DATA_DIR"), "hypercorn.toml") -DEBUG = get_debug() -HUEY_FILENAME = getattr(settings, "HUEY_FILENAME") -ACCESS_LOG_FILE = getattr(settings, "ACCESS_LOG_FILE") - - -class Command(BaseCommand): - help = "Runs all commands needed to safely start Conreq." - - def handle(self, *args, **options): - port = options["port"] - verbosity = "-v 1" if DEBUG else "-v 0" - - # Run any preconfiguration tasks - if not options["disable_preconfig"]: - preconfig_args = [ - "preconfig_conreq", - options["uid"], - options["gid"], - ] - if not options["set_perms"]: - preconfig_args.append("--no-perms") - call_command(*preconfig_args) - - # Execute tests to ensure Conreq is healthy before starting - if not options["skip_checks"]: - call_command("test", "--noinput", "--parallel", "--failfast") - - # Perform any debug related clean-up - if DEBUG: - print("Conreq is in DEBUG mode.") - print("Clearing cache...") - cache.clear() - print("Removing stale background tasks...") - self.reset_huey_db() - - # Migrate the database - call_command("migrate", "--noinput", verbosity) - - if not DEBUG: - # Collect static files - call_command("collectstatic", "--link", "--clear", "--noinput", verbosity) - call_command("compress", "--force", verbosity) - - # Run background task management - proc = Process(target=self.start_huey, daemon=True) - proc.start() - - # Run the production webserver - if not DEBUG: - config = HypercornConfig() - config.bind = f"0.0.0.0:{port}" - config.websocket_ping_interval = 20 - config.workers = 3 - config.application_path = "conreq.asgi:application" - config.accesslog = ACCESS_LOG_FILE - - # Additonal webserver configuration - if os.path.exists(HYPERCORN_TOML): - config.from_toml(HYPERCORN_TOML) - - # Run the webserver - run_hypercorn(config) - - # Run the development webserver - if DEBUG: - call_command("runserver", f"0.0.0.0:{port}") - - def add_arguments(self, parser): - parser.add_argument( - "-p", - "--port", - help="Select the port number for Conreq to run on.", - default=8000, - type=int, - ) - - parser.add_argument( - "--disable-preconfig", - action="store_true", - help="Disables Conreq's preconfiguration prior to startup.", - ) - - parser.add_argument( - "--uid", - help="User ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", - type=int, - default=0, - ) - - parser.add_argument( - "--gid", - help="Group ID to chown to (Linux only). Defaults to the current user. Use -1 to remain unchanged.", - type=int, - default=0, - ) - - parser.add_argument( - "--set-perms", - action="store_true", - help="Have Conreq set permissions during preconfig.", - ) - - @staticmethod - def reset_huey_db(): - """Deletes all entries within the Huey background task database.""" - with sqlite3.connect(HUEY_FILENAME) as cursor: - tables = list( - cursor.execute("select name from sqlite_master where type is 'table'") - ) - cursor.executescript(";".join(["delete from %s" % i for i in tables])) - - @staticmethod - def start_huey(): - """Starts the Huey background task manager.""" - django.setup() - if DEBUG: - call_command("run_huey") - else: - call_command("run_huey", "--quiet") diff --git a/conreq/core/base/management/commands/start_conreq_app.py b/conreq/core/base/management/commands/start_conreq_app.py deleted file mode 100644 index ebf402d3..00000000 --- a/conreq/core/base/management/commands/start_conreq_app.py +++ /dev/null @@ -1,27 +0,0 @@ -import os - -from django.conf import settings -from django.core.management import call_command -from django.core.management.base import BaseCommand - -APPS_DIR = getattr(settings, "APPS_DIR") -BASE_DIR = getattr(settings, "BASE_DIR") -APP_TEMPLATE_DIR = os.path.join(BASE_DIR, "conreq", "app_template") - - -class Command(BaseCommand): - help = "Creates all files needed to start a new Conreq app." - - def handle(self, *args, **options): - call_command( - "startapp", - "--template=" + APP_TEMPLATE_DIR, - options["name"], - APPS_DIR, - ) - - def add_arguments(self, parser): - parser.add_argument( - "name", - help="Name of the new app.", - ) diff --git a/conreq/core/base/static/css/initialization.css b/conreq/core/base/static/css/initialization.css deleted file mode 100644 index f3881ed3..00000000 --- a/conreq/core/base/static/css/initialization.css +++ /dev/null @@ -1,46 +0,0 @@ -/* Input boxes that gets an error on validation */ -input.invalid { - background-color: #ffdddd; -} - -/* The active form tab */ -.tab { - display: none; - flex-direction: column; - width: 100%; - align-items: center; - justify-content: space-evenly; -} - -/* Current step indicator */ -.step { - height: 15px; - width: 15px; - margin: 0 2px; - background-color: #bbbbbb; - border: none; - border-radius: 50%; - display: inline-block; - opacity: 0.3; -} - -.step.active { - background: var(--accent-color); - opacity: 1; -} - -.step.finish { - background: var(--accent-color); - opacity: 0.5; -} - -/* Navigation controls */ -#prevBtn { - margin-right: 20px; -} - -#box-nav-container { - display: flex; - width: 90%; - justify-content: space-between; -} diff --git a/conreq/core/base/static/css/issues.css b/conreq/core/base/static/css/issues.css deleted file mode 100644 index 855aab03..00000000 --- a/conreq/core/base/static/css/issues.css +++ /dev/null @@ -1,48 +0,0 @@ -.issue-container { - padding: 15px; - border-radius: 8px; - background: #252525; - color: rgba(255, 255, 255, 0.75); - font-weight: 300; - line-height: 18px; - height: auto; - overflow: hidden; - width: 300px; -} - -.issue-container .content-type-icon { - position: absolute; - top: 10px; - right: 10px; -} - -.issue-container .issue-manage-icons { - position: absolute; - bottom: 10px; - right: 10px; -} - -.issue-container .issue-manage-icons .fas { - transition: 0.3s color ease; - margin-left: 10px; -} - -.issue-container .issue-manage-icons .fas:hover { - color: #fff; -} - -.issue-container .title { - font-weight: 700; -} - -.issue-container .category:not(:last-child) { - margin-bottom: 10px; -} - -.issue-container .category.content-name { - padding-right: 25px; -} - -.issue-container .category.content-name a { - display: block; -} diff --git a/conreq/core/base/static/css/libraries/magnific_popup_1.1.0.css b/conreq/core/base/static/css/libraries/magnific_popup_1.1.0.css deleted file mode 100644 index 8561e181..00000000 --- a/conreq/core/base/static/css/libraries/magnific_popup_1.1.0.css +++ /dev/null @@ -1,351 +0,0 @@ -/* Magnific Popup CSS */ -.mfp-bg { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1042; - overflow: hidden; - position: fixed; - background: #0b0b0b; - opacity: 0.8; } - -.mfp-wrap { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1043; - position: fixed; - outline: none !important; - -webkit-backface-visibility: hidden; } - -.mfp-container { - text-align: center; - position: absolute; - width: 100%; - height: 100%; - left: 0; - top: 0; - padding: 0 8px; - box-sizing: border-box; } - -.mfp-container:before { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; } - -.mfp-align-top .mfp-container:before { - display: none; } - -.mfp-content { - position: relative; - display: inline-block; - vertical-align: middle; - margin: 0 auto; - text-align: left; - z-index: 1045; } - -.mfp-inline-holder .mfp-content, -.mfp-ajax-holder .mfp-content { - width: 100%; - cursor: auto; } - -.mfp-ajax-cur { - cursor: progress; } - -.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { - cursor: -moz-zoom-out; - cursor: -webkit-zoom-out; - cursor: zoom-out; } - -.mfp-zoom { - cursor: pointer; - cursor: -webkit-zoom-in; - cursor: -moz-zoom-in; - cursor: zoom-in; } - -.mfp-auto-cursor .mfp-content { - cursor: auto; } - -.mfp-close, -.mfp-arrow, -.mfp-preloader, -.mfp-counter { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; } - -.mfp-loading.mfp-figure { - display: none; } - -.mfp-hide { - display: none !important; } - -.mfp-preloader { - color: #CCC; - position: absolute; - top: 50%; - width: auto; - text-align: center; - margin-top: -0.8em; - left: 8px; - right: 8px; - z-index: 1044; } - .mfp-preloader a { - color: #CCC; } - .mfp-preloader a:hover { - color: #FFF; } - -.mfp-s-ready .mfp-preloader { - display: none; } - -.mfp-s-error .mfp-content { - display: none; } - -button.mfp-close, -button.mfp-arrow { - overflow: visible; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; - display: block; - outline: none; - padding: 0; - z-index: 1046; - box-shadow: none; - touch-action: manipulation; } - -button::-moz-focus-inner { - padding: 0; - border: 0; } - -.mfp-close { - width: 44px; - height: 44px; - line-height: 44px; - position: absolute; - right: 0; - top: 0; - text-decoration: none; - text-align: center; - opacity: 0.65; - padding: 0 0 18px 10px; - color: #FFF; - font-style: normal; - font-size: 28px; - font-family: Arial, Baskerville, monospace; } - .mfp-close:hover, - .mfp-close:focus { - opacity: 1; } - .mfp-close:active { - top: 1px; } - -.mfp-close-btn-in .mfp-close { - color: #333; } - -.mfp-image-holder .mfp-close, -.mfp-iframe-holder .mfp-close { - color: #FFF; - right: -6px; - text-align: right; - padding-right: 6px; - width: 100%; } - -.mfp-counter { - position: absolute; - top: 0; - right: 0; - color: #CCC; - font-size: 12px; - line-height: 18px; - white-space: nowrap; } - -.mfp-arrow { - position: absolute; - opacity: 0.65; - margin: 0; - top: 50%; - margin-top: -55px; - padding: 0; - width: 90px; - height: 110px; - -webkit-tap-highlight-color: transparent; } - .mfp-arrow:active { - margin-top: -54px; } - .mfp-arrow:hover, - .mfp-arrow:focus { - opacity: 1; } - .mfp-arrow:before, - .mfp-arrow:after { - content: ''; - display: block; - width: 0; - height: 0; - position: absolute; - left: 0; - top: 0; - margin-top: 35px; - margin-left: 35px; - border: medium inset transparent; } - .mfp-arrow:after { - border-top-width: 13px; - border-bottom-width: 13px; - top: 8px; } - .mfp-arrow:before { - border-top-width: 21px; - border-bottom-width: 21px; - opacity: 0.7; } - -.mfp-arrow-left { - left: 0; } - .mfp-arrow-left:after { - border-right: 17px solid #FFF; - margin-left: 31px; } - .mfp-arrow-left:before { - margin-left: 25px; - border-right: 27px solid #3F3F3F; } - -.mfp-arrow-right { - right: 0; } - .mfp-arrow-right:after { - border-left: 17px solid #FFF; - margin-left: 39px; } - .mfp-arrow-right:before { - border-left: 27px solid #3F3F3F; } - -.mfp-iframe-holder { - padding-top: 40px; - padding-bottom: 40px; } - .mfp-iframe-holder .mfp-content { - line-height: 0; - width: 100%; - max-width: 900px; } - .mfp-iframe-holder .mfp-close { - top: -40px; } - -.mfp-iframe-scaler { - width: 100%; - height: 0; - overflow: hidden; - padding-top: 56.25%; } - .mfp-iframe-scaler iframe { - position: absolute; - display: block; - top: 0; - left: 0; - width: 100%; - height: 100%; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: #000; } - -/* Main image in popup */ -img.mfp-img { - width: auto; - max-width: 100%; - height: auto; - display: block; - line-height: 0; - box-sizing: border-box; - padding: 40px 0 40px; - margin: 0 auto; } - -/* The shadow behind the image */ -.mfp-figure { - line-height: 0; } - .mfp-figure:after { - content: ''; - position: absolute; - left: 0; - top: 40px; - bottom: 40px; - display: block; - right: 0; - width: auto; - height: auto; - z-index: -1; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: #444; } - .mfp-figure small { - color: #BDBDBD; - display: block; - font-size: 12px; - line-height: 14px; } - .mfp-figure figure { - margin: 0; } - -.mfp-bottom-bar { - margin-top: -36px; - position: absolute; - top: 100%; - left: 0; - width: 100%; - cursor: auto; } - -.mfp-title { - text-align: left; - line-height: 18px; - color: #F3F3F3; - word-wrap: break-word; - padding-right: 36px; } - -.mfp-image-holder .mfp-content { - max-width: 100%; } - -.mfp-gallery .mfp-image-holder .mfp-figure { - cursor: pointer; } - -@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { - /** - * Remove all paddings around the image on small screen - */ - .mfp-img-mobile .mfp-image-holder { - padding-left: 0; - padding-right: 0; } - .mfp-img-mobile img.mfp-img { - padding: 0; } - .mfp-img-mobile .mfp-figure:after { - top: 0; - bottom: 0; } - .mfp-img-mobile .mfp-figure small { - display: inline; - margin-left: 5px; } - .mfp-img-mobile .mfp-bottom-bar { - background: rgba(0, 0, 0, 0.6); - bottom: 0; - margin: 0; - top: auto; - padding: 3px 5px; - position: fixed; - box-sizing: border-box; } - .mfp-img-mobile .mfp-bottom-bar:empty { - padding: 0; } - .mfp-img-mobile .mfp-counter { - right: 5px; - top: 3px; } - .mfp-img-mobile .mfp-close { - top: 0; - right: 0; - width: 35px; - height: 35px; - line-height: 35px; - background: rgba(0, 0, 0, 0.6); - position: fixed; - text-align: center; - padding: 0; } } - -@media all and (max-width: 900px) { - .mfp-arrow { - -webkit-transform: scale(0.75); - transform: scale(0.75); } - .mfp-arrow-left { - -webkit-transform-origin: 0; - transform-origin: 0; } - .mfp-arrow-right { - -webkit-transform-origin: 100%; - transform-origin: 100%; } - .mfp-container { - padding-left: 6px; - padding-right: 6px; } } diff --git a/conreq/core/base/static/css/login.css b/conreq/core/base/static/css/login.css deleted file mode 100644 index 1b94216d..00000000 --- a/conreq/core/base/static/css/login.css +++ /dev/null @@ -1,3 +0,0 @@ -.sign-in-form { - margin-top: 35px; -} diff --git a/conreq/core/base/static/css/main.css b/conreq/core/base/static/css/main.css deleted file mode 100644 index f8351c37..00000000 --- a/conreq/core/base/static/css/main.css +++ /dev/null @@ -1,308 +0,0 @@ -:root { - /* Globals */ - --body-bg: linear-gradient( - 145deg, - rgba(18, 23, 25, 0.8), - rgba(18, 23, 25, 0.25), - rgba(18, 23, 25, 0.15), - rgba(0, 0, 0, 0) - ); - --large-card-bg: linear-gradient(90deg, #2a2a2a, hsl(0deg 0% 22%)); - --global-font: "Roboto", sans-serif; - --primary-font-size: 14px; - --secondary-font-size: 12px; - --box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), - 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12); - --accent-color: #258a6d; - --placeholder-bg: var(--poster-bg-color); - /* Sidebar */ - --sidebar-bg: rgb(30 31 30 / 30%); - --sidebar-width: 240px; - --navgroup-padding: 23px 20px 10px 20px; - --navpages-btn-padding: 13px 15px; - /* Navbar */ - --navbar-bg: rgba(255, 255, 255, 0.04); - --navbar-height: 0px; - --searchbar-width: 45%; - /* Viewport */ - --viewport-padding: 30px; - --viewport-total-padding: calc(var(--viewport-padding) * 2); - --viewport-left: var(--sidebar-width); - /* Posters */ - --poster-bg-color: #191919; - --poster-width: 150px; - --poster-height: calc(var(--poster-width) * 1.5); - --poster-container-height: calc(var(--poster-width) * 2.1); - --poster-details-height: calc( - var(--poster-container-height) - var(--poster-height) - ); - --poster-padding: 10px; - --poster-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.24), - 0 0 2px rgba(0, 0, 0, 0.12); - /* Poster Indicators */ - --tv-color: #0076a3; - --tv-indicator-hr: 2px solid var(--tv-color); - --movie-color: #b66707; - --movie-indicator-hr: 2px solid var(--movie-color); -} - -/* Generic rules */ - -html { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - height: 100%; - overflow: hidden; - font-family: var(--global-font); - scroll-behavior: smooth; - background: #363636; -} - -body { - background: var(--body-bg); - margin: 0px; - padding: 0px; - overflow-y: scroll; - box-sizing: content-box; - position: relative; - line-height: 1; - overflow: hidden; - width: 100%; - height: 100%; - z-index: 9999; -} - -a { - color: unset; - transition: 0.3s ease color; - text-decoration: none; -} - -a:hover { - color: #fff; - text-decoration: initial; -} - -:focus { - outline: none; -} - -.empty-viewport > div { - line-height: 2; -} - -.bold { - font-weight: 700; -} - -.red { - background-color: #ff0000; -} - -.green { - background-color: #39b54a; -} - -.yellow { - background-color: #ffff00; -} - -.inline-block { - display: inline-block; -} - -.inline { - display: inline; -} - -.light { - font-weight: 300; -} - -.box-shadow { - box-shadow: var(--box-shadow); -} - -.no-highlighting { - /* iOS Safari */ - -webkit-touch-callout: none; - /* Konqueror HTML */ - -webkit-user-select: none; - /* Old versions of Firefox */ - -moz-user-select: none; - /* Internet Explorer/Edge */ - -ms-user-select: none; - /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ - user-select: none; -} - -.clickable { - cursor: pointer; -} - -.line-clamp-1 { - display: block; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - text-overflow: ellipsis; - overflow: hidden; -} - -.opacity-1 { - opacity: 1 !important; -} - -.spinner-border { - z-index: 999; - margin: auto; - color: var(--accent-color); -} - -/* Text input boxes */ - -.pretty.p-switch.p-fill input:checked ~ .state:before { - border-color: var(--accent-color); - background-color: var(--accent-color) !important; -} - -::-webkit-input-placeholder { - opacity: 0.75; -} - -::-moz-placeholder { - opacity: 0.75; -} - -:-ms-input-placeholder { - opacity: 0.75; -} - -::-ms-input-placeholder { - opacity: 0.75; -} - -::placeholder { - opacity: 0.75; -} - -.text-input { - display: block; - border: none; - outline: none !important; - color: rgb(255 255 255 / 0.65); - padding: 10px; - font-size: var(--primary-font-size); - font-family: var(--global-font); - transition: background 0.3s ease, color 0.3s ease; - border-radius: 4px; - font-weight: 300; -} - -.text-input:focus { - background: #fff; - color: #252525; -} - -.text-input-container { - background: rgb(255 255 255 / 0.08); - border-radius: 4px; - transition: background 0.4s ease, color 0.4s ease; - color: rgb(255 255 255 / 0.75); - overflow: hidden; - height: 35px; -} - -.text-input-container:focus-within { - background: #fff; - color: #252525; -} - -.modal .text-input-container { - background: rgb(255 255 255 / 0.08); - color: rgb(255 255 255 / 0.75); -} - -.modal .text-input-container:focus-within { - background: #fff; - color: #252525; -} - -.text-input-container.error { - background: rgb(255 0 0 / 28%); -} - -.text-input-container.dropdown { - overflow: visible; -} - -.text-input-container input { - box-sizing: border-box; - height: 100%; - width: 100%; - background: none; - color: inherit; - border: none; - font-size: var(--primary-font-size); - padding-left: 15px; - padding-right: 15px; - outline: none !important; -} - -/* Images */ - -img.lazy { - opacity: 0; -} - -img.lazy.initial, -img.lazy.loaded, -img.lazy.error { - opacity: 1; -} - -img.lazy:not([src]) { - visibility: hidden; -} - -.mfp-bg { - z-index: 1061; -} - -.mfp-wrap { - z-index: 1062; -} - -/* Scrollbar */ - -.simplebar-scrollbar::before { - background-color: var(--accent-color); -} - -::-webkit-scrollbar { - width: 7px; - height: 7px; - background: transparent; -} - -.sidebar::-webkit-scrollbar { - display: none; -} - -::-webkit-scrollbar-thumb { - border-radius: 3px; - background: rgb(65 146 123 / 0.6); -} - -::-webkit-scrollbar-track, -::-webkit-scrollbar-corner { - display: none; -} - -/* Hide scrollbars for non-webkit browsers */ - -html * { - /* IE 11 */ - -ms-overflow-style: none; - /* Firefox 64 */ - scrollbar-width: none; -} diff --git a/conreq/core/base/static/css/manage_users.css b/conreq/core/base/static/css/manage_users.css deleted file mode 100644 index 3393c5bb..00000000 --- a/conreq/core/base/static/css/manage_users.css +++ /dev/null @@ -1,185 +0,0 @@ -.table { - table-layout: fixed; - border: none; - color: rgb(255 255 255 / 0.75); -} -.table-wrapper { - background: var(--large-card-bg); - padding: 20px 25px; - border-radius: 3px; - box-shadow: var(--box-shadow); -} -.table-wrapper .staff, -.table-wrapper .action { - width: 100px; -} -.table-title-container { - padding-bottom: 15px; - background: rgb(29 29 29); - color: #fff; - padding: 16px 30px; - margin: -20px -25px 10px; - border-radius: 3px 3px 0 0; -} -.table-title-container h2 { - margin: 0; - font-size: 24px; - width: auto; - padding: 0; -} -.table-title-container .row { - display: flex; - justify-content: space-between; - margin: 0; - align-items: center; -} -.table-title-container .btn { - color: #566787; - float: right; - font-size: 13px; - background: #fff; - min-width: 50px; - border-radius: 2px; - border: none; - outline: none !important; - margin-left: 10px; -} -.table-title-container .btn:hover, -.table-title-container .btn:focus { - color: #566787; - background: #f2f2f2; -} -.table-title-container .btn i { - float: left; - font-size: 21px; - margin-right: 5px; -} -.table-title-container .btn span { - float: left; - margin-top: 2px; -} -table.table tr th, -table.table tr td { - border-color: #e9e9e9; - padding: 12px 15px; - vertical-align: middle; - border-left: none; - border-right: none; -} -table.table tr th { - background: rgba(255, 255, 255, 0.05); -} -table.table th i { - font-size: 13px; - margin: 0 5px; -} -table.table td:last-child i { - opacity: 0.9; - font-size: 22px; - margin: 0 5px; -} -table.table tr th:last-child, -table.table tr td:last-child { - text-align: center; -} -table.table td a { - font-weight: bold; - color: #566787; - display: inline-block; - text-decoration: none; -} -table.table td i { - font-size: 19px; -} -table.table td { - overflow-y: auto; -} - -table.table-striped tbody tr:nth-of-type(odd) { - background: transparent; -} -table.table-striped.table-hover tbody tr:hover { - background: rgb(255 255 255 / 0.05); -} -.table-hover tbody tr:hover { - color: rgb(255 255 255 / 1); -} -.table-bordered > :not(caption) > * { - border: none; -} -table.table .avatar { - border-radius: 50%; - vertical-align: middle; - margin-right: 10px; -} -.status { - font-size: 30px; - margin: 2px 2px 0 0; - display: inline-block; - vertical-align: middle; - line-height: 10px; -} -.text-success { - color: #10c469; -} -.text-info { - color: #62c9e8; -} -.text-warning { - color: #ffc107; -} -.text-danger { - color: #ff5b5b; -} -.pagination { - font-weight: 700; - float: right; -} -.pagination li a { - border: none; - font-size: 13px; - min-width: 30px; - min-height: 30px; - color: #999; - margin: 0 2px; - line-height: 30px; - border-radius: 2px !important; - text-align: center; - padding: 0 6px; -} -.pagination li a:hover { - color: #fff; -} -.pagination li.active a, -.pagination li.active a.page-link { - background: #03a9f4; -} -.pagination li.active a:hover { - background: #0397d6; -} -.pagination li.disabled i { - color: #ccc; -} -.pagination li i { - font-size: 16px; - padding-top: 6px; -} -.pagination li:not(.active) a { - background: none; -} -.pagination li.active a.page-link { - background: var(--accent-color); -} -.page-link:focus { - box-shadow: none; -} -.bootstrap-table .fixed-table-container .table thead .asc, -.bootstrap-table .fixed-table-container .table thead .desc { - -webkit-filter: brightness(100); - filter: brightness(100); -} -.hint-text { - float: left; - margin-top: 10px; - font-size: 13px; -} diff --git a/conreq/core/base/static/css/mobile.css b/conreq/core/base/static/css/mobile.css deleted file mode 100644 index 08b8c732..00000000 --- a/conreq/core/base/static/css/mobile.css +++ /dev/null @@ -1,283 +0,0 @@ -@media only screen and (max-width: 1300px) { - /* Tables */ - .table-wrapper .joined { - display: none; - } -} - -@media only screen and (max-width: 1250px) { - /* Settings Menu */ - .settings-input-group { - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - } -} - -@media only screen and (max-width: 1150px) { - :root { - /* Sidebar */ - --sidebar-width: 200px; - /* Videos */ - --video-height: calc(var(--video-width) * 0.5625); - --video-width: 30vw; - /* Artwork */ - --artwork-height: calc(var(--video-width) * 0.5625); - --artwork-width: 30vw; - } - /* Tables */ - .table-wrapper .last-seen { - display: none; - } -} -@media only screen and (max-width: 1000px) { - /* Posters */ - .viewport .poster-container .fa-angle-down { - display: none; - } - /* More Info */ - .more-info-topbar .report-modal-btn, - .more-info-topbar .report-selection-modal-btn, - .more-info-topbar .series-modal-btn, - .more-info-topbar .request-btn { - font-size: 0; - display: flex; - align-items: center; - justify-content: center; - } - .more-info-topbar .standard-btn .fas { - font-size: 22px; - } - .more-info-quick-info { - grid-template-columns: repeat(4, auto); - } -} - -@media only screen and (max-width: 880px) { - :root { - /* More Info Grid */ - --left-column-width: 175px; - } - /* Tables */ - .table-wrapper .staff { - display: none; - } - .more-info-quick-info { - grid-template-columns: repeat(3, auto); - } -} - -@media only screen and (max-width: 800px) { - :root { - /* Sidebar */ - --sidebar-width: 100%; - /* Navbar */ - --searchbar-width: 80%; - --navbar-height: 45px; - /* Viewport */ - --viewport-left: 0; - --viewport-padding: 15px; - --primary-font-size: 16px; - /* Posters */ - --poster-width: calc( - ( - 100vw - (var(--poster-padding) * 3) - - (var(--viewport-total-padding) * 2) - ) / 4 - ); - /* Videos */ - --video-height: calc(var(--video-width) * 0.5625); - --video-width: 70vw; - /* Artwork */ - --artwork-height: calc(var(--video-width) * 0.5625); - --artwork-width: 70vw; - /* More Info */ - --more-info-section-padding: 0; - --more-info-section-spacing: 45px; - } - ::-webkit-scrollbar { - display: none; - } - .navbar { - z-index: 100; - display: flex; - flex-wrap: nowrap; - justify-content: flex-start; - } - .searchbar { - width: auto; - margin-bottom: 15px; - margin-left: 10px; - margin-right: 10px; - } - .sidebar { - z-index: 99; - transition: height 0.4s ease-in; - background: #1f1f1f; - } - .sidebar.collapsed { - display: none; - } - .nav-tab .fas { - opacity: 1; - margin: 0; - padding: var(--navpages-btn-padding); - padding-left: 20px; - } - .viewport-container, - .viewport-container-top, - .viewport-loader { - z-index: 4; - width: 100vw; - } - .navbar .navbar-toggler { - display: inline-block; - border: none; - padding-left: 0; - padding-right: 0; - background: none; - } - /* More Info */ - .tns-ovh { - overflow: visible; - } - .more-info-topbar { - display: flex; - flex-direction: column; - width: 100%; - } - .more-info-poster-container { - margin: 0 auto; - width: 55vw; - } - .more-info-poster-container img { - height: calc(55vw * 1.5); - } - .more-info-topbar .standard-btn.available { - display: none; - } - .tns-controls { - display: none; - } - .more-info-overview { - margin-top: 15px; - } - .main-title { - margin-top: 25px; - font-size: 26px; - } - .main-rating { - font-size: 16px; - display: block; - width: -webkit-fit-content; - width: -moz-fit-content; - width: fit-content; - margin-bottom: 10px; - } - .more-info-main-info { - margin-top: 0; - } - .more-info { - margin-bottom: 80px; - padding-left: 10px; - padding-right: 10px; - } - .tns-inner { - margin: 0 !important; - } - .viewport .carousel .section-title { - padding-bottom: 15px; - } - .more-info-quick-info-container { - margin-left: 0; - margin-right: 0; - } - /* Settings Menu */ - .settings-input-group { - grid-template-columns: minmax(0, 1fr); - } - /* Posters */ - .viewport .poster-container .poster-description-container { - opacity: 1 !important; - } - .viewport .poster-container > a > .content-type-icon { - opacity: 1; - } - .viewport .poster-container .requested-by { - opacity: 1; - } - /* Issue Reporting */ - .issue-container .issue-manage-icons .fas { - font-size: 20px; - padding: 5px; - } - /* Manage Users */ - .table-wrapper { - padding: 0; - } - .table-title-container { - margin: 0; - } - .table-wrapper .fixed-table-pagination, - .table-wrapper .fixed-table-toolbar { - margin-left: 10px; - margin-right: 10px; - } -} - -@media only screen and (max-width: 600px) { - :root { - /* Posters */ - --poster-width: calc( - ( - 100vw - (var(--poster-padding) * 2) - - (var(--viewport-total-padding) * 2) - ) / 3 - ); - } - /* Tables */ - .table-wrapper .email, - .table-wrapper .table-title { - display: none !important; - } - .table-wrapper .row { - flex-direction: row-reverse; - } - /* More Info */ - .more-info-quick-info { - grid-template-columns: repeat(2, auto); - } -} - -@media only screen and (max-width: 450px) { - :root { - /* Posters */ - --poster-width: calc( - ( - 100vw - var(--poster-padding) - - (var(--viewport-total-padding) * 2) - ) / 2 - ); - } - /* More Info */ - .more-info-quick-info { - grid-template-columns: repeat(1, auto); - } -} - -/* Modals */ -@media only screen and (max-width: 991px) { - .modal-body.filter .simple-filter-container { - display: flex; - flex-wrap: wrap; - } - .modal-body.filter .simple-filter-toggle-container { - flex-direction: column; - margin: 0 6px; - } - .modal-body.filter .simple-filter-toggle-container > *:not(:last-child) { - margin-bottom: 10px; - } - .modal-body .simple-filter-btn { - padding: 15px 25px; - width: 100%; - } -} diff --git a/conreq/core/base/static/css/modal.css b/conreq/core/base/static/css/modal.css deleted file mode 100644 index e9f4dfa2..00000000 --- a/conreq/core/base/static/css/modal.css +++ /dev/null @@ -1,300 +0,0 @@ -/* Modal Container */ - -.modal-open .modal { - overflow: hidden; -} - -.modal-content { - background: #3f3f3f; -} - -/* Modal Body */ - -.modal-body { - background: #252525; - color: #fff; - padding: 0; - max-height: 50vh; - overflow-y: auto; - overflow-y: overlay; -} - -/* Modal Header */ - -.modal-header { - border: none; - align-items: center; - justify-content: space-between; - flex-direction: row-reverse; -} - -.modal-header.mini { - align-items: flex-end; - justify-content: flex-end; - flex-direction: row; -} - -.modal-header .fas { - color: rgba(255, 255, 255, 0.7); - font-size: 20px; - transition: color 0.3s ease; -} - -.modal-header-btn-container { - padding-left: 25px; -} - -.modal-header .fas:hover { - color: #fff; -} - -.modal-header .title { - color: #fff; - font-weight: 700; - line-height: 1; - overflow-wrap: anywhere; -} - -/* Modal Footer */ - -.modal-footer { - border: none; -} - -.standard-btn.select-all-btn:not(.available) { - background: #6d6d6d; - margin-right: 16px; -} - -.standard-btn.select-all-btn:hover:not(.available) { - background: #828282; -} - -/* Seasons/Episode Modal Styling */ - -.row-container { - padding: 0px 15px; - display: grid; - grid-template-columns: 30px auto 30px; -} - -.row-container > * { - padding: 15px 0px; -} - -.row-container .fa-angle-down { - grid-column: 3; - color: rgba(255, 255, 255, 0.7); - height: auto; - width: 100%; - text-align: center; - font-size: 20px; -} - -.row-container .fa-angle-down:hover { - color: #fff; -} - -.row-container .fa-angle-down:not(.collapsed) { - transform: rotate(180deg); -} - -.row-container .row-title { - font-weight: 700; - color: rgba(255, 255, 255, 0.7); - line-height: 24px; - display: flex; - align-items: center; - height: 24px; -} - -.row-container .row-collapse-icon-container { - display: flex; - justify-content: center; - align-items: center; -} - -.suboption-row-container { - padding: 7px 15px; - display: grid; - grid-template-columns: 30px auto; - color: rgba(255, 255, 255, 0.5); -} - -.suboption-row-container > .checkbox-container { - grid-column: 1; -} - -.suboption-row-container .suboption-title-container { - color: rgba(255, 255, 255, 0.5); - grid-column: 2; - line-height: 20px; - display: flex; - align-items: center; - height: 20px; -} - -.suboption-row-container - .suboption-title-container - > *:not(.modal-dot-container) { - display: inline-block; - display: -webkit-inline-box; - margin-right: 5px; -} - -.all-suboptions-container { - background: rgba(255, 255, 255, 0.03); -} - -.checkbox-container, -.row-title-container { - display: flex; - align-items: center; - justify-content: flex-start; - width: -webkit-fit-content; - width: -moz-fit-content; - width: fit-content; -} - -.modal-dot { - width: 5px; - height: 5px; - border-radius: 50%; -} - -.modal-dot-container { - padding-left: 5px; - padding-right: 10px; - display: flex; - justify-content: center; - align-items: center; - height: 100%; -} - -/* Content Preview Modal */ -.modal-content.content-preview { - display: flex; - flex-direction: row; - justify-content: space-between; -} - -.modal-content.content-preview .poster-container { - min-width: 35%; - padding: 25px; - display: flex; - align-items: center; - justify-content: center; -} - -.modal-content.content-preview .poster { - border-radius: 6px; - width: 100%; - -o-object-fit: contain; - object-fit: contain; - background: var(--poster-bg-color); -} - -.modal-content.content-preview .grid-modal-right { - display: flex; - flex-direction: column; - justify-content: space-between; - min-width: 65%; -} - -.modal-content.content-preview .modal-header { - height: -webkit-min-content; - height: -moz-min-content; - height: min-content; -} - -.modal-content.content-preview .modal-footer { - height: -webkit-min-content; - height: -moz-min-content; - height: min-content; -} - -.modal-content.content-preview .info { - height: auto; - margin-right: 25px; -} - -.modal-content.content-preview .title { - font-size: 24px; - color: rgba(255, 255, 255, 0.7); - margin-bottom: 10px; -} - -.modal-content.content-preview .description { - color: rgba(255, 255, 255, 0.7); - font-size: 16px; - margin-top: 10px; - padding-right: 10px; - line-height: 1.25; - min-height: 150px; - max-height: 250px; - overflow-y: auto; -} - -.mini-info-bar { - display: grid; - grid-template-columns: repeat(2, auto); - grid-template-rows: -webkit-min-content -webkit-min-content -webkit-min-content; - grid-template-rows: min-content min-content min-content; - background: #252525; - padding: 13px; - padding-top: 6px; - padding-left: 8px; - border-radius: 5px; -} - -.modal-info-block { - color: rgba(255, 255, 255, 0.7); - margin-top: 7px; - margin-left: 5px; - font-size: 14.5px; -} - -.modal-info { - display: inline; -} - -.modal-info.bold { - margin-right: 5px; -} - -/* Filter Modal */ -.modal-body.filter .simple-filter-container { - padding: 20px; - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); - grid-auto-rows: minmax(0, 1fr); -} - -.modal-body.filter .simple-filter-toggle-container { - padding: 20px; - padding-bottom: 0; - display: flex; - justify-content: center; -} - -.modal-body .simple-filter-btn { - font-size: 22px; - font-weight: 600; - padding: 15px 30px; - background: #00695c; - border-radius: 4px; - margin: 6px; - transition: background 0.3s ease; -} - -.modal-body .simple-filter-btn:hover { - background: #009688; -} - -/* Manage User */ -.modal-body.manage-user { - padding: 15px; -} -.manage-user-input { - padding-bottom: 20px; -} diff --git a/conreq/core/base/static/css/more_info.css b/conreq/core/base/static/css/more_info.css deleted file mode 100644 index 66b53764..00000000 --- a/conreq/core/base/static/css/more_info.css +++ /dev/null @@ -1,584 +0,0 @@ -:root { - --movie-indicator: #b66707; - --more-info-section-spacing: 20px; - --more-info-section-padding: 20px; - --left-column-width: 250px; - --right-column-width: auto; - --cast-poster-card-height: calc( - var(--poster-height) + var(--cast-poster-card-details-height) - ); - --cast-poster-card-details-height: 70px; - --artwork-height: 200px; - --artwork-width: calc(var(--artwork-height) * 1.77); - --video-height: 300px; - --video-width: calc(var(--video-height) * 1.77); - --backdrop-height: 400px; -} - -/* Right Side */ - -.more-info-main-info { - width: 100%; - display: inline-block; - padding-left: var(--more-info-section-padding); - margin-top: 115px; -} - -.more-info-quick-info-container { - margin-top: 40px; - margin-left: 20px; - margin-right: 20px; -} - -.more-info-quick-info { - box-sizing: border-box; - width: 100%; - border-radius: 4px; - font-family: "Roboto", sans-serif; - font-weight: 400; - font-size: 15px; - display: grid; - grid-template-columns: repeat(5, auto); - gap: 15px; -} - -.more-info-quick-info.collapse:not(.show) { - height: 95px; - display: grid; - overflow: hidden; - -webkit-mask-image: linear-gradient( - to bottom, - rgba(0, 0, 0, 1), - rgba(0, 0, 0, 0) - ); - mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); - pointer-events: none; -} - -.quick-info-read-more-btn { - width: 100%; - text-align: center; - font-weight: 700; - font-size: 14px; -} - -.inline-availablity-dot { - width: 6px; - height: 6px; - border-radius: 50%; - display: inline-block; - margin-bottom: 2px; - margin-left: 5px; - border: 1px solid rgba(0, 0, 0, 0.3); -} - -.main-title { - margin-bottom: 10px; - font-family: var(--global-font); - font-weight: 700; - font-size: 38px; - color: #fff; - text-shadow: 1px 1px 5px #000; -} - -.main-rating { - background: #252525; - border-radius: 6px; - color: rgba(255, 255, 255, 0.8); - display: inline-block; - font-size: 20px; - padding: 8px 11px; - box-shadow: var(--box-shadow); -} - -.rating { - padding-left: 7px; - color: #64eac4; - font-weight: 700; -} - -.user-rating { - float: right; - font-weight: 700; - font-size: 14px; - line-height: 14px; - color: rgba(255, 255, 255, 0.75); - background: rgba(255, 255, 255, 0.15); - padding: 5px; - border-radius: 5px; - margin-left: 10px; - margin-bottom: 5px; - min-width: 60px; - text-align: center; -} - -.more-info-main-info .standard-btn { - margin-left: 15px; -} - -.modal .standard-btn.report-modal-btn, -.standard-btn { - color: #fff; - font-family: var(--global-font); - font-size: 17px; - line-height: 40px; - text-align: center; - width: auto; - padding-left: 15px; - padding-right: 15px; - height: 40px; - border-radius: 4px; - background: var(--accent-color); - float: right; - font-weight: bold; - transition-duration: 0.3s; - transition-timing-function: ease; -} - -.standard-btn.available { - background: #333333; -} -.standard-btn.view-episodes .fa-plus { - font-size: 0; -} - -.modal .standard-btn.report-modal-btn:hover, -.standard-btn.series-modal-btn.available:hover, -.standard-btn:hover:not(.available) { - background: #2ba180; -} - -.standard-btn.report-selection-modal-btn, -.standard-btn.report-btn, -.standard-btn.report-modal-btn, -.standard-btn.delete-user-btn { - background: #a53939; -} - -.standard-btn.report-selection-modal-btn:hover, -.standard-btn.report-btn:hover, -.standard-btn.report-modal-btn:hover, -.standard-btn.delete-user-btn:hover { - background: #d04141; -} - -.more-info-overview { - box-sizing: border-box; - margin-top: var(--more-info-section-spacing); - width: 100%; - border-radius: 4px; - font-family: "Roboto", sans-serif; - font-weight: 400; - padding-top: var(--more-info-section-padding); - font-size: 15px; -} - -.more-info-summary { - grid-row: 1; - grid-column: 1; - font-size: 16px; - line-height: 22px; - padding-left: var(--more-info-section-padding); - padding-right: var(--more-info-section-padding); -} - -.tns-inner > .more-info-reviews { - opacity: 1; -} - -.more-info-reviews .bold.head { - grid-row: 1; - grid-column: 1; - text-align: left; -} - -.more-info-reviews .fa-angle-right { - grid-row: 1 / 2; - grid-column: 4; - font-size: 28px; - height: 100%; - margin-left: 10px; - color: #252525; -} - -.giant-quote { - display: inline; - font-size: 20px; - font-family: "Times New Roman", serif; -} - -.giant-quote:first-of-type { - margin-right: 3px; -} - -.giant-quote:last-of-type { - margin-left: 3px; -} - -.review-quote { - display: block; - max-height: 250px; - overflow-y: auto; - padding-right: 15px; -} - -.review { - padding: 15px; - border-radius: 8px; - background: var(--poster-bg-color); - color: rgba(255, 255, 255, 0.75); - font-weight: 300; - line-height: 18px; - height: auto; - overflow: hidden; -} - -.more-info-reviews .review .bold { - margin-bottom: 5px; - text-align: right; - margin-top: 5px; - color: #4ecea9; - font-size: 18px; - display: block; -} - -.tns-nav { - text-align: center; -} - -.tns-nav > [aria-controls] { - width: 9px; - height: 9px; - padding: 0; - margin: 0 5px; - border-radius: 50%; - background: #ddd; - border: 0; -} - -.tns-nav > .tns-nav-active { - background: var(--accent-color); -} - -.viewport .cast.poster-container { - --poster-details-height: var(--cast-poster-card-details-height); - --poster-container-height: auto; -} - -.viewport .person-roles.poster-container .poster-description, -.viewport .cast.poster-container .poster-description { - text-align: left; -} - -.viewport .cast.poster-container .poster-title { - width: 100%; -} - -.section-title { - margin-bottom: 5px; - font-size: 18px; - line-height: 22px; -} - -.viewport .carousel .section-title { - margin-bottom: 0; - padding-top: var(--more-info-section-padding); - padding-left: var(--more-info-section-padding); - padding-right: var(--more-info-section-padding); - display: inline-block; - width: 100%; -} - -.tns-carousel { - padding-bottom: var(--more-info-section-padding); - padding-top: calc(var(--more-info-section-padding) / 2); - display: flex; -} - -.carousel-inner-container { - display: none; -} - -.carousel-inner-container.tns-carousel { - display: flex; -} - -.carousel-controls { - position: absolute; - right: calc(var(--more-info-section-padding) / 2); - top: calc(var(--more-info-section-padding) * 0.85); - display: flex; -} - -.tns-controls { - text-align: center; -} - -.tns-controls:not([aria-label]) { - display: none; -} - -.tns-controls [aria-controls] { - background: transparent; - border: 0; - font-size: 18px; - padding: 0 10px; - transition: opacity 0.3s ease; -} - -.tns-controls [aria-controls][aria-disabled="true"] { - opacity: 0.4; -} - -.tns-controls [aria-controls]:not([aria-disabled="true"]) { - cursor: pointer; -} - -.tns-inner { - /* Fix for when there's too few items in the carousel */ - margin: 0px 10px 0px 20px !important; -} - -.viewport .tns-inner .poster-container { - margin: 0; -} - -.artwork-container-wrapper { - width: var(--artwork-width); - min-width: var(--artwork-width); - max-width: var(--artwork-width); - height: var(--artwork-height); - min-height: var(--artwork-height); - max-height: var(--artwork-height); - text-align: left; - overflow: hidden; -} - -.artwork-container { - background: var(--placeholder-bg); - width: 100%; - height: 100%; - border-radius: 10px; - overflow: hidden; -} - -.artwork-carousel-artwork { - width: 100%; - height: 100%; - -o-object-fit: cover; - object-fit: cover; - transition: opacity 2.5s; -} - -.youtube-player { - width: var(--video-width); - min-width: var(--video-width); - max-width: var(--video-width); - height: var(--video-height); - min-height: var(--video-height); - max-height: var(--video-height); - border-radius: 10px; - overflow: hidden; -} - -/* Global */ - -.movie-backdrop-container { - position: absolute; - left: 0px; - top: 0px; - z-index: -1; - width: 100%; -} - -.movie-backdrop-container > * { - -webkit-mask-image: linear-gradient( - to bottom, - rgba(0, 0, 0, 1), - rgba(0, 0, 0, 0) - ); - mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); -} - -.movie-backdrop-container img { - width: 100%; - height: var(--backdrop-height); - -o-object-fit: cover; - object-fit: cover; - position: absolute; - transition: opacity 5s ease; -} - -.movie-backdrop-container .backdrop-placeholder-gradient { - width: 100%; - height: var(--backdrop-height); - position: absolute; - background: var(--placeholder-bg); - z-index: -1; - opacity: 0.55; -} - -.movie-backdrop-container > .backdrop-tint { - background: linear-gradient(360deg, black, transparent); - width: 100%; - height: var(--backdrop-height); - opacity: 0.85; - position: absolute; - z-index: 1; -} - -.more-info-topbar { - display: grid; - grid-template-columns: var(--left-column-width) var(--right-column-width); - -moz-column-gap: 25px; - column-gap: 25px; -} - -.viewport .carousel { - box-sizing: border-box; - margin-top: var(--more-info-section-spacing); - width: 100%; - border-radius: 4px; - font-family: "Roboto", sans-serif; - font-weight: 400; - padding: 0; - font-size: 15px; - position: relative; -} - -/* Left Side */ - -#movie-request-status { - display: inline; -} - -.quick-info-block .modal-dot { - border: 1px solid rgba(0, 0, 0, 0.3); -} - -.quick-info-block.availability .quick-info { - display: flex; - align-items: center; -} - -.more-info-poster-container { - width: 100%; - height: auto; - box-shadow: var(--box-shadow); - border-radius: 5px; - overflow: hidden; - background: var(--placeholder-bg); -} - -.more-info-poster-container img { - display: block; - width: 100%; - height: calc(var(--left-column-width) * 1.5); - transition: opacity 1.5s ease; -} - -.more-info-collection-btn { - width: 100%; - text-align: center; - background: var(--accent-color); - font-family: "Roboto", sans-serif; - color: #fff; - padding-top: 4px; - padding-bottom: 4px; - font-weight: 700; - box-shadow: var(--box-shadow); - transition: background 0.3s ease; -} - -.more-info-collection-btn:hover { - background: #2ba180; -} - -.quick-info-block { - font-size: inherit; - color: inherit; -} - -.quick-info.bold { - margin-bottom: 5px; -} - -.quick-info { - font-size: inherit; - display: block; - color: inherit; -} - -.quick-info-btn { - background: var(--accent-color); - padding: 5px 8px; - display: inline-block; - border-radius: 4px; - color: #fff; - margin: 2px; - transition: background 0.3s ease; -} - -.quick-info-btn:hover { - background: #2ba180; -} - -.quick-info-extra-spacing { - line-height: 18px; -} - -/* Image/Video Popup Modals (ex. artwork) */ - -.mfp-no-margins .mfp-container { - padding: 0; -} - -.mfp-zoom-out-cur .mfp-image-holder .mfp-close { - right: 0px; - cursor: pointer !important; - transition: opacity 0.3s ease; - background: transparent; -} - -.mfp-arrow { - transition: opacity 0.3s ease, transform 0.3s ease; - background: none !important; -} - -.mfp-arrow:focus { - opacity: 0.65; -} - -.mfp-arrow:hover { - opacity: 1; -} - -.mfp-arrow:active { - margin-top: -55px; - opacity: 1; -} - -.mfp-counter { - display: none; -} - -.mfp-with-zoom .mfp-container, -.mfp-with-zoom.mfp-bg { - opacity: 0; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - transition: all 0.3s ease-out; -} - -.mfp-with-zoom.mfp-ready .mfp-container { - opacity: 1; -} - -.mfp-with-zoom.mfp-ready.mfp-bg { - opacity: 0.8; -} - -.mfp-with-zoom.mfp-removing .mfp-container, -.mfp-with-zoom.mfp-removing.mfp-bg { - opacity: 0; -} diff --git a/conreq/core/base/static/css/navbar.css b/conreq/core/base/static/css/navbar.css deleted file mode 100644 index 836e6799..00000000 --- a/conreq/core/base/static/css/navbar.css +++ /dev/null @@ -1,84 +0,0 @@ -.navbar { - background: var(--navbar-bg); - height: var(--navbar-height); - box-shadow: var(--box-shadow); - padding-left: 20px; - padding-right: 20px; - z-index: 3; - display: none; -} - -.navbar-dark .navbar-brand { - margin-left: 20px; - margin-right: 0; - color: rgba(255, 255, 255, 0.5); - font-weight: 500; - font-size: 16px; -} - -.navbar .navbar-toggler { - display: flex; -} - -.navbar-toggler-icon { - font-size: 16px; -} - -.searchbar { - position: relative; - height: 40px; - margin: auto; - margin-bottom: 30px; - width: var(--searchbar-width); - background: rgb(0 0 0 / 0.45); - border-radius: 15px; - transition: background 0.4s ease, color 0.4s ease; - color: rgba(255, 255, 255, 0.3); - overflow: hidden; - display: flex; -} - -.viewport-container .searchbar, -.viewport-container-top .searchbar { - box-shadow: var(--poster-box-shadow); -} - -.searchbar:focus-within { - background: #fff; - color: #252525; -} - -.searchbar input { - box-sizing: border-box; - height: 100%; - max-width: 100%; - background: none; - width: calc(100% - 40px); - color: inherit; - border: none; - font-size: var(--primary-font-size); - font-weight: 500; - padding-left: 15px; - outline: none !important; -} - -.searchbar .fa-search { - top: 0px; - right: 0px; - margin-right: 15px; - width: calc(var(--navbar-height) * 0.3); - color: inherit; - margin: 0 auto; - display: flex; - justify-content: center; - align-items: center; -} - -button { - transition: background 0.3s ease; -} - -button:focus { - outline: none; - background: rgb(255 255 255 / 0.04); -} diff --git a/conreq/core/base/static/css/posters.css b/conreq/core/base/static/css/posters.css deleted file mode 100644 index 05fb5254..00000000 --- a/conreq/core/base/static/css/posters.css +++ /dev/null @@ -1,169 +0,0 @@ -/* Posters */ - -.masonry-item { - margin-bottom: var(--poster-padding); -} - -.viewport .poster-container { - border-radius: 5px; - width: var(--poster-width); - overflow: hidden; - box-shadow: var(--poster-box-shadow); - transition: transform 0.15s ease-in-out; - z-index: 1; - background: var(--poster-bg-color); - height: var(--poster-container-height); - transform: scale(1); -} - -.viewport .poster-container.culled { - padding: 10px; - color: rgba(255, 255, 255, 0.75); -} - -.poster-fix { - width: var(--poster-width); - height: var(--poster-height); - overflow: hidden; -} - -.viewport .poster { - width: var(--poster-width); - height: var(--poster-height); - display: block; - transition: transform 0.3s ease, opacity 2.5s, -webkit-filter 0.3s ease; - transition: filter 0.3s ease, transform 0.3s ease, opacity 2.5s; - transition: filter 0.3s ease, transform 0.3s ease, opacity 2.5s, - -webkit-filter 0.3s ease; - z-index: 6; - position: relative; -} - -.viewport .poster:hover { - -webkit-filter: contrast(1.1) saturate(1.2); - filter: contrast(1.1) saturate(1.2); - transform: scale(1.08); -} - -.viewport .poster-container:hover { - transform: scale(1.05); - z-index: 2; -} - -.poster-description-container { - z-index: 7; - position: relative; - height: var(--poster-details-height); - overflow: hidden; - width: var(--poster-width); -} - -.poster-title { - font-family: var(--global-font); - font-weight: 300; - overflow: hidden; - text-overflow: ellipsis; - font-size: 16px; - color: #ffffff; - padding: 7px var(--poster-padding) 5px var(--poster-padding); - text-align: left; - display: block; - width: calc(var(--poster-width) - 20px); -} - -.poster-description { - font-family: var(--global-font); - font-weight: 300; - font-size: var(--secondary-font-size); - text-align: center; - color: rgba(255, 255, 255, 0.4); - padding: 0px var(--poster-padding); -} - -.description-tint { - background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0), #191919); - height: var(--poster-details-height); - width: var(--poster-width); - position: absolute; - top: var(--poster-height); - left: 0px; - z-index: 10; - -webkit-filter: brightness(25%); - filter: brightness(25%); -} - -.viewport .poster-container .fa-angle-down { - position: absolute; - bottom: 0px; - color: rgba(255, 255, 255, 0.5); - z-index: 11; - vertical-align: middle; - width: var(--poster-width); - padding-top: calc(var(--poster-details-height) - 18px); - padding-bottom: 2px; - font-size: 18px; - transition: color 0.3s ease, background 0.3s ease; - text-align: center; -} - -.viewport .poster-container .fa-angle-down:hover { - background-color: rgb(255 255 255 / 10%); - color: rgba(255, 255, 255, 0.85); -} - -.requested-by { - position: absolute; - top: calc(var(--poster-height) - 30px); - right: 5px; - transition: opacity 0.6s ease; - z-index: 7; - color: rgb(255 255 255 / 0.75); - border-radius: 4px; - padding: 5px; - font-size: 12px; - line-height: 14px; - background: var(--poster-bg-color); - font-weight: 700; - max-width: 110px; -} - -.viewport .tv.poster-container > a > .content-type-icon { - color: #bbdeff; -} - -.viewport .movie.poster-container > a > .content-type-icon { - color: #ffbd72; -} - -.viewport .poster-container > a > .content-type-icon { - position: absolute; - top: calc(var(--poster-height) - 30px); - left: 5px; - opacity: 0.8; - transition: opacity 0.6s ease; - z-index: 7; - color: rgb(255 255 255 / 0.75); - border-radius: 4px; - padding: 5px; - font-size: 12px; - line-height: 14px; - background: var(--poster-bg-color); - font-weight: 700; - z-index: 11; -} - -.viewport .poster-container:hover > a:hover > .content-type-icon { - opacity: 1; -} - -.availablity-dot { - width: 5px; - height: 5px; - border-radius: 50%; - display: inline-block; - position: absolute; - top: 0; - right: 0px; - margin: 7px 6px; - pointer-events: auto; -} diff --git a/conreq/core/base/static/css/server_settings.css b/conreq/core/base/static/css/server_settings.css deleted file mode 100644 index c14998e2..00000000 --- a/conreq/core/base/static/css/server_settings.css +++ /dev/null @@ -1,81 +0,0 @@ -.settings-group-title { - font-size: 21px; - line-height: 1.5; -} - -.viewport.settings { - width: 100%; - max-width: calc( - 1920px - var(--sidebar-width) - var(--viewport-total-padding) - ); -} - -.settings-group { - width: 100%; - margin-bottom: 30px; -} - -.settings-input-group { - display: grid; - flex-direction: column; - margin: 0; - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); - -moz-column-gap: 20px; - column-gap: 50px; -} - -.settings-item-group { - display: flex; - flex-direction: column; - justify-content: center; - min-height: 70px; -} - -.text-input-title { - font-weight: 500; - line-height: 1.5; -} - -.settings-item.text-display-only { - display: flex; - align-items: center; - height: 100%; - padding-left: 15px; - padding-right: 15px; - font-size: 16px; -} - -.settings-item.text-display-only .settings-item-text { - width: calc(100% - 15px); -} - -.settings-item .fas { - margin-left: 15px; - font-size: 18px; -} - -.settings-item .fas:first { - margin-left: auto; -} - -input[type="text"]:not(.content-search) { - width: 100%; -} - -.settings-item.toggler label { - font-weight: 500; -} - -.check-update-btn { - align-self: center; - width: auto; - margin: auto; -} - -.settings-item-details.info { - word-wrap: break-word; -} - -.settings-item-group.toggler { - min-height: 45px; -} diff --git a/conreq/core/base/static/css/sidebar.css b/conreq/core/base/static/css/sidebar.css deleted file mode 100644 index 50817ae8..00000000 --- a/conreq/core/base/static/css/sidebar.css +++ /dev/null @@ -1,142 +0,0 @@ -.sidebar { - z-index: 2; - height: calc(100% - var(--navbar-height)); - width: var(--sidebar-width); - position: relative; - left: 0; - background: var(--sidebar-bg); - overflow-x: hidden; - font-family: var(--global-font); - font-weight: 400; - box-shadow: var(--box-shadow); - overflow-y: auto; - overflow-y: overlay; - display: inline-block; - color: rgb(156 156 156); -} - -.sidebar .navpages { - white-space: nowrap; - height: 100%; - text-overflow: ellipsis; -} - -.nav-tab:hover { - background: rgba(255, 255, 255, 0.03); -} - -.nav-tab.active { - background: rgba(255, 255, 255, 0.08); - color: #fff; -} - -.nav-tab { - margin: 0 5px; -} - -.nav-tab, -.nav-group { - text-decoration: none; - font-size: var(--primary-font-size); - display: block; - transition: 0.3s; - white-space: nowrap; - overflow: hidden; - position: relative; - border-radius: 10px; - width: auto; -} - -.nav-group { - font-size: 15px; -} - -.nav-group.collapsed .fa-caret-up { - transform: rotate(180deg); -} - -.group-name { - padding: var(--navgroup-padding); -} - -.nav-tab > a, -.nav-tab > div { - padding: var(--navpages-btn-padding); -} - -.nav-group .icon-right, -.nav-tab .icon-right { - color: rgb(94 94 94); - transition: color 0.3s ease, opacity 0.3s ease; - position: absolute; - right: 0; - top: 0; -} - -.nav-group .icon-right { - margin: var(--navgroup-padding); -} - -.nav-tab .icon-right { - margin: var(--navpages-btn-padding); -} - -.nav-group .icon-right:hover, -.nav-tab .icon-right:hover { - color: #fff; -} - -.sidebar-user { - color: #fff; - padding: 10px 15px; - background: var(--accent-color); - border-radius: 0 0 10px 10px; -} - -.sidebar-user .sidebar-profile-pic { - display: inline-flex; - margin-right: 15px; - background: #072f12; - padding: 10px; - border-radius: 50%; - height: 35px; - width: 35px; - justify-content: center; - align-items: center; -} - -.sidebar-user .username { - display: inline-flex; - width: calc(100% - 50px); - font-weight: 700; -} - -.sidebar-user .username > div { - width: 100%; -} - -.tabs-collapse { - display: flex; - width: 100%; -} - -.tabs-indicator { - background: #5d5d5d; - width: 2px; - height: auto; - border-radius: 20px; - margin-left: 27px; - margin-bottom: 5px; -} - -.tabs { - width: 100%; -} - -.group-icon { - display: inline-flex; - align-items: center; - justify-content: center; - width: 42px; - margin-left: -13px; -} diff --git a/conreq/core/base/static/css/simple_posters.css b/conreq/core/base/static/css/simple_posters.css deleted file mode 100644 index 89ce3599..00000000 --- a/conreq/core/base/static/css/simple_posters.css +++ /dev/null @@ -1,98 +0,0 @@ -.viewport .poster-container { - height: var(--poster-height); -} - -.viewport .poster-container .fa-angle-down { - padding-top: 0px; - color: #000000; - background: #e4e4e4; - -webkit-filter: drop-shadow(0 0 6px #000000); - filter: drop-shadow(0 0 6px #000000); - border-radius: 20px; - width: 20px; - height: 20px; - left: 50%; - bottom: 3px; - transform: translate(-50%, 0%); - line-height: 1.15; - opacity: 0.4; - transition: color 0.3s ease, background 0.3s ease, opacity 0.3s ease; -} - -.viewport .poster-container:hover .fa-angle-down { - opacity: 1; -} - -.viewport .poster-container .fa-angle-down:hover { - color: var(--accent-color); - background: #ffffff; -} - -.viewport .poster-container > a > .requested-by { - top: calc(var(--poster-height) - 55px); - left: 5px; - right: unset; - opacity: 1; -} - -.viewport .poster-container > a > .requested-by { - max-width: calc(100% - 10px); -} - -.viewport .poster-container .poster-description-container { - opacity: 0.85; - position: absolute; - top: -2px; - left: -2px; - width: calc(var(--poster-width) + 4px); - pointer-events: none; - background: linear-gradient(180deg, black, transparent); - border: none; - transition: opacity 0.6s ease; - height: -webkit-fit-content; - height: -moz-fit-content; - height: fit-content; - padding-top: 2px; - padding-bottom: 25px; - color: #d8d8d8; - text-shadow: -2px -2px 6px #000, 2px -2px 6px #000, -2px 2px 6px #000, - 2px 2px 6px #000; -} - -.availablity-dot { - margin: 8px 7px; -} - -.viewport .poster-container:hover .poster-description-container { - opacity: 1; -} - -.poster-container.person-roles .poster-description, -.poster-container.cast .poster-description { - color: inherit; - font-weight: 400; -} - -.poster-container.tv .poster-description, -.poster-container.movie .poster-description { - display: none; -} - -.viewport .poster-container .poster { - transform: scale(1.08); -} - -.viewport .poster-container .poster:hover { - transform: none; -} - -.viewport .poster-container > a > .content-type-icon { - line-height: 1; - top: unset; - bottom: 5px; - left: 5px; -} - -.viewport .poster-container .description-tint { - display: none; -} diff --git a/conreq/core/base/static/css/viewport.css b/conreq/core/base/static/css/viewport.css deleted file mode 100644 index 0c8b24bd..00000000 --- a/conreq/core/base/static/css/viewport.css +++ /dev/null @@ -1,44 +0,0 @@ -.viewport-container, -.viewport-container-top { - position: absolute; - height: calc(100% - var(--navbar-height)); - overflow-x: hidden; - overflow-y: auto; - overflow-y: overlay; - width: calc(100vw - var(--viewport-left)); - padding: var(--viewport-padding); - padding-bottom: 0; - display: inline-block; - color: rgb(255 255 255 / 0.75); -} - -.viewport { - padding-bottom: var(--viewport-padding); - min-height: -webkit-fit-content; - min-height: -moz-fit-content; - min-height: fit-content; - margin: auto; - transition: opacity 1.5s ease; -} - -.empty-viewport { - text-align: center; - min-width: -webkit-fit-content; - min-width: -moz-fit-content; - min-width: fit-content; - width: 30%; - max-width: 100%; - margin: auto; - margin-top: 10px; - padding: 40px; - border-radius: 6px; - box-shadow: var(--box-shadow); - line-height: 1.5; -} - -.viewport-container > .loading-animation-container, -.viewport-container-top > .loading-animation-container { - display: flex; - height: 100%; - width: 100%; -} diff --git a/conreq/core/base/static/icons/android-chrome-192x192.png b/conreq/core/base/static/icons/android-chrome-192x192.png deleted file mode 100644 index 98a80675..00000000 Binary files a/conreq/core/base/static/icons/android-chrome-192x192.png and /dev/null differ diff --git a/conreq/core/base/static/icons/android-chrome-512x512.png b/conreq/core/base/static/icons/android-chrome-512x512.png deleted file mode 100644 index ca919528..00000000 Binary files a/conreq/core/base/static/icons/android-chrome-512x512.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-114x114-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-114x114-precomposed.png deleted file mode 100644 index 38d25404..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-114x114-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-114x114.png b/conreq/core/base/static/icons/apple-touch-icon-114x114.png deleted file mode 100644 index 0a438de7..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-114x114.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-120x120-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-120x120-precomposed.png deleted file mode 100644 index aefbad73..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-120x120-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-120x120.png b/conreq/core/base/static/icons/apple-touch-icon-120x120.png deleted file mode 100644 index 81a448f1..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-120x120.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-144x144-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-144x144-precomposed.png deleted file mode 100644 index 430d36dd..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-144x144-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-144x144.png b/conreq/core/base/static/icons/apple-touch-icon-144x144.png deleted file mode 100644 index 64a7e7c0..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-144x144.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-152x152-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-152x152-precomposed.png deleted file mode 100644 index 82906c08..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-152x152-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-152x152.png b/conreq/core/base/static/icons/apple-touch-icon-152x152.png deleted file mode 100644 index 9d255db1..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-152x152.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-180x180-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-180x180-precomposed.png deleted file mode 100644 index 83b9c605..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-180x180-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-180x180.png b/conreq/core/base/static/icons/apple-touch-icon-180x180.png deleted file mode 100644 index 4fbdc458..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-180x180.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-57x57-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-57x57-precomposed.png deleted file mode 100644 index 898270e5..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-57x57-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-57x57.png b/conreq/core/base/static/icons/apple-touch-icon-57x57.png deleted file mode 100644 index 6c2037f3..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-57x57.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-60x60-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-60x60-precomposed.png deleted file mode 100644 index 21c4801f..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-60x60-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-60x60.png b/conreq/core/base/static/icons/apple-touch-icon-60x60.png deleted file mode 100644 index 5ac1573e..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-60x60.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-72x72-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-72x72-precomposed.png deleted file mode 100644 index 25b75c30..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-72x72-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-72x72.png b/conreq/core/base/static/icons/apple-touch-icon-72x72.png deleted file mode 100644 index 33cfdced..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-72x72.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-76x76-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-76x76-precomposed.png deleted file mode 100644 index 27e008cf..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-76x76-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-76x76.png b/conreq/core/base/static/icons/apple-touch-icon-76x76.png deleted file mode 100644 index 64e4679a..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-76x76.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon-precomposed.png b/conreq/core/base/static/icons/apple-touch-icon-precomposed.png deleted file mode 100644 index 83b9c605..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon-precomposed.png and /dev/null differ diff --git a/conreq/core/base/static/icons/apple-touch-icon.png b/conreq/core/base/static/icons/apple-touch-icon.png deleted file mode 100644 index 4fbdc458..00000000 Binary files a/conreq/core/base/static/icons/apple-touch-icon.png and /dev/null differ diff --git a/conreq/core/base/static/icons/browserconfig.xml b/conreq/core/base/static/icons/browserconfig.xml deleted file mode 100644 index 0b7d9287..00000000 --- a/conreq/core/base/static/icons/browserconfig.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - #31b58f - - - diff --git a/conreq/core/base/static/icons/favicon-16x16.png b/conreq/core/base/static/icons/favicon-16x16.png deleted file mode 100644 index c069d80f..00000000 Binary files a/conreq/core/base/static/icons/favicon-16x16.png and /dev/null differ diff --git a/conreq/core/base/static/icons/favicon-32x32.png b/conreq/core/base/static/icons/favicon-32x32.png deleted file mode 100644 index cf7cc79f..00000000 Binary files a/conreq/core/base/static/icons/favicon-32x32.png and /dev/null differ diff --git a/conreq/core/base/static/icons/favicon.ico b/conreq/core/base/static/icons/favicon.ico deleted file mode 100644 index c19f8769..00000000 Binary files a/conreq/core/base/static/icons/favicon.ico and /dev/null differ diff --git a/conreq/core/base/static/icons/maskable.png b/conreq/core/base/static/icons/maskable.png deleted file mode 100644 index b6b255d1..00000000 Binary files a/conreq/core/base/static/icons/maskable.png and /dev/null differ diff --git a/conreq/core/base/static/icons/mstile-150x150.png b/conreq/core/base/static/icons/mstile-150x150.png deleted file mode 100644 index 0be35e47..00000000 Binary files a/conreq/core/base/static/icons/mstile-150x150.png and /dev/null differ diff --git a/conreq/core/base/static/icons/mstile-310x310.png b/conreq/core/base/static/icons/mstile-310x310.png deleted file mode 100644 index 07fb39dd..00000000 Binary files a/conreq/core/base/static/icons/mstile-310x310.png and /dev/null differ diff --git a/conreq/core/base/static/icons/mstile-70x70.png b/conreq/core/base/static/icons/mstile-70x70.png deleted file mode 100644 index 9beb0ccc..00000000 Binary files a/conreq/core/base/static/icons/mstile-70x70.png and /dev/null differ diff --git a/conreq/core/base/static/icons/safari-pinned-tab.svg b/conreq/core/base/static/icons/safari-pinned-tab.svg deleted file mode 100644 index 5b728b43..00000000 --- a/conreq/core/base/static/icons/safari-pinned-tab.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/conreq/core/base/static/icons/site.webmanifest b/conreq/core/base/static/icons/site.webmanifest deleted file mode 100644 index 1c4442d5..00000000 --- a/conreq/core/base/static/icons/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "", - "short_name": "", - "icons": [ - { - "src": "/static/icons/android-chrome-192x192.png?v=A053y77goM", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/static/icons/android-chrome-512x512.png?v=A053y77goM", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#04110d", - "background_color": "#04110d", - "display": "standalone" -} diff --git a/conreq/core/base/static/icons/standard.png b/conreq/core/base/static/icons/standard.png deleted file mode 100644 index efa05e86..00000000 Binary files a/conreq/core/base/static/icons/standard.png and /dev/null differ diff --git a/conreq/core/base/static/images/person_placeholder.png b/conreq/core/base/static/images/person_placeholder.png deleted file mode 100644 index 813911f7..00000000 Binary files a/conreq/core/base/static/images/person_placeholder.png and /dev/null differ diff --git a/conreq/core/base/static/images/poster_placeholder.png b/conreq/core/base/static/images/poster_placeholder.png deleted file mode 100644 index 5ead50c2..00000000 Binary files a/conreq/core/base/static/images/poster_placeholder.png and /dev/null differ diff --git a/conreq/core/base/static/js/client_websockets.js b/conreq/core/base/static/js/client_websockets.js deleted file mode 100644 index 00538dae..00000000 --- a/conreq/core/base/static/js/client_websockets.js +++ /dev/null @@ -1,102 +0,0 @@ -let first_websocket_connection = true; -let display_disconnected_toast = true; -var viewport_loaded = false; - -// WEBSOCKET CREATION -var COMMAND_SOCKET = null; -let RETRY_COUNTER = 0; -let MAX_FAST_RETRIES = 30; - -$(document).ready(async function () { - let ws_connect = async function () { - // Note: this websocket automatically reconnects upon disconnection - let loc = window.location; - let ws_start = ""; - if (loc.protocol == "https:") { - ws_start = "wss://"; - } else { - ws_start = "ws://"; - } - let endpoint = ws_start + loc.host + $("#base-url").val(); - COMMAND_SOCKET = new WebSocket(endpoint); - - // RECEIVABLE COMMANDS - COMMAND_SOCKET.onmessage = function (response) { - // Websocket message received, parse for JSON - console.info(response); - json_response = JSON.parse(response.data); - - // Check for valid commands - if (json_response.command_name == "forbidden") { - location.reload(); - } else { - console.warn( - "Unknown command " + - json_response.command_name + - " received!" - ); - } - }; - - // WEBSOCKET EVENT: ON OPEN - COMMAND_SOCKET.onopen = function () { - RETRY_COUNTER = 0; - display_disconnected_toast = true; - - if (first_websocket_connection) { - first_websocket_connection = false; - } else { - // Show a message saying we reconnected - reconnected_toast_message(); - } - }; - - // WEBSOCKET EVENT: ON CLOSE - COMMAND_SOCKET.onclose = function () { - // Toast message to notify that the user has disconnected from the server - if (display_disconnected_toast) { - disconnected_toast_message(); - first_websocket_connection = false; - display_disconnected_toast = false; - } - - // Automatically reconnect upon disconnection - RETRY_COUNTER++; - if (RETRY_COUNTER <= MAX_FAST_RETRIES) { - console.info( - RETRY_COUNTER, - "Websocket is closed. Reconnect will be attempted in 3 second." - ); - setTimeout(async function () { - ws_connect(); - }, 3000); - } else { - console.info( - "Websocket is closed. Reconnect will be attempted in 30 second." - ); - setTimeout(async function () { - ws_connect(); - }, 30000); - } - }; - - // WEBSOCKET EVENT: ON ERROR - COMMAND_SOCKET.onerror = function (error) { - if (display_disconnected_toast) { - disconnected_toast_message(); - first_websocket_connection = false; - display_disconnected_toast = false; - } - - console.error( - "Websocket encountered an error: ", - error.message, - "Closing socket..." - ); - COMMAND_SOCKET.close(); - }; - }; - - // First connection attempt - ws_connect(); -}); diff --git a/conreq/core/base/static/js/events_click.js b/conreq/core/base/static/js/events_click.js deleted file mode 100644 index 9712376a..00000000 --- a/conreq/core/base/static/js/events_click.js +++ /dev/null @@ -1,515 +0,0 @@ -let ongoing_request = null; -let report_selection = null; - -var request_btn_click_event = async function () { - $(".request-btn").each(async function () { - $(this).unbind("click"); - $(this).click(async function () { - let params = { - tmdb_id: $(this).data("tmdb-id"), - content_type: $(this).data("content-type"), - seasons: null, - episode_ids: null, - }; - - // Prevent the user from spamming the request button - if (ongoing_request == this) { - return false; - } else { - ongoing_request = this; - } - - // Request a movie - if (params.content_type == "movie") { - post_json($(this).data("request-url"), params, function () { - let request_btn = $(".request-btn"); - requested_toast_message(); - if ($(window).width() < 1000) { - $(".request-btn").hide(); - } - request_btn.text("REQUESTED"); - request_btn.unbind("click"); - request_btn.removeClass("clickable"); - $("#modal-container").modal("hide"); - ongoing_request = null; - }).fail(async function () { - conreq_no_response_toast_message(); - ongoing_request = null; - }); - } - - // Request a TV show - else if (params.content_type == "tv") { - let selection = modal_checkbox_aggregator(); - // Request the whole show - if (selection == true) { - post_json($(this).data("request-url"), params, function () { - requested_toast_message(); - $(".series-modal-btn").text("REQUESTED"); - $("#modal-container").modal("hide"); - ongoing_request = null; - }).fail(async function () { - conreq_no_response_toast_message(); - ongoing_request = null; - }); - } - - // Request parts of the show - else if ( - selection.seasons.length || - selection.episode_ids.length - ) { - params.seasons = selection.seasons; - params.episode_ids = selection.episode_ids; - post_json($(this).data("request-url"), params, function () { - requested_toast_message(); - $(".series-modal-btn").text("REQUESTED"); - $("#modal-container").modal("hide"); - ongoing_request = null; - }).fail(async function () { - conreq_no_response_toast_message(); - ongoing_request = null; - }); - } - // User didn't select anything - else { - no_selection_toast_message(); - ongoing_request = null; - } - } - }); - }); -}; - -var quick_info_btn_click_event = async function () { - $(".quick-info-read-more-btn").click(async function () { - $(".more-info-quick-info.collapse").collapse("toggle"); - $(this).remove(); - }); -}; - -var content_modal_click_event = async function () { - $( - ".series-modal-btn, .content-preview-modal-btn, .report-selection-modal-btn" - ).each(async function () { - let current_btn = $(this); - if (!current_btn.hasClass("loaded")) { - current_btn.click(async function () { - let params = { - tmdb_id: $(this).data("tmdb-id"), - content_type: $(this).data("content-type"), - report_modal: $(this).hasClass( - "report-selection-modal-btn" - ), - }; - generate_modal( - $(this).data("modal-url") + "?" + $.param(params) - ); - }); - current_btn.addClass("loaded"); - } - }); -}; - -var create_report_modal_click_event = async function () { - $(".report-modal-btn").each(async function () { - $(this).unbind("click"); - $(this).click(async function () { - let params = { - tmdb_id: $(this).data("tmdb-id"), - content_type: $(this).data("content-type"), - }; - - // Report an issue with a movie - if (params.content_type == "movie") { - report_selection = null; - generate_modal( - $(this).data("modal-url") + "?" + $.param(params) - ); - } - - // Report an issue with a TV show - else if (params.content_type == "tv") { - // Determine what checkboxes are checked - let current_selection = modal_checkbox_aggregator(); - report_selection = null; - - // All non-special seasons were checkboxed - if (current_selection == true) { - generate_modal( - $(this).data("modal-url") + "?" + $.param(params) - ); - } - - // Parts of the show are checkboxed - else if ( - current_selection.seasons.length || - current_selection.episodes.length || - current_selection.episode_ids.length - ) { - report_selection = current_selection; - generate_modal( - $(this).data("modal-url") + "?" + $.param(params) - ); - } - - // User didn't select anything - else { - no_selection_toast_message(); - } - } - }); - }); -}; - -var create_filter_modal_click_event = async function () { - $(".filter-modal-btn").each(async function () { - $(this).unbind("click"); - $(this).click(async function () { - generate_modal($(this).data("modal-url")); - }); - }); -}; - -var report_btn_click_event = async function () { - $(".report-btn").each(async function () { - $(this).unbind("click"); - $(this).click(async function () { - let params = { - tmdb_id: $(this).data("tmdb-id"), - content_type: $(this).data("content-type"), - issue_ids: $(".checkbox:checked") - .map(function () { - return $(this).data("issue-id"); - }) - .get(), - }; - - // Ensure the user selected something - if (!params.issue_ids.length) { - no_selection_toast_message(); - return false; - } - - // Save the episodes/seasons reported in the previous step - if (params.content_type == "tv" && report_selection) { - $.extend(params, report_selection); - } - - // Prevent the user from spamming the button - if (ongoing_request == this) { - return false; - } else { - ongoing_request = this; - } - - // Send the report to the server - post_json($(this).data("report-url"), params, function () { - reported_toast_message(); - $(".request-btn").text("REQUESTED"); - $("#modal-container").modal("hide"); - ongoing_request = null; - }).fail(async function () { - conreq_no_response_toast_message(); - ongoing_request = null; - }); - }); - }); -}; - -var modal_select_all_btn_click_event = async function () { - $(".modal .select-all-btn").click(async function () { - let modal_text = this.innerHTML; - if (modal_text == "SELECT ALL") { - this.innerHTML = "UNSELECT ALL"; - $(".modal input:not(.specials)").prop("checked", true); - } else { - this.innerHTML = "SELECT ALL"; - $(".modal input:not(.specials)").prop("checked", false); - } - }); -}; - -var row_title_click_event = async function () { - $(".modal .row-title-container").click(async function () { - // Checkmark the season - let season_block = $(this.parentElement); - let season_checkbox = season_block.find("input"); - season_checkbox.prop("checked", !season_checkbox.prop("checked")); - - // Checkmark all related episodes - let episode_container = $( - season_checkbox.data("all-suboptions-container") - ); - let episode_checkboxes = episode_container.find("input"); - episode_checkboxes.prop("checked", season_checkbox.prop("checked")); - }); -}; - -var row_checkbox_click_event = async function () { - $(".modal .checkbox").click(async function () { - // Checkmark all related episodes - let season_checkbox = $(this); - let episode_container = $( - season_checkbox.data("all-suboptions-container") - ); - let episode_checkboxes = episode_container.find("input"); - episode_checkboxes.prop("checked", season_checkbox.prop("checked")); - }); -}; - -var row_suboption_title_click_event = async function () { - $(".modal .suboption-title-container").click(async function () { - // Checkmark the individual episode - let episode_block = $(this.parentElement); - let episode_checkbox = episode_block.find("input"); - episode_checkbox.prop("checked", !episode_checkbox.prop("checked")); - - // Uncheck the season box - let season_container = $(episode_checkbox.data("season-container")); - let season_checkbox = season_container.find("input"); - if (episode_checkbox.prop("checked") == false) { - season_checkbox.prop("checked", false); - } - - // Checkmark the season box if every episode is checked - else { - let all_episodes_container = $(this.parentElement.parentElement); - let episode_checkboxes = all_episodes_container.find("input"); - let checkmarked_episode_checkboxes = - episode_checkboxes.filter("input:checked"); - if ( - episode_checkboxes.length == - checkmarked_episode_checkboxes.length - ) { - season_checkbox.prop("checked", true); - } - } - }); -}; - -var row_suboption_checkbox_click_event = async function () { - $(".modal .suboption-checkbox").click(async function () { - // Uncheck the season box - let episode_checkbox = $(this); - let season_container = $(episode_checkbox.data("season-container")); - let season_checkbox = season_container.find("input"); - if (episode_checkbox.prop("checked") == false) { - season_checkbox.prop("checked", false); - } - - // Checkmark the season box if every episode is checked - else { - let all_episodes_container = $( - this.parentElement.parentElement.parentElement.parentElement - ); - let episode_checkboxes = all_episodes_container.find("input"); - let checkmarked_episode_checkboxes = - episode_checkboxes.filter("input:checked"); - if ( - episode_checkboxes.length == - checkmarked_episode_checkboxes.length - ) { - season_checkbox.prop("checked", true); - } - } - }); -}; - -var modal_expand_btn_click_event = async function () { - $(".modal .fa-expand").click(async function () { - $("#modal-container").modal("hide"); - }); -}; - -var issue_approve_btn_click_event = async function () { - $(".issue-manage-icons .fas.approve").click(async function () { - let params = { - action: "resolve", - request_id: $(this.parentElement).data("request-id"), - resolved: !($(this.parentElement).data("resolved") == "True"), - }; - post_json($(this.parentElement).data("url"), params, function () { - generate_viewport(false); - }).fail(async function () { - conreq_no_response_toast_message(); - }); - }); -}; - -var issue_delete_btn_click_event = async function () { - $(".issue-manage-icons .fas.delete").click(async function () { - let params = { - action: "delete", - request_id: $(this.parentElement).data("request-id"), - }; - post_json($(this.parentElement).data("url"), params, function () { - generate_viewport(false); - }).fail(async function () { - conreq_no_response_toast_message(); - }); - }); -}; - -var simple_filter_btn_click_event = async function () { - $(".simple-filter-btn").click(async function () { - let extras = ""; - if ($("input.anime-only:checked").length) { - extras = "&type=anime"; - } else if ($("input.no-anime:checked").length) { - extras = "&type=no-anime"; - } - window.location = $(this).data("href") + extras; - $("#modal-container").modal("hide"); - }); -}; - -var search_click_event = async function () { - $(".content-search").unbind("keyup"); - $(".content-search").on("keyup", async function (e) { - if (e.keyCode == 13) { - perform_search(this); - } - }); - $(".searchbar .fas.fa-search").unbind("click"); - $(".searchbar .fas.fa-search").click(async function () { - perform_search($(this).parent().children("input")[0]); - }); -}; - -var delete_user_btn_click_event = async function () { - $(".delete-user-btn").click(async function () { - let btn = $(this); - let delete_query = - btn.data("delete-url") + - "?username=" + - escape(btn.data("username")); - post_url(delete_query, function (result) { - if (result.success) { - $("#modal-container").modal("hide"); - success_toast_message(); - } - }).fail(async function () { - conreq_no_response_toast_message(); - }); - }); -}; - -var manage_user_btn_click_event = async function () { - $(".manage-user-btn").unbind("click"); - $(".manage-user-btn").click(async function () { - let params = { - username: escape($(this).data("username")), - }; - generate_modal($(this).data("modal-url") + "?" + $.param(params)); - }); -}; - -var save_user_btn_click_event = async function () { - $(".save-user-btn").click(async function () { - post_modal_form(async function (response) { - if (response.success) { - $("#modal-container").modal("hide"); - save_success_toast_message(); - } else { - error_toast_message(response.message); - } - }).fail(async function () { - conreq_no_response_toast_message(); - }); - }); -}; - -var invite_user_btn_click_event = async function () { - $(".standard-btn.invite-user").click(async function () { - let btn = $(this); - let generate_invite_url = btn.data("generate-invite-url"); - let sign_up_url = window.location.origin + btn.data("sign-up-url"); - get_url(generate_invite_url, function (result) { - let invite_link = - sign_up_url + "?invite_code=" + escape(result.invite_code); - create_invite_link_elem(invite_link); - }).fail(conreq_no_response_toast_message); - copy_to_clipboard(); - }); -}; - -var reload_needed_click_event = async function () { - $(".reload-needed").click(async function () { - page_reload_needed = true; - }); -}; - -var refresh_api_key_click_event = async function () { - $(".refresh-conreq-api").click(async function () { - let setting_name = $(this).data("setting-name"); - change_server_setting(setting_name); - }); -}; - -var server_settings_dropdown_click_event = async function () { - $(".text-input-container.dropdown .dropdown-item").unbind("click"); - $(".text-input-container.dropdown .dropdown-item").click(async function () { - let setting_name = $(this).parent().data("setting-name"); - let dropdown_id = $(this).data("id"); - change_server_setting(setting_name, dropdown_id).then( - async function () { - generate_viewport(false); - } - ); - }); -}; - -var sidebar_collapse_click_event = async function () { - $(".nav-tab.suboption, .navbar-toggler").each(async function () { - $(this).click(async function () { - if (window.matchMedia("(max-width: 800px)").matches) { - if ($("#sidebar").hasClass("collapsed")) { - $("#sidebar").removeClass("collapsed"); - } else { - $("#sidebar").addClass("collapsed"); - } - } - }); - }); -}; - -var more_info_poster_popup_click_event = async function () { - if ( - $(".more-info-poster").length && - $(".more-info-poster").data("contains-img") == true - ) { - $(document).ready(function () { - $(".more-info-poster-container").magnificPopup({ - delegate: "img", - type: "image", - closeOnContentClick: true, - callbacks: { - elementParse: function (item) { - item.src = item.el.attr("src"); - }, - }, - }); - }); - } -}; - -var modal_poster_popup_click_event = async function () { - if ( - $(".modal-content .poster").length && - $(".modal-content .poster").data("contains-img") == true - ) { - $(document).ready(function () { - $(".modal-content .poster-container").magnificPopup({ - delegate: "img", - type: "image", - closeOnContentClick: true, - callbacks: { - elementParse: function (item) { - item.src = item.el.attr("src"); - }, - }, - }); - }); - } -}; diff --git a/conreq/core/base/static/js/events_generic.js b/conreq/core/base/static/js/events_generic.js deleted file mode 100644 index e0429966..00000000 --- a/conreq/core/base/static/js/events_generic.js +++ /dev/null @@ -1,205 +0,0 @@ -$(document).ready(async function () { - $(".viewport-container").on("prepare", async function () { - issue_approve_btn_click_event(); - issue_delete_btn_click_event(); - }); - - $(".viewport-container").on("loaded", async function () { - // Bootstrap Table - if ($("table").length) { - $("table").bootstrapTable(); - } - - // User Management events - manage_user_btn_click_event(); - delete_user_btn_click_event(); - invite_user_btn_click_event(); - - // Searchbar - search_click_event(); - - // Server Settings - $( - 'input[type="text"].settings-item.admin, input[type="url"].settings-item.admin' - ).each(async function () { - let setting_name = $(this).data("setting-name"); - let current_value = $(this).val(); - previous_admin_settings[setting_name] = current_value; - }); - $( - 'input[type="text"].settings-item.admin, input[type="url"].settings-item.admin' - ).on("keypress", function (e) { - let setting_name = $(this).data("setting-name"); - let current_value = $(this).val(); - if (e.which == 13) { - change_server_setting(setting_name, current_value); - previous_admin_settings[setting_name] = current_value; - } - }); - $( - 'input[type="text"].settings-item.admin, input[type="url"].settings-item.admin' - ).focusout(async function () { - let setting_name = $(this).data("setting-name"); - let current_value = $(this).val(); - if (previous_admin_settings[setting_name] != current_value) { - change_server_setting(setting_name, current_value); - previous_admin_settings[setting_name] = current_value; - } - }); - $(".toggler .settings-item.admin").change(async function () { - let setting_name = $(this).data("setting-name"); - let current_value = $(this).children("input").is(":checked"); - change_server_setting(setting_name, current_value); - }); - server_settings_dropdown_click_event(); - refresh_api_key_click_event(); - reload_needed_click_event(); - - // Masonry Grid - if ($(".viewport-container>.viewport-masonry").length) { - masonry_grid = $(".viewport-container>.viewport-masonry").masonry({ - itemSelector: ".masonry-item", - gutter: 10, - horizontalOrder: true, - fitWidth: true, - transitionDuration: "0s", - stagger: "0s", - isStill: true, - }); - } - - content_modal_click_event(); - - // Infinite Scroller - if ($(".viewport-container>.infinite-scroll").length) { - let elements_path = null; - if (get_window_location().includes("?")) { - elements_path = - base_url + get_window_location() + "&page={{#}}"; - } else { - elements_path = - base_url + get_window_location() + "?page={{#}}"; - } - setTimeout(async function () { - masonry_grid.infiniteScroll({ - path: elements_path, - append: ".masonry-item", - outlayer: masonry_grid.data("masonry"), - prefill: true, - elementScroll: ".viewport-container", - loadOnScroll: true, - history: false, - scrollThreshold: $(".viewport-container").height() * 4, - }); - - masonry_grid.on("append.infiniteScroll", async function () { - cull_old_posters(); - content_modal_click_event(); - }); - - infinite_scroller_created = true; - }, 500); - } - }); - - $(".viewport-container").on("destroy", function () { - // Bootstrap Table - if ($("table").length) { - $("table").bootstrapTable("destroy"); - } - - // Infinite Scroller - if (masonry_grid != null) { - if (infinite_scroller_created) { - masonry_grid.infiniteScroll("destroy"); - infinite_scroller_created = false; - } - masonry_grid.masonry("destroy"); - masonry_grid = null; - } - }); - - $(".viewport-container").on("loaded-cached", async function () { - if (masonry_grid != null) { - masonry_grid.masonry("layout"); - } - $(youtube_players).each(function () { - if (this.stopVideo) { - this.stopVideo(); - } - }); - }); - - $(".viewport-container-top").on("prepare", async function () { - // Create any carousels that need to be made - create_all_carousels(); - - // More Info page events - request_btn_click_event(); - content_modal_click_event(); - create_report_modal_click_event(); - quick_info_btn_click_event(); - more_info_poster_popup_click_event(); - }); - - $(".viewport-container-top").on("loaded", async function () { - // Uncollapse quick info if the height is small - if ($(".more-info-quick-info.collapse").prop("scrollHeight") <= 250) { - $(".more-info-quick-info.collapse").removeClass("collapse"); - $(".quick-info-read-more-btn").remove(); - } - }); - - $(".viewport-container-top").on("destroy", async function () { - // Carousels - if (review_carousel != null) { - review_carousel.destroy(); - review_carousel = null; - } - if (videos_carousel != null) { - videos_carousel.destroy(); - videos_carousel = null; - } - viewport_carousel_destructor(); - }); - - $(".viewport-container, .viewport-container-top").on( - "prepare", - async function () { - let current_viewport = $(this); - // Component Loader - current_viewport.find(".component-loader").each(async function () { - let loader = $(this); - $.get(loader.data("url"), function (fetched_html) { - current_viewport.trigger("component-loading", [loader]); - let new_element = loader.replaceWithPush(fetched_html); - current_viewport.trigger("component-loaded", [ - new_element, - loader, - ]); - }); - }); - } - ); - - $(".viewport-container, .viewport-container-top").on( - "component-loaded", - // Handling any situations related to the component loader - async function (event, new_element) { - if (new_element.is(".carousel.auto-construct")) { - viewport_carousel_constructor(); - content_modal_click_event(); - } - if (new_element.hasClass("auto-uncollapse")) { - new_element.collapse("show"); - } - server_settings_dropdown_click_event(); - } - ); - - $(".sidebar").on("loaded", async function () { - sidebar_collapse_click_event(); - create_filter_modal_click_event(); - manage_user_btn_click_event(); - }); -}); diff --git a/conreq/core/base/static/js/generic_functions.js b/conreq/core/base/static/js/generic_functions.js deleted file mode 100644 index b9df1742..00000000 --- a/conreq/core/base/static/js/generic_functions.js +++ /dev/null @@ -1,345 +0,0 @@ -var http_request = $.ajax({}); -let start_time, end_time; -var base_url = ""; -var masonry_grid = null; -var infinite_scroller_created = false; -var previous_admin_settings = new Map(); - -// Asychronous sleeping -var sleep = function (ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -}; - -// Returns the window location with the base url added -var add_base_url = function (window_location = null) { - // Get the current location - if (!window_location) { - window_location = get_window_location(); - } - // Append the base URL - if (window_location && !window_location.startsWith(base_url)) { - window_location = base_url + window_location; - } - return window_location; -}; - -// Gets the current window location from the hash -var get_window_location = function (raw = false) { - // Read the URL hash to determine what page we are on - let window_location = window.location.hash.split(/#(.+)/)[1]; - if ( - raw == false && - window_location && - window_location.startsWith("/display/") - ) { - // Remove display from the non-raw url. - // It's only used to signify something is to be added to the secondary viewport. - window_location = window_location.slice("/display".length); - } - if (window_location) { - return window_location; - } - return ""; -}; - -// Gets the current window location from the hash without parameters -var get_window_location_no_params = function () { - let window_location = get_window_location(); - // Read the URL hash to determine what page we are on - if (window_location.includes("?")) { - return window_location.split(/\?(.+)/)[0]; - } - return window_location; -}; - -// Gets the current window location from the hash -var get_window_params = function () { - // Read the URL hash to determine what page we are on - let window_hash = window.location.hash; - - if (window_hash.includes("?")) { - return window.location.hash.split(/\?(.+)/)[1]; - } - return ""; -}; - -// Successful copy event -let copy_to_clipboard_success = async function () { - invite_copied_toast_message(); - $(".invite_link").remove(); -}; - -// Legacy: Copies the text of an element to the clipboard -let copy_to_clipboard_fallback = async function () { - let invite_link_element = document.getElementById("invite_link"); - invite_link_element.select(); - document.execCommand("copy") - ? copy_to_clipboard_success() - : conreq_no_response_toast_message(); -}; - -// Copies the text of an element to the clipboard -var copy_to_clipboard = async function () { - let max_retries = 10; - - // Wait for the element to exist - for (let try_num = 0; try_num <= max_retries; try_num++) { - if (document.getElementById("invite_link") != null) { - break; - } else if (try_num >= max_retries) { - // The element failed to load in time, notify the user. - conreq_no_response_toast_message(); - return; - } - await sleep(250); - } - let invite_link_element = document.getElementById("invite_link"); - - // Copy to clipboard using the Navigator API - if (typeof navigator.clipboard != "undefined") { - window.navigator.clipboard - .writeText(invite_link_element.textContent) - .then(copy_to_clipboard_success, copy_to_clipboard_fallback); - } - - // Fallback to legacy copy to clipboard method - else { - copy_to_clipboard_fallback(); - } -}; - -// Creates a page element that copy_to_clipboard can copy from -var create_invite_link_elem = function (invite_link) { - const el = document.createElement("textarea"); - el.value = invite_link; - el.textContent = invite_link; - el.readOnly = true; - el.style.position = "absolute"; - el.style.left = "-99999px"; - el.id = "invite_link"; - el.className = "invite_link"; - document.body.appendChild(el); -}; - -// Post to a URL -var post_url = function (url, callback) { - http_request.abort(); - http_request = $.ajax({ - type: "POST", - url: url, - headers: { - "X-CSRFToken": document.getElementsByName("csrfmiddlewaretoken")[0] - .value, - }, - success: callback, - }); - return http_request; -}; - -// Post JSON to a URL -var post_json = function (url, data, callback) { - http_request.abort(); - http_request = $.ajax({ - type: "POST", - url: url, - headers: { - "X-CSRFToken": document.getElementsByName("csrfmiddlewaretoken")[0] - .value, - }, - data: JSON.stringify(data), - contentType: "application/json; charset=utf-8", - success: callback, - }); - return http_request; -}; - -// Gets a URL -var get_url = function (location, success = function () {}) { - http_request.abort(); - http_request = $.get(location, function (response = null) { - return success(response); - }); - return http_request; -}; - -// Post a form to a URL -var post_modal_form = function (callback) { - let modal_form = $(".modal-body form"); - if (modal_form.length) { - let url = modal_form.attr("action"); - http_request.abort(); - http_request = $.ajax({ - type: "POST", - url: url, - headers: { - "X-CSRFToken": document.getElementsByName( - "csrfmiddlewaretoken" - )[0].value, - }, - data: modal_form.serialize(), - success: callback, - }); - return http_request; - } - console.warn("Attempted to submit modal form that doesn't exist!"); - return false; -}; - -// Determine what seasons/episodes were selected -var modal_checkbox_aggregator = function () { - let params = { - seasons: [], - episodes: [], - episode_ids: [], - }; - - let season_checkboxes = $(".checkbox"); - let season_checkboxes_not_specials = $(".checkbox:not(.specials)"); - let season_checkboxes_not_specials_checked = $( - ".checkbox:not(.specials):checked" - ); - - let seasons = []; - let episodes = []; - let episode_ids = []; - // Iterate through every season checkbox - season_checkboxes.prop("checked", function (index, season_checkmark) { - // Whole season was requested - if (season_checkmark == true) { - seasons.push($(this).data("season-number")); - } - // Individual episode was requested - else if (season_checkmark == false) { - let episode_container = $($(this).data("all-suboptions-container")); - let episode_checkboxes = episode_container.find("input"); - episode_checkboxes.prop( - "checked", - function (index, episode_checkmark) { - if (episode_checkmark == true) { - episodes.push($(this).data("episode")); - episode_ids.push($(this).data("episode-id")); - } - } - ); - } - }); - - // Request the whole show - if ( - season_checkboxes_not_specials_checked.length == - season_checkboxes_not_specials.length - ) { - return true; - } - - // Request parts of the show - else if (seasons.length || episode_ids.length || episodes.length) { - params.seasons = seasons; - params.episodes = episodes; - params.episode_ids = episode_ids; - return params; - } - - // Request nothing - else { - return params; - } -}; - -// Change a server setting -var change_server_setting = function (setting_name = null, value = null) { - let json_payload = { - setting_name: setting_name, - value: value, - }; - post_json( - $(".viewport.server.settings").data("url"), - json_payload, - function (json_response) { - if (json_response.command_name == "new conreq api key") { - $("#conreq-api-key").text(json_response.value); - } - if (json_response.success) { - generate_viewport(false); - save_success_toast_message(); - } else { - error_toast_message(json_response.error_message); - } - } - ).fail(async function () { - error_toast_message("Internal server error."); - }); -}; - -// Performs a content search -let perform_search = async function (searchbar) { - let searchbar_input = $(searchbar); - let parameters = searchbar_input.val(); - let content_type = searchbar_input.data("content-type"); - let new_location = - searchbar_input.data("search-url") + "?query=" + escape(parameters); - if (content_type) { - new_location += "&content_type=" + content_type; - } - window.location = new_location; -}; - -// Removes old posters from the infinite scroller to save memory -var cull_old_posters = async function () { - let viewport_container = $(viewport_container_class); - let viewport = $(viewport_class); - if (document.querySelector(".viewport-masonry")) { - // Logic to delete excess masonry items - let masonry_items = $(".viewport-masonry > .masonry-item"); - - // Calculate the current state of the viewport - let scroll_position = viewport_container.scrollTop(); - let card_width = $(".masonry-item").outerWidth() + 10; - let card_height = $(".masonry-item").outerHeight() + 10; - let viewport_width = viewport.width(); - let viewport_container_height = viewport_container.height(); - let cards_per_row = (viewport_width + 10) / card_width; - let deletable_num_of_rows = Math.max( - 0, - Math.floor( - (scroll_position - viewport_container_height * 6) / card_height - ) - ); - let num_of_posters_to_delete = deletable_num_of_rows * cards_per_row; - - // If there are posters to delete, do it. - if (num_of_posters_to_delete > 0 && masonry_grid != null) { - // Delete the contents of old elements - masonry_items - .slice(0, num_of_posters_to_delete) - .empty() - .addClass("culled") - .text("Hidden to save memory."); - - // Output to console that posters have been deleted - console.info( - "Hiding the content of " + - num_of_posters_to_delete + - " posters because a new page has loaded." - ); - } - } -}; - -// Hide any floaty objects -var hide_modals_and_popups = async function () { - $("#modal-container").modal("hide"); - $.magnificPopup.close(); - if (window.matchMedia("(max-width: 800px)").matches) { - if (!$("#sidebar").hasClass("collapsed")) { - $("#sidebar").addClass("collapsed"); - } - } -}; - -$.fn.replaceWithPush = function (a) { - let $a = $(DOMPurify.sanitize(a)); - - this.replaceWith($a); - return $a; -}; diff --git a/conreq/core/base/static/js/initialization.js b/conreq/core/base/static/js/initialization.js deleted file mode 100644 index 6c11d87b..00000000 --- a/conreq/core/base/static/js/initialization.js +++ /dev/null @@ -1,117 +0,0 @@ -let current_tab_num = 0; // Current tab is set to be the first tab (0) -let all_tabs = document.getElementsByClassName("tab"); -let all_step_indicators = document.getElementsByClassName("step"); -let last_tab_num = all_tabs.length - 1; -let password = document.getElementById("password"); -let confirm_password = document.getElementById("confirm_password"); - -let show_tab = function () { - // Display the current tab - let all_tabs = document.getElementsByClassName("tab"); - all_tabs[current_tab_num].style.display = "flex"; - - // Change the string in the buttons if needed - if (current_tab_num == last_tab_num) { - document.getElementById("nextBtn").innerHTML = "Submit"; - } else { - document.getElementById("nextBtn").innerHTML = "Next"; - } - - // Hide/show the previous button depending on what page we are on - if (current_tab_num == 0) { - document.getElementById("prevBtn").style.visibility = "hidden"; - } else { - document.getElementById("prevBtn").style.visibility = "visible"; - } -}; - -let next_tab = function () { - // Exit the function if any field in the current tab is invalid - if (!validate_tab()) { - console.warn("Tab not valid!"); - return false; - } - - // if you have reached the end of the form, submit it - if (current_tab_num == last_tab_num) { - document.getElementById("initialization-form").submit(); - return false; - } - - // Hide the current tab: - all_tabs[current_tab_num].style.display = "none"; - - // Otherwise, display the correct tab: - current_tab_num += 1; - show_tab(); - next_step_indicator(); -}; - -let previous_tab = function () { - // Hide the current tab: - all_tabs[current_tab_num].style.display = "none"; - - // Otherwise, display the correct tab: - current_tab_num -= 1; - show_tab(); - previous_step_indicator(); -}; - -let validate_tab = function () { - let input_valid = true; - let required_inputs = all_tabs[current_tab_num].querySelectorAll( - "input[required]" - ); - - // Confirm if all fields are filled out - required_inputs.forEach(function (element) { - if (!element.value) { - input_valid = false; - element.classList.add("invalid"); - } else { - element.classList.remove("invalid"); - } - }); - - // Confirm if passwords match - if (input_valid) { - input_valid = validate_password(); - } - - return input_valid; -}; - -let validate_password = function () { - if (password.value != confirm_password.value) { - passwords_dont_match_toast_message(); - return false; - } else { - return true; - } -}; - -let next_step_indicator = function () { - let previous_step = all_step_indicators[current_tab_num - 1]; - let current_step = all_step_indicators[current_tab_num]; - - if (current_tab_num > 0) { - // Remove active and add finish to the previous step - previous_step.classList.remove("active"); - previous_step.classList.add("finish"); - } - - // Add active to the current step - current_step.classList.add("active"); -}; - -let previous_step_indicator = function () { - let next_step = all_step_indicators[current_tab_num + 1]; - let current_step = all_step_indicators[current_tab_num]; - - // Remove active and finish on the right step - next_step.classList.remove("active"); - next_step.classList.remove("finish"); - // Add active and remove finish on the current step - current_step.classList.remove("finish"); - current_step.classList.add("active"); -}; diff --git a/conreq/core/base/static/js/libraries/dom_purify_2.2.min.js b/conreq/core/base/static/js/libraries/dom_purify_2.2.min.js deleted file mode 100644 index 20e8f49b..00000000 --- a/conreq/core/base/static/js/libraries/dom_purify_2.2.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! @license DOMPurify | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.0.8/LICENSE */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).DOMPurify=t()}(this,(function(){"use strict";var e=Object.hasOwnProperty,t=Object.setPrototypeOf,n=Object.isFrozen,r=Object.freeze,o=Object.seal,i=Object.create,a="undefined"!=typeof Reflect&&Reflect,l=a.apply,c=a.construct;l||(l=function(e,t,n){return e.apply(t,n)}),r||(r=function(e){return e}),o||(o=function(e){return e}),c||(c=function(e,t){return new(Function.prototype.bind.apply(e,[null].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1?n-1:0),o=1;o/gm),F=o(/^data-[\-\w.\u00B7-\uFFFF]/),C=o(/^aria-[\-\w]+$/),H=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),z=o(/^(?:\w+script|data):/i),I=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function U(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:P(),n=function(t){return e(t)};if(n.version="2.2.2",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;var o=t.document,i=t.document,a=t.DocumentFragment,l=t.HTMLTemplateElement,c=t.Node,s=t.NodeFilter,T=t.NamedNodeMap,B=void 0===T?t.NamedNodeMap||t.MozNamedAttrMap:T,G=t.Text,q=t.Comment,K=t.DOMParser,V=t.trustedTypes;if("function"==typeof l){var Y=i.createElement("template");Y.content&&Y.content.ownerDocument&&(i=Y.content.ownerDocument)}var X=W(V,o),$=X&&Le?X.createHTML(""):"",Z=i,J=Z.implementation,Q=Z.createNodeIterator,ee=Z.getElementsByTagName,te=Z.createDocumentFragment,ne=o.importNode,re={};try{re=x(i).documentMode?i.documentMode:{}}catch(e){}var oe={};n.isSupported=J&&void 0!==J.createHTMLDocument&&9!==re;var ie=N,ae=R,le=F,ce=C,se=z,ue=I,de=H,fe=null,pe=A({},[].concat(U(S),U(k),U(_),U(D),U(E))),me=null,ye=A({},[].concat(U(L),U(w),U(M),U(O))),he=null,ge=null,ve=!0,be=!0,Te=!1,Ae=!1,xe=!1,Se=!1,ke=!1,_e=!1,De=!1,Ee=!0,Le=!1,we=!0,Me=!0,Oe=!1,Ne={},Re=A({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","plaintext","script","style","svg","template","thead","title","video","xmp"]),Fe=null,Ce=A({},["audio","video","img","source","image","track"]),He=null,ze=A({},["alt","class","for","id","label","name","pattern","placeholder","summary","title","value","style","xmlns"]),Ie=null,je=i.createElement("form"),Ue=function(e){Ie&&Ie===e||(e&&"object"===(void 0===e?"undefined":j(e))||(e={}),e=x(e),fe="ALLOWED_TAGS"in e?A({},e.ALLOWED_TAGS):pe,me="ALLOWED_ATTR"in e?A({},e.ALLOWED_ATTR):ye,He="ADD_URI_SAFE_ATTR"in e?A(x(ze),e.ADD_URI_SAFE_ATTR):ze,Fe="ADD_DATA_URI_TAGS"in e?A(x(Ce),e.ADD_DATA_URI_TAGS):Ce,he="FORBID_TAGS"in e?A({},e.FORBID_TAGS):{},ge="FORBID_ATTR"in e?A({},e.FORBID_ATTR):{},Ne="USE_PROFILES"in e&&e.USE_PROFILES,ve=!1!==e.ALLOW_ARIA_ATTR,be=!1!==e.ALLOW_DATA_ATTR,Te=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ae=e.SAFE_FOR_TEMPLATES||!1,xe=e.WHOLE_DOCUMENT||!1,_e=e.RETURN_DOM||!1,De=e.RETURN_DOM_FRAGMENT||!1,Ee=!1!==e.RETURN_DOM_IMPORT,Le=e.RETURN_TRUSTED_TYPE||!1,ke=e.FORCE_BODY||!1,we=!1!==e.SANITIZE_DOM,Me=!1!==e.KEEP_CONTENT,Oe=e.IN_PLACE||!1,de=e.ALLOWED_URI_REGEXP||de,Ae&&(be=!1),De&&(_e=!0),Ne&&(fe=A({},[].concat(U(E))),me=[],!0===Ne.html&&(A(fe,S),A(me,L)),!0===Ne.svg&&(A(fe,k),A(me,w),A(me,O)),!0===Ne.svgFilters&&(A(fe,_),A(me,w),A(me,O)),!0===Ne.mathMl&&(A(fe,D),A(me,M),A(me,O))),e.ADD_TAGS&&(fe===pe&&(fe=x(fe)),A(fe,e.ADD_TAGS)),e.ADD_ATTR&&(me===ye&&(me=x(me)),A(me,e.ADD_ATTR)),e.ADD_URI_SAFE_ATTR&&A(He,e.ADD_URI_SAFE_ATTR),Me&&(fe["#text"]=!0),xe&&A(fe,["html","head","body"]),fe.table&&(A(fe,["tbody"]),delete he.tbody),r&&r(e),Ie=e)},Pe=function(e){f(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){e.outerHTML=$}},We=function(e,t){try{f(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(n.removed,{attribute:null,from:t})}t.removeAttribute(e)},Be=function(e){var t=void 0,n=void 0;if(ke)e=""+e;else{var r=m(e,/^[\r\n\t ]+/);n=r&&r[0]}var o=X?X.createHTML(e):e;try{t=(new K).parseFromString(o,"text/html")}catch(e){}if(!t||!t.documentElement){var a=(t=J.createHTMLDocument("")).body;a.parentNode.removeChild(a.parentNode.firstElementChild),a.outerHTML=o}return e&&n&&t.body.insertBefore(i.createTextNode(n),t.body.childNodes[0]||null),ee.call(t,xe?"html":"body")[0]},Ge=function(e){return Q.call(e.ownerDocument||e,e,s.SHOW_ELEMENT|s.SHOW_COMMENT|s.SHOW_TEXT,(function(){return s.FILTER_ACCEPT}),!1)},qe=function(e){return!(e instanceof G||e instanceof q)&&!("string"==typeof e.nodeName&&"string"==typeof e.textContent&&"function"==typeof e.removeChild&&e.attributes instanceof B&&"function"==typeof e.removeAttribute&&"function"==typeof e.setAttribute&&"string"==typeof e.namespaceURI)},Ke=function(e){return"object"===(void 0===c?"undefined":j(c))?e instanceof c:e&&"object"===(void 0===e?"undefined":j(e))&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},Ve=function(e,t,r){oe[e]&&u(oe[e],(function(e){e.call(n,t,r,Ie)}))},Ye=function(e){var t=void 0;if(Ve("beforeSanitizeElements",e,null),qe(e))return Pe(e),!0;if(m(e.nodeName,/[\u0080-\uFFFF]/))return Pe(e),!0;var r=p(e.nodeName);if(Ve("uponSanitizeElement",e,{tagName:r,allowedTags:fe}),("svg"===r||"math"===r)&&0!==e.querySelectorAll("p, br, form, table").length)return Pe(e),!0;if(!Ke(e.firstElementChild)&&(!Ke(e.content)||!Ke(e.content.firstElementChild))&&v(/<[!/\w]/g,e.innerHTML)&&v(/<[!/\w]/g,e.textContent))return Pe(e),!0;if(!fe[r]||he[r]){if(Me&&!Re[r]&&"function"==typeof e.insertAdjacentHTML)try{var o=e.innerHTML;e.insertAdjacentHTML("AfterEnd",X?X.createHTML(o):o)}catch(e){}return Pe(e),!0}return"noscript"!==r&&"noembed"!==r||!v(/<\/no(script|embed)/i,e.innerHTML)?(Ae&&3===e.nodeType&&(t=e.textContent,t=y(t,ie," "),t=y(t,ae," "),e.textContent!==t&&(f(n.removed,{element:e.cloneNode()}),e.textContent=t)),Ve("afterSanitizeElements",e,null),!1):(Pe(e),!0)},Xe=function(e,t,n){if(we&&("id"===t||"name"===t)&&(n in i||n in je))return!1;if(be&&v(le,t));else if(ve&&v(ce,t));else{if(!me[t]||ge[t])return!1;if(He[t]);else if(v(de,y(n,ue,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==h(n,"data:")||!Fe[e]){if(Te&&!v(se,y(n,ue,"")));else if(n)return!1}else;}return!0},$e=function(e){var t=void 0,r=void 0,o=void 0,i=void 0;Ve("beforeSanitizeAttributes",e,null);var a=e.attributes;if(a){var l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:me};for(i=a.length;i--;){var c=t=a[i],s=c.name,u=c.namespaceURI;if(r=g(t.value),o=p(s),l.attrName=o,l.attrValue=r,l.keepAttr=!0,l.forceKeepAttr=void 0,Ve("uponSanitizeAttribute",e,l),r=l.attrValue,!l.forceKeepAttr&&(We(s,e),l.keepAttr))if(v(/\/>/i,r))We(s,e);else{Ae&&(r=y(r,ie," "),r=y(r,ae," "));var f=e.nodeName.toLowerCase();if(Xe(f,o,r))try{u?e.setAttributeNS(u,s,r):e.setAttribute(s,r),d(n.removed)}catch(e){}}}Ve("afterSanitizeAttributes",e,null)}},Ze=function e(t){var n=void 0,r=Ge(t);for(Ve("beforeSanitizeShadowDOM",t,null);n=r.nextNode();)Ve("uponSanitizeShadowNode",n,null),Ye(n)||(n.content instanceof a&&e(n.content),$e(n));Ve("afterSanitizeShadowDOM",t,null)};return n.sanitize=function(e,r){var i=void 0,l=void 0,s=void 0,u=void 0,d=void 0;if(e||(e="\x3c!--\x3e"),"string"!=typeof e&&!Ke(e)){if("function"!=typeof e.toString)throw b("toString is not a function");if("string"!=typeof(e=e.toString()))throw b("dirty is not a string, aborting")}if(!n.isSupported){if("object"===j(t.toStaticHTML)||"function"==typeof t.toStaticHTML){if("string"==typeof e)return t.toStaticHTML(e);if(Ke(e))return t.toStaticHTML(e.outerHTML)}return e}if(Se||Ue(r),n.removed=[],"string"==typeof e&&(Oe=!1),Oe);else if(e instanceof c)1===(l=(i=Be("\x3c!----\x3e")).ownerDocument.importNode(e,!0)).nodeType&&"BODY"===l.nodeName||"HTML"===l.nodeName?i=l:i.appendChild(l);else{if(!_e&&!Ae&&!xe&&-1===e.indexOf("<"))return X&&Le?X.createHTML(e):e;if(!(i=Be(e)))return _e?null:$}i&&ke&&Pe(i.firstChild);for(var f=Ge(Oe?e:i);s=f.nextNode();)3===s.nodeType&&s===u||Ye(s)||(s.content instanceof a&&Ze(s.content),$e(s),u=s);if(u=null,Oe)return e;if(_e){if(De)for(d=te.call(i.ownerDocument);i.firstChild;)d.appendChild(i.firstChild);else d=i;return Ee&&(d=ne.call(o,d,!0)),d}var p=xe?i.outerHTML:i.innerHTML;return Ae&&(p=y(p,ie," "),p=y(p,ae," ")),X&&Le?X.createHTML(p):p},n.setConfig=function(e){Ue(e),Se=!0},n.clearConfig=function(){Ie=null,Se=!1},n.isValidAttribute=function(e,t,n){Ie||Ue({});var r=p(e),o=p(t);return Xe(r,o,n)},n.addHook=function(e,t){"function"==typeof t&&(oe[e]=oe[e]||[],f(oe[e],t))},n.removeHook=function(e){oe[e]&&d(oe[e])},n.removeHooks=function(e){oe[e]&&(oe[e]=[])},n.removeAllHooks=function(){oe={}},n}()})); -//# sourceMappingURL=dom_purify_2.2.min.map diff --git a/conreq/core/base/static/js/libraries/dom_purify_2.2.min.map b/conreq/core/base/static/js/libraries/dom_purify_2.2.min.map deleted file mode 100644 index c467cd1c..00000000 --- a/conreq/core/base/static/js/libraries/dom_purify_2.2.min.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"purify.min.js","sources":["../src/utils.js","../src/tags.js","../src/attrs.js","../src/regexp.js","../src/purify.js"],"sourcesContent":["const { hasOwnProperty, setPrototypeOf, isFrozen } = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\nexport function unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\nexport function unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/* Add properties to a lookup table */\nexport function addToSet(set, array) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = stringToLowerCase(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/* Shallow clone an object */\nexport function clone(object) {\n const newObject = create(null);\n\n let property;\n for (property in object) {\n if (apply(hasOwnProperty, object, [property])) {\n newObject[property] = object[property];\n }\n }\n\n return newObject;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n freeze,\n hasOwnProperty,\n isFrozen,\n setPrototypeOf,\n seal,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringTrim,\n // Errors\n typeErrorCreate,\n};\n","import { freeze } from './utils';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'audio',\n 'canvas',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'video',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n]);\n\nexport const text = freeze(['#text']);\n","import { freeze } from './utils';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'xmlns',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n","import { seal } from './utils';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\s\\S]*|[\\s\\S]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\s\\S]*|[\\s\\S]*%>/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\n","import * as TAGS from './tags';\nimport * as ATTRS from './attrs';\nimport * as EXPRESSIONS from './regexp';\nimport {\n addToSet,\n clone,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n} from './utils';\n\nconst getGlobal = () => (typeof window === 'undefined' ? null : window);\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {Document} document The document object (to determine policy name suffix)\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, document) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (\n document.currentScript &&\n document.currentScript.hasAttribute(ATTR_NAME)\n ) {\n suffix = document.currentScript.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n const originalDocument = window.document;\n\n let { document } = window;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n Text,\n Comment,\n DOMParser,\n trustedTypes,\n } = window;\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n const trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n originalDocument\n );\n const emptyHTML =\n trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML('')\n : '';\n\n const {\n implementation,\n createNodeIterator,\n getElementsByTagName,\n createDocumentFragment,\n } = document;\n const { importNode } = originalDocument;\n\n let documentMode = {};\n try {\n documentMode = clone(document).documentMode ? document.documentMode : {};\n } catch (_) {}\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n implementation &&\n typeof implementation.createHTMLDocument !== 'undefined' &&\n documentMode !== 9;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM\n * `Node` is imported into the current `Document`. If this flag is not enabled the\n * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by\n * DOMPurify.\n *\n * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`\n * might cause XSS from attacks hidden in closed shadowroots in case the browser\n * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/\n */\n let RETURN_DOM_IMPORT = true;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks? */\n let SANITIZE_DOM = true;\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n const FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n /* Set configuration parameters */\n ALLOWED_TAGS =\n 'ALLOWED_TAGS' in cfg\n ? addToSet({}, cfg.ALLOWED_TAGS)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR =\n 'ALLOWED_ATTR' in cfg\n ? addToSet({}, cfg.ALLOWED_ATTR)\n : DEFAULT_ALLOWED_ATTR;\n URI_SAFE_ATTRIBUTES =\n 'ADD_URI_SAFE_ATTR' in cfg\n ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR)\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS =\n 'ADD_DATA_URI_TAGS' in cfg\n ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS)\n : DEFAULT_DATA_URI_TAGS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [...TAGS.text]);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n const _forceRemove = function (node) {\n arrayPush(DOMPurify.removed, { element: node });\n try {\n node.parentNode.removeChild(node);\n } catch (_) {\n node.outerHTML = emptyHTML;\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n const _removeAttribute = function (name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node,\n });\n }\n\n node.removeAttribute(name);\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty) {\n /* Create a HTML document */\n let doc;\n let leadingWhitespace;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n const dirtyPayload = trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n /* Use the DOMParser API by default, fallback later if needs be */\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');\n } catch (_) {}\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createHTMLDocument('');\n const { body } = doc;\n body.parentNode.removeChild(body.parentNode.firstElementChild);\n body.outerHTML = dirtyPayload;\n }\n\n if (dirty && leadingWhitespace) {\n doc.body.insertBefore(\n document.createTextNode(leadingWhitespace),\n doc.body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n };\n\n /**\n * _createIterator\n *\n * @param {Document} root document/fragment to create iterator for\n * @return {Iterator} iterator instance\n */\n const _createIterator = function (root) {\n return createNodeIterator.call(\n root.ownerDocument || root,\n root,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT,\n () => {\n return NodeFilter.FILTER_ACCEPT;\n },\n false\n );\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n const _isClobbered = function (elm) {\n if (elm instanceof Text || elm instanceof Comment) {\n return false;\n }\n\n if (\n typeof elm.nodeName !== 'string' ||\n typeof elm.textContent !== 'string' ||\n typeof elm.removeChild !== 'function' ||\n !(elm.attributes instanceof NamedNodeMap) ||\n typeof elm.removeAttribute !== 'function' ||\n typeof elm.setAttribute !== 'function' ||\n typeof elm.namespaceURI !== 'string'\n ) {\n return true;\n }\n\n return false;\n };\n\n /**\n * _isNode\n *\n * @param {Node} obj object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n const _isNode = function (object) {\n return typeof Node === 'object'\n ? object instanceof Node\n : object &&\n typeof object === 'object' &&\n typeof object.nodeType === 'number' &&\n typeof object.nodeName === 'string';\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n const _executeHook = function (entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], (hook) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n const _sanitizeElements = function (currentNode) {\n let content;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check if tagname contains Unicode */\n if (stringMatch(currentNode.nodeName, /[\\u0080-\\uFFFF]/)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = stringToLowerCase(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* Take care of an mXSS pattern using p, br inside svg, math */\n if (\n (tagName === 'svg' || tagName === 'math') &&\n currentNode.querySelectorAll('p, br, form, table').length !== 0\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n !_isNode(currentNode.firstElementChild) &&\n (!_isNode(currentNode.content) ||\n !_isNode(currentNode.content.firstElementChild)) &&\n regExpTest(/<[!/\\w]/g, currentNode.innerHTML) &&\n regExpTest(/<[!/\\w]/g, currentNode.textContent)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Keep content except for bad-listed elements */\n if (\n KEEP_CONTENT &&\n !FORBID_CONTENTS[tagName] &&\n typeof currentNode.insertAdjacentHTML === 'function'\n ) {\n try {\n const htmlToInsert = currentNode.innerHTML;\n currentNode.insertAdjacentHTML(\n 'AfterEnd',\n trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(htmlToInsert)\n : htmlToInsert\n );\n } catch (_) {}\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove in case a noscript/noembed XSS is suspected */\n if (\n (tagName === 'noscript' || tagName === 'noembed') &&\n regExpTest(/<\\/no(script|embed)/i, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {\n /* Get the element's text content */\n content = currentNode.textContent;\n content = stringReplace(content, MUSTACHE_EXPR, ' ');\n content = stringReplace(content, ERB_EXPR, ' ');\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR, lcName)) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n return false;\n\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n // eslint-disable-next-line no-negated-condition\n } else if (!value) {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n } else {\n return false;\n }\n\n return true;\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode) {\n let attr;\n let value;\n let lcName;\n let l;\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes) {\n return;\n }\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n };\n l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n attr = attributes[l];\n const { name, namespaceURI } = attr;\n value = stringTrim(attr.value);\n lcName = stringToLowerCase(name);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n value = stringReplace(value, MUSTACHE_EXPR, ' ');\n value = stringReplace(value, ERB_EXPR, ' ');\n }\n\n /* Is `value` valid for this attribute? */\n const lcTag = currentNode.nodeName.toLowerCase();\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n arrayPop(DOMPurify.removed);\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment) {\n let shadowNode;\n const shadowIterator = _createIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} configuration object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg) {\n let body;\n let importedNode;\n let currentNode;\n let oldNode;\n let returnNode;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n if (!dirty) {\n dirty = '';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n // eslint-disable-next-line no-negated-condition\n if (typeof dirty.toString !== 'function') {\n throw typeErrorCreate('toString is not a function');\n } else {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n }\n }\n\n /* Check we can run. Otherwise fall back or ignore */\n if (!DOMPurify.isSupported) {\n if (\n typeof window.toStaticHTML === 'object' ||\n typeof window.toStaticHTML === 'function'\n ) {\n if (typeof dirty === 'string') {\n return window.toStaticHTML(dirty);\n }\n\n if (_isNode(dirty)) {\n return window.toStaticHTML(dirty.outerHTML);\n }\n }\n\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) {\n /* No special handling necessary for in-place sanitization */\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : emptyHTML;\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const nodeIterator = _createIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while ((currentNode = nodeIterator.nextNode())) {\n /* Fix IE's strange behavior with manipulated textNodes #89 */\n if (currentNode.nodeType === 3 && currentNode === oldNode) {\n continue;\n }\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n\n oldNode = currentNode;\n }\n\n oldNode = null;\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (RETURN_DOM_IMPORT) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' ');\n serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' ');\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(serializedHTML)\n : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {string} tag Tag name of containing element.\n * @param {string} attr Attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = stringToLowerCase(tag);\n const lcName = stringToLowerCase(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n *\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n"],"names":["hasOwnProperty","Object","setPrototypeOf","isFrozen","freeze","seal","create","Reflect","apply","construct","fun","thisValue","args","x","Func","func","arrayForEach","unapply","Array","prototype","forEach","arrayPop","pop","arrayPush","push","stringToLowerCase","String","toLowerCase","stringMatch","match","stringReplace","replace","stringIndexOf","indexOf","stringTrim","trim","regExpTest","RegExp","test","typeErrorCreate","TypeError","thisArg","addToSet","set","array","l","length","element","lcElement","clone","object","newObject","property","html","svg","svgFilters","mathMl","text","xml","MUSTACHE_EXPR","ERB_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","getGlobal","window","_createTrustedTypesPolicy","trustedTypes","document","createPolicy","suffix","currentScript","hasAttribute","getAttribute","policyName","_","warn","createDOMPurify","DOMPurify","root","version","VERSION","removed","nodeType","isSupported","originalDocument","DocumentFragment","HTMLTemplateElement","Node","NodeFilter","NamedNodeMap","MozNamedAttrMap","Text","Comment","DOMParser","template","createElement","content","ownerDocument","trustedTypesPolicy","emptyHTML","RETURN_TRUSTED_TYPE","createHTML","implementation","createNodeIterator","getElementsByTagName","createDocumentFragment","importNode","documentMode","hooks","createHTMLDocument","EXPRESSIONS","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","ATTRS","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","SAFE_FOR_TEMPLATES","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_DOM_IMPORT","SANITIZE_DOM","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","CONFIG","formElement","_parseConfig","cfg","ADD_URI_SAFE_ATTR","ADD_DATA_URI_TAGS","ALLOWED_URI_REGEXP","ADD_TAGS","ADD_ATTR","table","tbody","_forceRemove","node","parentNode","removeChild","outerHTML","_removeAttribute","name","getAttributeNode","removeAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","parseFromString","documentElement","body","firstElementChild","insertBefore","createTextNode","childNodes","call","_createIterator","SHOW_ELEMENT","SHOW_COMMENT","SHOW_TEXT","FILTER_ACCEPT","_isClobbered","elm","nodeName","textContent","attributes","setAttribute","namespaceURI","_isNode","_executeHook","entryPoint","currentNode","data","hook","_sanitizeElements","tagName","querySelectorAll","innerHTML","insertAdjacentHTML","htmlToInsert","cloneNode","_isValidAttribute","lcTag","lcName","value","_sanitizeAttributes","attr","hookEvent","attrName","attrValue","keepAttr","forceKeepAttr","undefined","setAttributeNS","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","nextNode","sanitize","importedNode","oldNode","returnNode","toString","_typeof","toStaticHTML","appendChild","firstChild","nodeIterator","serializedHTML","setConfig","clearConfig","isValidAttribute","tag","addHook","hookFunction","removeHook","removeHooks","removeAllHooks"],"mappings":";oMAAQA,EAA6CC,OAA7CD,eAAgBE,EAA6BD,OAA7BC,eAAgBC,EAAaF,OAAbE,SAElCC,EAAyBH,OAAzBG,OAAQC,EAAiBJ,OAAjBI,KAAMC,EAAWL,OAAXK,SAC0B,oBAAZC,SAA2BA,QAAvDC,IAAAA,MAAOC,IAAAA,UAERD,MACK,SAAUE,EAAKC,EAAWC,UACzBF,EAAIF,MAAMG,EAAWC,KAI3BR,MACM,SAAUS,UACVA,IAINR,MACI,SAAUQ,UACRA,IAINJ,MACS,SAAUK,EAAMF,4CACfE,uIAAQF,QAIvB,IAoB4BG,EApBtBC,EAAeC,EAAQC,MAAMC,UAAUC,SAEvCC,EAAWJ,EAAQC,MAAMC,UAAUG,KACnCC,EAAYN,EAAQC,MAAMC,UAAUK,MAGpCC,EAAoBR,EAAQS,OAAOP,UAAUQ,aAC7CC,EAAcX,EAAQS,OAAOP,UAAUU,OACvCC,EAAgBb,EAAQS,OAAOP,UAAUY,SACzCC,EAAgBf,EAAQS,OAAOP,UAAUc,SACzCC,EAAajB,EAAQS,OAAOP,UAAUgB,MAEtCC,EAAanB,EAAQoB,OAAOlB,UAAUmB,MAEtCC,GAMsBxB,EANQyB,UAO3B,sCAAI5B,gDAASH,EAAUM,EAAMH,KAL/B,SAASK,EAAQF,UACf,SAAC0B,8BAAY7B,0DAASJ,EAAMO,EAAM0B,EAAS7B,IAQ7C,SAAS8B,EAASC,EAAKC,GACxB1C,KAIayC,EAAK,cAGlBE,EAAID,EAAME,OACPD,KAAK,KACNE,EAAUH,EAAMC,MACG,iBAAZE,EAAsB,KACzBC,EAAYvB,EAAkBsB,GAChCC,IAAcD,IAEX5C,EAASyC,OACNC,GAAKG,KAGHA,KAIVD,IAAW,SAGVJ,EAIF,SAASM,EAAMC,OACdC,EAAY7C,EAAO,MAErB8C,aACCA,KAAYF,EACX1C,EAAMR,EAAgBkD,EAAQ,CAACE,QACvBA,GAAYF,EAAOE,WAI1BD,EC5FF,IAAME,EAAOjD,EAAO,CACzB,IACA,OACA,UACA,UACA,OACA,UACA,QACA,QACA,IACA,MACA,MACA,MACA,QACA,aACA,OACA,KACA,SACA,SACA,UACA,SACA,OACA,OACA,MACA,WACA,UACA,OACA,WACA,KACA,YACA,MACA,UACA,MACA,SACA,MACA,MACA,KACA,KACA,UACA,KACA,WACA,aACA,SACA,OACA,SACA,OACA,KACA,KACA,KACA,KACA,KACA,KACA,OACA,SACA,SACA,KACA,OACA,IACA,MACA,QACA,MACA,MACA,QACA,SACA,KACA,OACA,MACA,OACA,UACA,OACA,WACA,QACA,MACA,OACA,KACA,WACA,SACA,SACA,IACA,UACA,MACA,WACA,IACA,KACA,KACA,OACA,IACA,OACA,UACA,SACA,SACA,QACA,SACA,SACA,OACA,SACA,SACA,QACA,MACA,UACA,MACA,QACA,QACA,KACA,WACA,WACA,QACA,KACA,QACA,OACA,KACA,QACA,KACA,IACA,KACA,MACA,QACA,QAIWkD,EAAMlD,EAAO,CACxB,MACA,IACA,WACA,cACA,eACA,eACA,gBACA,mBACA,QACA,SACA,SACA,WACA,OACA,OACA,UACA,SACA,OACA,IACA,QACA,WACA,QACA,QACA,OACA,iBACA,SACA,OACA,WACA,QACA,OACA,UACA,UACA,WACA,iBACA,OACA,OACA,QACA,SACA,SACA,OACA,WACA,QACA,OACA,QACA,QACA,OACA,UAGWmD,EAAanD,EAAO,CAC/B,UACA,gBACA,sBACA,cACA,mBACA,oBACA,oBACA,iBACA,UACA,UACA,UACA,UACA,UACA,iBACA,UACA,cACA,eACA,WACA,eACA,qBACA,cACA,SACA,iBAGWoD,EAASpD,EAAO,CAC3B,OACA,WACA,SACA,UACA,QACA,SACA,KACA,aACA,gBACA,KACA,KACA,QACA,UACA,WACA,QACA,OACA,KACA,SACA,QACA,SACA,OACA,OACA,UACA,SACA,MACA,QACA,MACA,SACA,eAGWqD,EAAOrD,EAAO,CAAC,UCpOfiD,EAAOjD,EAAO,CACzB,SACA,SACA,QACA,MACA,iBACA,eACA,uBACA,WACA,aACA,UACA,SACA,UACA,cACA,cACA,UACA,OACA,QACA,QACA,QACA,OACA,UACA,WACA,eACA,SACA,cACA,WACA,WACA,UACA,MACA,WACA,0BACA,wBACA,WACA,YACA,UACA,eACA,OACA,MACA,UACA,SACA,SACA,OACA,OACA,WACA,KACA,YACA,YACA,QACA,OACA,QACA,OACA,OACA,UACA,OACA,MACA,MACA,YACA,QACA,SACA,MACA,YACA,WACA,QACA,OACA,UACA,aACA,SACA,OACA,UACA,UACA,cACA,cACA,SACA,UACA,UACA,aACA,WACA,MACA,WACA,MACA,WACA,OACA,OACA,UACA,aACA,QACA,WACA,QACA,OACA,QACA,OACA,UACA,QACA,MACA,SACA,OACA,QACA,UACA,WACA,QACA,YACA,OACA,SACA,SACA,QACA,QACA,UAGWkD,EAAMlD,EAAO,CACxB,gBACA,aACA,WACA,qBACA,SACA,gBACA,gBACA,UACA,gBACA,iBACA,QACA,OACA,KACA,QACA,OACA,gBACA,YACA,YACA,QACA,sBACA,8BACA,gBACA,kBACA,KACA,KACA,IACA,KACA,KACA,kBACA,YACA,UACA,UACA,MACA,WACA,YACA,MACA,OACA,eACA,YACA,SACA,cACA,cACA,gBACA,cACA,YACA,mBACA,eACA,aACA,eACA,cACA,KACA,KACA,KACA,KACA,aACA,WACA,gBACA,oBACA,SACA,OACA,KACA,kBACA,KACA,MACA,IACA,KACA,KACA,KACA,KACA,UACA,YACA,aACA,WACA,OACA,eACA,iBACA,eACA,mBACA,iBACA,QACA,aACA,aACA,eACA,eACA,cACA,cACA,mBACA,YACA,MACA,OACA,QACA,SACA,OACA,MACA,OACA,aACA,SACA,WACA,UACA,QACA,SACA,cACA,SACA,WACA,cACA,OACA,aACA,sBACA,mBACA,eACA,SACA,gBACA,sBACA,iBACA,IACA,KACA,KACA,SACA,OACA,OACA,cACA,YACA,UACA,SACA,SACA,QACA,OACA,kBACA,mBACA,mBACA,eACA,cACA,eACA,cACA,aACA,eACA,mBACA,oBACA,iBACA,kBACA,oBACA,iBACA,SACA,eACA,QACA,eACA,iBACA,WACA,UACA,UACA,YACA,cACA,kBACA,iBACA,aACA,OACA,KACA,KACA,UACA,SACA,UACA,aACA,UACA,aACA,gBACA,gBACA,QACA,eACA,OACA,eACA,mBACA,mBACA,IACA,KACA,KACA,QACA,IACA,KACA,KACA,IACA,eAGWoD,EAASpD,EAAO,CAC3B,SACA,cACA,QACA,WACA,QACA,eACA,cACA,aACA,aACA,QACA,MACA,UACA,eACA,WACA,QACA,QACA,SACA,OACA,KACA,UACA,SACA,gBACA,SACA,SACA,iBACA,YACA,WACA,cACA,UACA,UACA,gBACA,WACA,WACA,OACA,WACA,WACA,aACA,UACA,SACA,SACA,cACA,gBACA,uBACA,YACA,YACA,aACA,WACA,iBACA,iBACA,YACA,UACA,QACA,UAGWsD,EAAMtD,EAAO,CACxB,aACA,SACA,cACA,YACA,gBClWWuD,EAAgBtD,EAAK,6BACrBuD,EAAWvD,EAAK,yBAChBwD,EAAYxD,EAAK,8BACjByD,EAAYzD,EAAK,kBACjB0D,EAAiB1D,EAC5B,yFAEW2D,EAAoB3D,EAAK,yBACzB4D,EAAkB5D,EAC7B,mYCOF,IAAM6D,EAAY,iBAAyB,oBAAXC,OAAyB,KAAOA,QAU1DC,EAA4B,SAAUC,EAAcC,MAE9B,qBAAjBD,gBAAAA,KAC8B,mBAA9BA,EAAaE,oBAEb,SAMLC,EAAS,KAGXF,EAASG,eACTH,EAASG,cAAcC,aAHP,6BAKPJ,EAASG,cAAcE,aALhB,8BAQZC,EAAa,aAAeJ,EAAS,IAAMA,EAAS,eAGjDH,EAAaE,aAAaK,EAAY,qBAChCvB,UACFA,KAGX,MAAOwB,kBAICC,KACN,uBAAyBF,EAAa,0BAEjC,cAIX,SAASG,QAAgBZ,yDAASD,IAC1Bc,EAAY,SAACC,UAASF,EAAgBE,SAMlCC,QAAUC,UAMVC,QAAU,IAEfjB,IAAWA,EAAOG,UAAyC,IAA7BH,EAAOG,SAASe,kBAGvCC,aAAc,EAEjBN,MAGHO,EAAmBpB,EAAOG,SAE1BA,EAAaH,EAAbG,SAEJkB,EASErB,EATFqB,iBACAC,EAQEtB,EARFsB,oBACAC,EAOEvB,EAPFuB,K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"} \ No newline at end of file diff --git a/conreq/core/base/static/js/libraries/magnific_popup_1.1.0.min.js b/conreq/core/base/static/js/libraries/magnific_popup_1.1.0.min.js deleted file mode 100644 index 6ee3a3bd..00000000 --- a/conreq/core/base/static/js/libraries/magnific_popup_1.1.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! Magnific Popup - v1.1.0 - 2016-02-20 -* http://dimsemenov.com/plugins/magnific-popup/ -* Copyright (c) 2016 Dmitry Semenov; */ -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):window.jQuery||window.Zepto)}(function(a){var b,c,d,e,f,g,h="Close",i="BeforeClose",j="AfterClose",k="BeforeAppend",l="MarkupParse",m="Open",n="Change",o="mfp",p="."+o,q="mfp-ready",r="mfp-removing",s="mfp-prevent-close",t=function(){},u=!!window.jQuery,v=a(window),w=function(a,c){b.ev.on(o+a+p,c)},x=function(b,c,d,e){var f=document.createElement("div");return f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(c,d){b.ev.triggerHandler(o+c,d),b.st.callbacks&&(c=c.charAt(0).toLowerCase()+c.slice(1),b.st.callbacks[c]&&b.st.callbacks[c].apply(b,a.isArray(d)?d:[d]))},z=function(c){return c===g&&b.currTemplate.closeBtn||(b.currTemplate.closeBtn=a(b.st.closeMarkup.replace("%title%",b.st.tClose)),g=c),b.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(b=new t,b.init(),a.magnificPopup.instance=b)},B=function(){var a=document.createElement("p").style,b=["ms","O","Moz","Webkit"];if(void 0!==a.transition)return!0;for(;b.length;)if(b.pop()+"Transition"in a)return!0;return!1};t.prototype={constructor:t,init:function(){var c=navigator.appVersion;b.isLowIE=b.isIE8=document.all&&!document.addEventListener,b.isAndroid=/android/gi.test(c),b.isIOS=/iphone|ipad|ipod/gi.test(c),b.supportsTransition=B(),b.probablyMobile=b.isAndroid||b.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),d=a(document),b.popupsCache={}},open:function(c){var e;if(c.isObj===!1){b.items=c.items.toArray(),b.index=0;var g,h=c.items;for(e=0;e(a||v.height())},_setFocus:function(){(b.st.focus?b.content.find(b.st.focus).eq(0):b.wrap).focus()},_onFocusIn:function(c){return c.target===b.wrap[0]||a.contains(b.wrap[0],c.target)?void 0:(b._setFocus(),!1)},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(l,[b,c,d]),a.each(c,function(c,d){if(void 0===d||d===!1)return!0;if(e=c.split("_"),e.length>1){var f=b.find(p+"-"+e[0]);if(f.length>0){var g=e[1];"replaceWith"===g?f[0]!==d[0]&&f.replaceWith(d):"img"===g?f.is("img")?f.attr("src",d):f.replaceWith(a("").attr("src",d).attr("class",f.attr("class"))):f.attr(e[1],d)}}else b.find(p+"-"+c).html(d)})},_getScrollbarSize:function(){if(void 0===b.scrollbarSize){var a=document.createElement("div");a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),b.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return b.scrollbarSize}},a.magnificPopup={instance:null,proto:t.prototype,modules:[],open:function(b,c){return A(),b=b?a.extend(!0,{},b):{},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0}},a.fn.magnificPopup=function(c){A();var d=a(this);if("string"==typeof c)if("open"===c){var e,f=u?d.data("magnificPopup"):d[0].magnificPopup,g=parseInt(arguments[1],10)||0;f.items?e=f.items[g]:(e=d,f.delegate&&(e=e.find(f.delegate)),e=e.eq(g)),b._openClick({mfpEl:e},d,f)}else b.isOpen&&b[c].apply(b,Array.prototype.slice.call(arguments,1));else c=a.extend(!0,{},c),u?d.data("magnificPopup",c):d[0].magnificPopup=c,b.addGroup(d,c);return d};var C,D,E,F="inline",G=function(){E&&(D.after(E.addClass(C)).detach(),E=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){b.types.push(F),w(h+"."+F,function(){G()})},getInline:function(c,d){if(G(),c.src){var e=b.st.inline,f=a(c.src);if(f.length){var g=f[0].parentNode;g&&g.tagName&&(D||(C=e.hiddenClass,D=x(C),C="mfp-"+C),E=f.after(D).detach().removeClass(C)),b.updateStatus("ready")}else b.updateStatus("error",e.tNotFound),f=a("
");return c.inlineElement=f,f}return b.updateStatus("ready"),b._parseMarkup(d,{},c),d}}});var H,I="ajax",J=function(){H&&a(document.body).removeClass(H)},K=function(){J(),b.req&&b.req.abort()};a.magnificPopup.registerModule(I,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'The content could not be loaded.'},proto:{initAjax:function(){b.types.push(I),H=b.st.ajax.cursor,w(h+"."+I,K),w("BeforeChange."+I,K)},getAjax:function(c){H&&a(document.body).addClass(H),b.updateStatus("loading");var d=a.extend({url:c.src,success:function(d,e,f){var g={data:d,xhr:f};y("ParseAjax",g),b.appendContent(a(g.data),I),c.finished=!0,J(),b._setFocus(),setTimeout(function(){b.wrap.addClass(q)},16),b.updateStatus("ready"),y("AjaxContentAdded")},error:function(){J(),c.finished=c.loadError=!0,b.updateStatus("error",b.st.ajax.tError.replace("%url%",c.src))}},b.st.ajax.settings);return b.req=a.ajax(d),""}}});var L,M=function(c){if(c.data&&void 0!==c.data.title)return c.data.title;var d=b.st.image.titleSrc;if(d){if(a.isFunction(d))return d.call(b,c);if(c.el)return c.el.attr(d)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var c=b.st.image,d=".image";b.types.push("image"),w(m+d,function(){"image"===b.currItem.type&&c.cursor&&a(document.body).addClass(c.cursor)}),w(h+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),v.off("resize"+p)}),w("Resize"+d,b.resizeImage),b.isLowIE&&w("AfterChange",b.resizeImage)},resizeImage:function(){var a=b.currItem;if(a&&a.img&&b.st.image.verticalFit){var c=0;b.isLowIE&&(c=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",b.wH-c)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y("ImageHasSize",a),a.imgHidden&&(b.content&&b.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var c=0,d=a.img[0],e=function(f){L&&clearInterval(L),L=setInterval(function(){return d.naturalWidth>0?void b._onImageHasSize(a):(c>200&&clearInterval(L),c++,void(3===c?e(10):40===c?e(50):100===c&&e(500)))},f)};e(1)},getImage:function(c,d){var e=0,f=function(){c&&(c.img[0].complete?(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("ready")),c.hasSize=!0,c.loaded=!0,y("ImageLoadComplete")):(e++,200>e?setTimeout(f,100):g()))},g=function(){c&&(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("error",h.tError.replace("%url%",c.src))),c.hasSize=!0,c.loaded=!0,c.loadError=!0)},h=b.st.image,i=d.find(".mfp-img");if(i.length){var j=document.createElement("img");j.className="mfp-img",c.el&&c.el.find("img").length&&(j.alt=c.el.find("img").attr("alt")),c.img=a(j).on("load.mfploader",f).on("error.mfploader",g),j.src=c.src,i.is("img")&&(c.img=c.img.clone()),j=c.img[0],j.naturalWidth>0?c.hasSize=!0:j.width||(c.hasSize=!1)}return b._parseMarkup(d,{title:M(c),img_replaceWith:c.img},c),b.resizeImage(),c.hasSize?(L&&clearInterval(L),c.loadError?(d.addClass("mfp-loading"),b.updateStatus("error",h.tError.replace("%url%",c.src))):(d.removeClass("mfp-loading"),b.updateStatus("ready")),d):(b.updateStatus("loading"),c.loading=!0,c.hasSize||(c.imgHidden=!0,d.addClass("mfp-loading"),b.findImageSize(c)),d)}}});var N,O=function(){return void 0===N&&(N=void 0!==document.createElement("p").style.MozTransform),N};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var a,c=b.st.zoom,d=".zoom";if(c.enabled&&b.supportsTransition){var e,f,g=c.duration,j=function(a){var b=a.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all "+c.duration/1e3+"s "+c.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,b.css(e),b},k=function(){b.content.css("visibility","visible")};w("BuildControls"+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.content.css("visibility","hidden"),a=b._getItemToZoom(),!a)return void k();f=j(a),f.css(b._getOffset()),b.wrap.append(f),e=setTimeout(function(){f.css(b._getOffset(!0)),e=setTimeout(function(){k(),setTimeout(function(){f.remove(),a=f=null,y("ZoomAnimationEnded")},16)},g)},16)}}),w(i+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.st.removalDelay=g,!a){if(a=b._getItemToZoom(),!a)return;f=j(a)}f.css(b._getOffset(!0)),b.wrap.append(f),b.content.css("visibility","hidden"),setTimeout(function(){f.css(b._getOffset())},16)}}),w(h+d,function(){b._allowZoom()&&(k(),f&&f.remove(),a=null)})}},_allowZoom:function(){return"image"===b.currItem.type},_getItemToZoom:function(){return b.currItem.hasSize?b.currItem.img:!1},_getOffset:function(c){var d;d=c?b.currItem.img:b.st.zoom.opener(b.currItem.el||b.currItem);var e=d.offset(),f=parseInt(d.css("padding-top"),10),g=parseInt(d.css("padding-bottom"),10);e.top-=a(window).scrollTop()-f;var h={width:d.width(),height:(u?d.innerHeight():d[0].offsetHeight)-g-f};return O()?h["-moz-transform"]=h.transform="translate("+e.left+"px,"+e.top+"px)":(h.left=e.left,h.top=e.top),h}}});var P="iframe",Q="//about:blank",R=function(a){if(b.currTemplate[P]){var c=b.currTemplate[P].find("iframe");c.length&&(a||(c[0].src=Q),b.isIE8&&c.css("display",a?"block":"none"))}};a.magnificPopup.registerModule(P,{options:{markup:'
',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){b.types.push(P),w("BeforeChange",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(h+"."+P,function(){R()})},getIframe:function(c,d){var e=c.src,f=b.st.iframe;a.each(f.patterns,function(){return e.indexOf(this.index)>-1?(this.id&&(e="string"==typeof this.id?e.substr(e.lastIndexOf(this.id)+this.id.length,e.length):this.id.call(this,e)),e=this.src.replace("%id%",e),!1):void 0});var g={};return f.srcAction&&(g[f.srcAction]=e),b._parseMarkup(d,g,c),b.updateStatus("ready"),d}}});var S=function(a){var c=b.items.length;return a>c-1?a-c:0>a?c+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var c=b.st.gallery,e=".mfp-gallery";return b.direction=!0,c&&c.enabled?(f+=" mfp-gallery",w(m+e,function(){c.navigateByImgClick&&b.wrap.on("click"+e,".mfp-img",function(){return b.items.length>1?(b.next(),!1):void 0}),d.on("keydown"+e,function(a){37===a.keyCode?b.prev():39===a.keyCode&&b.next()})}),w("UpdateStatus"+e,function(a,c){c.text&&(c.text=T(c.text,b.currItem.index,b.items.length))}),w(l+e,function(a,d,e,f){var g=b.items.length;e.counter=g>1?T(c.tCounter,f.index,g):""}),w("BuildControls"+e,function(){if(b.items.length>1&&c.arrows&&!b.arrowLeft){var d=c.arrowMarkup,e=b.arrowLeft=a(d.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,"left")).addClass(s),f=b.arrowRight=a(d.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,"right")).addClass(s);e.click(function(){b.prev()}),f.click(function(){b.next()}),b.container.append(e.add(f))}}),w(n+e,function(){b._preloadTimeout&&clearTimeout(b._preloadTimeout),b._preloadTimeout=setTimeout(function(){b.preloadNearbyImages(),b._preloadTimeout=null},16)}),void w(h+e,function(){d.off(e),b.wrap.off("click"+e),b.arrowRight=b.arrowLeft=null})):!1},next:function(){b.direction=!0,b.index=S(b.index+1),b.updateItemHTML()},prev:function(){b.direction=!1,b.index=S(b.index-1),b.updateItemHTML()},goTo:function(a){b.direction=a>=b.index,b.index=a,b.updateItemHTML()},preloadNearbyImages:function(){var a,c=b.st.gallery.preload,d=Math.min(c[0],b.items.length),e=Math.min(c[1],b.items.length);for(a=1;a<=(b.direction?e:d);a++)b._preloadItem(b.index+a);for(a=1;a<=(b.direction?d:e);a++)b._preloadItem(b.index-a)},_preloadItem:function(c){if(c=S(c),!b.items[c].preloaded){var d=b.items[c];d.parsed||(d=b.parseEl(c)),y("LazyLoad",d),"image"===d.type&&(d.img=a('').on("load.mfploader",function(){d.hasSize=!0}).on("error.mfploader",function(){d.hasSize=!0,d.loadError=!0,y("LazyLoadError",d)}).attr("src",d.src)),d.preloaded=!0}}}});var U="retina";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=b.st.retina,c=a.ratio;c=isNaN(c)?c():c,c>1&&(w("ImageHasSize."+U,function(a,b){b.img.css({"max-width":b.img[0].naturalWidth/c,width:"100%"})}),w("ElementParse."+U,function(b,d){d.src=a.replaceSrc(d,c)}))}}}}),A()}); \ No newline at end of file diff --git a/conreq/core/base/static/js/modal.js b/conreq/core/base/static/js/modal.js deleted file mode 100644 index dbfd1ec5..00000000 --- a/conreq/core/base/static/js/modal.js +++ /dev/null @@ -1,52 +0,0 @@ -let modal_loaded = false; - -// Fetches a modal via AJAX -var generate_modal = async function (modal_url) { - let modal_dialog = $("#modal-dialog"); - // Fetch the series modal - modal_loaded = false; - get_url(modal_url, async function (modal_html) { - // Save that the modal was successfully loaded - modal_loaded = true; - - // Place the new HTML on the page - modal_dialog[0].innerHTML = DOMPurify.sanitize(modal_html); - - // Show the new content - $("#modal-container .loading-animation").hide(); - $("#modal-content").show(); - $("#modal-container").modal("show"); - - // Add click events - request_btn_click_event(); - content_modal_click_event(); - modal_select_all_btn_click_event(); - modal_expand_btn_click_event(); - row_title_click_event(); - row_checkbox_click_event(); - row_suboption_title_click_event(); - row_suboption_checkbox_click_event(); - create_report_modal_click_event(); - report_btn_click_event(); - simple_filter_btn_click_event(); - modal_poster_popup_click_event(); - delete_user_btn_click_event(); - save_user_btn_click_event(); - }).fail(async function () { - // Server couldn't fetch the modal - if (http_request.statusText != "abort") { - conreq_no_response_toast_message(); - } - $("#modal-container").modal("hide"); - }); - - // If the modal is taking too long to load, show a loading animation - setTimeout(async function () { - if (!modal_loaded) { - // Show the loading icon - $("#modal-content").hide(); - $("#modal-container").modal("show"); - $("#modal-container .loading-animation").show(); - } - }, 300); -}; diff --git a/conreq/core/base/static/js/more_info.js b/conreq/core/base/static/js/more_info.js deleted file mode 100644 index f2d976a0..00000000 --- a/conreq/core/base/static/js/more_info.js +++ /dev/null @@ -1,125 +0,0 @@ -var create_all_carousels = async function () { - create_review_carousel(); - create_video_carousel(); - viewport_carousel_constructor(); -}; - -var all_carousels = []; -var viewport_carousel_constructor = async function () { - $(".viewport .carousel.auto-construct:not(.constructed)").each( - async function () { - let current_carousel = $(this); - let inner_container = current_carousel.find( - ".carousel-inner-container" - )[0]; - let controls = current_carousel.find(".carousel-controls")[0]; - all_carousels.push( - tns({ - container: inner_container, - controlsContainer: controls, - swipeAngle: 60, - autoWidth: true, - loop: false, - speed: 300, - mouseDrag: true, - gutter: 10, - nav: false, - slideBy: "page", - edgePadding: 20, - }) - ); - current_carousel.addClass("constructed"); - - // Popup modal - let artwork = current_carousel.find(".artwork-container"); - if (artwork.length) { - artwork.magnificPopup({ - delegate: "a", - type: "image", - mainClass: "mfp-no-margins", // class to remove default margin from left and right side - gallery: { - enabled: true, - navigateByImgClick: true, - preload: [1, 1], // Will preload 1 before and 1 after the current image - }, - }); - } - } - ); -}; - -var viewport_carousel_destructor = async function () { - $(all_carousels).each(async function () { - this.destroy(); - }); - all_carousels = []; -}; - -var review_carousel = null; -var create_review_carousel = async function () { - if ($(".reviews-inner-container").length) { - review_carousel = tns({ - container: ".reviews-inner-container", - items: 1, - speed: 300, - swipeAngle: 60, - rewind: true, - mouseDrag: true, - gutter: 10, - controls: false, - navPosition: "bottom", - autoplayPosition: "bottom", - autoplayButtonOutput: false, - responsive: { - 1601: { - items: 3, - }, - 1151: { - items: 2, - }, - }, - }); - } -}; - -var youtube_players = null; -var create_youtube_players = async function () { - youtube_players = []; - $(".youtube-player").each(async function () { - let player = new YT.Player(this, { - height: "", // Set by CSS - width: "", // Set by CSS - videoId: $(this).data("video-key"), - playerVars: { - frameborder: "0", - enablejsapi: "1", - modestbranding: "1", - }, - }); - youtube_players.push(player); - }); -}; - -var videos_carousel = null; -var create_video_carousel = async function () { - // Create youtube video players - create_youtube_players(); - - // Set up the carousel - if ($(".videos-inner-container").length) { - videos_carousel = tns({ - container: ".videos-inner-container", - controlsContainer: ".videos-carousel-controls", - swipeAngle: 60, - autoWidth: true, - loop: false, - items: 3, - speed: 300, - mouseDrag: true, - gutter: 10, - nav: false, - slideBy: "page", - edgePadding: 20, - }); - } -}; diff --git a/conreq/core/base/static/js/sidebar.js b/conreq/core/base/static/js/sidebar.js deleted file mode 100644 index b756ee9b..00000000 --- a/conreq/core/base/static/js/sidebar.js +++ /dev/null @@ -1,5 +0,0 @@ -$(document).ready(async function () { - $(".sidebar").trigger("prepare"); - new SimpleBar($("#sidebar")[0]); - $(".sidebar").trigger("loaded"); -}); diff --git a/conreq/core/base/static/js/sign_up.js b/conreq/core/base/static/js/sign_up.js deleted file mode 100644 index 0000eeb9..00000000 --- a/conreq/core/base/static/js/sign_up.js +++ /dev/null @@ -1,2 +0,0 @@ -document.querySelector("form").action = - document.querySelector("form").action + window.location.search; diff --git a/conreq/core/base/static/js/toast_messages.js b/conreq/core/base/static/js/toast_messages.js deleted file mode 100644 index 691d23f2..00000000 --- a/conreq/core/base/static/js/toast_messages.js +++ /dev/null @@ -1,180 +0,0 @@ -// Requested toast message -var requested_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Requested!", - message: "Server is searching for a download.", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// Reported toast message -var reported_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Reported!", - message: "Server is looking for a solution.", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// No selection toast message -var no_selection_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Rejected!", - message: "Nothing was selected.", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - }); -}; - -// Login failed toast message -var login_failed_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Error!", - message: "Invalid login credentials.", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - }); -}; - -// Server disconnected toast message -var disconnected_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Disconnected!", - message: "Trying to reconnect...", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - }); -}; - -// Server reconnected toast message -var reconnected_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Reconnected!", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// Saving settings failed -var error_toast_message = async function (error_message) { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Error!", - message: error_message, - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - timeout: 15000, - }); -}; - -// Saving settings succeeded -var success_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Success!", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// Saving settings succeeded -var save_success_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Saved!", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// Password confirm failed -var passwords_dont_match_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Error!", - message: "Passwords don't match!", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - }); -}; - -// Failed to perform conreq first time setup -var conreq_submission_failed_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Error!", - message: "One or more issues detected with submission!", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - }); -}; - -// Invite link has been copied to cliboard -var invite_copied_toast_message = async function () { - iziToast.show({ - icon: "fas fa-check-circle", - title: "Valid for 7 days.", - message: "Invite link has been copied to clipboard! ", - displayMode: "replace", - titleColor: "var(--accent-color)", - messageColor: "var(--accent-color)", - iconColor: "var(--accent-color)", - progressBarColor: "var(--accent-color)", - }); -}; - -// Failed to fetch something -var conreq_no_response_toast_message = async function () { - iziToast.show({ - icon: "fas fa-exclamation-triangle", - title: "Error!", - message: "The server did not respond!", - displayMode: "replace", - titleColor: "#9a5c0f", - messageColor: "#9a5c0f", - iconColor: "#c57615", - progressBarColor: "var(--accent-color)", - timeout: 15000, - }); -}; diff --git a/conreq/core/base/static/js/viewport.js b/conreq/core/base/static/js/viewport.js deleted file mode 100644 index a5a90ea2..00000000 --- a/conreq/core/base/static/js/viewport.js +++ /dev/null @@ -1,265 +0,0 @@ -var viewport_container_top_class = ".viewport-container-top"; -var viewport_container_class = ".viewport-container"; -let viewport_class = ".viewport"; -let page_reload_needed = false; -let viewport_http_request = $.ajax({}); -let viewport_http_request_aborted = false; - -// Create the lazyloader -var lazyloader = new LazyLoad({ - threshold: 0, - callback_error: async function (element) { - element.src = "/static/images/transparent.png"; - }, -}); - -// Updates the current tab based on the URL -let update_active_tab = async function () { - $(".nav-tab").each(async function () { - nav_tab = $(this); - // Set the active tab - if ( - nav_tab.children("a").attr("href") == - "#" + get_window_location_no_params() - ) { - if (!nav_tab.hasClass("active")) { - nav_tab.addClass("active"); - } - } - // Remove any old active tabs - else if (nav_tab.hasClass("active")) { - nav_tab.removeClass("active"); - } - }); -}; - -// Updates the page name -let update_page_title = async function (viewport_selector) { - let page_name = DOMPurify.sanitize( - $(viewport_selector + ">.page-name").val() - ); - let app_name = $("#app-name").val(); - if (page_name) { - document.title = page_name + " | " + app_name; - $(".navbar-brand").text(page_name); - } else { - document.title = app_name; - $(".navbar-brand").text(app_name); - } -}; - -// Helper to show the active viewport -let select_active_viewport = async function (viewport_selector) { - if (viewport_selector == viewport_container_class) { - $(viewport_container_top_class).attr("hidden", ""); - $(viewport_container_class).removeAttr("hidden"); - } else { - $(viewport_container_class).attr("hidden", ""); - $(viewport_container_top_class).removeAttr("hidden"); - } -}; - -// Determine if a cached viewport exists -let cached_viewport_exists = function () { - return Boolean($("main[data-url='" + get_window_location() + "']").length); -}; - -// Show the cached viewport -let display_cached_viewport = async function () { - let new_viewport = "main[data-url='" + get_window_location() + "']"; - let old_viewport = $( - "main:not([data-url='" + get_window_location() + "'])" - ); - $(new_viewport).trigger("prepare-cached"); - update_active_tab(); - update_page_title(new_viewport); - old_viewport.attr("hidden", ""); - $(new_viewport).removeAttr("hidden"); - $(new_viewport).trigger("loaded-cached"); -}; - -// Destroys old viewport JS instances -let destroy_viewport = async function (viewport_selector) { - $(viewport_selector).trigger("destroy"); - $(viewport_selector + ">*:not(.loading-animation-container)").remove(); -}; - -// Preforms any actions needed to prepare the viewport -let prepare_viewport = async function (viewport_selector) { - $(viewport_selector).trigger("prepare"); - $(viewport_selector).attr("data-url", get_window_location()); - - // Lazy load page elements - lazyloader.update(); -}; - -// Gets the viewport from a URL -let get_viewport = async function ( - location, - viewport_selector, - success = function () {} -) { - $(viewport_selector).trigger("url-changed"); - - // Abandon an old http request if the user clicks something else - if ( - viewport_http_request.statusText != "OK" || - viewport_http_request.statusText == null - ) { - viewport_http_request_aborted = true; - viewport_http_request.abort(); - } - - // Load the viewport html - viewport_http_request = $.get(location, function (response = null) { - return success(response); - }).fail(async function () { - if (!viewport_http_request_aborted) { - console.error("Failed to fetch viewport!"); - conreq_no_response_toast_message(); - await destroy_viewport(viewport_selector); - $(viewport_selector + ">*").remove(); - $(viewport_selector).append( - "

Could not connect to the server!

" - ); - $(viewport_selector + ">h1").css("text-align", "center"); - select_active_viewport(viewport_selector); - } - viewport_http_request_aborted = false; - }); - return http_request; -}; - -// Fetch the new viewport and update the current tab -var generate_viewport = async function (standard_viewport_load = true) { - hide_modals_and_popups(); - - if (cached_viewport_exists() && standard_viewport_load == true) { - display_cached_viewport(); - } else { - let viewport_selector = null; - if (get_window_location(true).startsWith("/display/")) { - // Display on the top layer - viewport_selector = viewport_container_top_class; - } else { - // Display on the primary viewport - viewport_selector = viewport_container_class; - } - // Check if the whole webpage needs to be reloaded - if (page_reload_needed && standard_viewport_load) { - location.reload(); - } - - // Read the URL hash to determine what page we are on - let window_location = get_window_location(); - - // If there is no window location, default to the first tab - if (!window_location) { - if (window.history.replaceState) { - // Replace the current page in the browser history to add a hash - window.history.replaceState( - {}, - null, - $(".nav-tab a").attr("href") - ); - window_location = window.location.hash.split("#")[1]; - } - } - - // Change the current tab - update_active_tab(); - - // Asynchronously fetch new viewport content - viewport_loaded = false; - get_viewport( - add_base_url(window_location), - viewport_selector, - async function (viewport_html) { - // Save that the page was successfully loaded - viewport_loaded = true; - - // Destroy old JS elements and event handlers - await destroy_viewport(viewport_selector); - - // Inject and configure the new content - $(viewport_selector)[0].innerHTML = - DOMPurify.sanitize(viewport_html); - select_active_viewport(viewport_selector); - await prepare_viewport(viewport_selector); - update_page_title(viewport_selector); - $(viewport_selector).trigger("loaded"); - - // Display the new content - $(viewport_selector + ">.loading-animation-container").hide(); - $( - viewport_selector + ">*:not(.loading-animation-container)" - ).show(); - - // Set scroll position - if (standard_viewport_load) { - $(viewport_selector).scrollTop(0); - } - } - ); - - // If the page is taking too long to load, show a loading animation - setTimeout(async function () { - if (!viewport_loaded && standard_viewport_load) { - // Hide the viewport and display the loading animation - select_active_viewport(viewport_selector); - $(viewport_selector + ">.loading-animation-container").show(); - $( - viewport_selector + ">*:not(.loading-animation-container)" - ).hide(); - } - }, 500); - } -}; - -// Perform actions whenever the HTML on the page changes -let page_mutation_observer = async function () { - let observer = new MutationObserver(async function () { - $("html").trigger("modified"); - // Initiate Lazyload on any new images - lazyloader.update(); - }); - - // Configuration of the observer - let config = { - attributes: false, - characterData: false, - subtree: true, - childList: true, - }; - - // Select the target node - let target = document.querySelector("body"); - - // Begin observing the modal - observer.observe(target, config); -}; - -$(document).ready(async function () { - base_url = $("#base-url").val(); - // Slide in animations for navbar, sidebar, and viewport - AOS.init(); - // Obtain the initial page - page_mutation_observer(); - generate_viewport(); -}); - -// Fetch a new page when the URL changes -if ("onhashchange" in window) { - // Window anchor change event supported - window.onhashchange = async function () { - generate_viewport(); - }; -} else { - // Window anchor change event not supported - let stored_hash = window.location.hash; - window.setInterval(async function () { - if (window.location.hash != stored_hash) { - generate_viewport(); - } - }, 100); -} diff --git a/conreq/core/base/tasks.py b/conreq/core/base/tasks.py deleted file mode 100644 index ee7803de..00000000 --- a/conreq/core/base/tasks.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sqlite3 - -from django.conf import settings -from django.db import connection -from huey import crontab -from huey.contrib.djhuey import db_periodic_task - -from conreq.utils.environment import get_database_type - -DB_ENGINE = get_database_type() -HUEY_FILENAME = getattr(settings, "HUEY_FILENAME") - - -@db_periodic_task(crontab(minute="0", hour="0", strict=True)) -def vacuum_huey_sqlite_db(): - """Periodically preforms a SQLITE vacuum on the background task database.""" - with sqlite3.connect(HUEY_FILENAME) as cursor: - cursor.execute( - # Only keep the 1000 latest tasks - """DELETE FROM task - WHERE id NOT IN ( - SELECT id - FROM ( - SELECT id - FROM task - ORDER BY id DESC - LIMIT 1000 - ) foo - ); - """ - ) - with sqlite3.connect(HUEY_FILENAME) as cursor: - cursor.execute("VACUUM") - - -if DB_ENGINE == "SQLITE3": - - @db_periodic_task(crontab(minute="0", hour="0", strict=True)) - def vacuum_conreq_sqlite_db(): - """Periodically performs any cleanup tasks needed for the default database.""" - with connection.cursor() as cursor: - cursor.execute("VACUUM") diff --git a/conreq/core/base/templates/primary/base_app.html b/conreq/core/base/templates/primary/base_app.html deleted file mode 100644 index 919d56f2..00000000 --- a/conreq/core/base/templates/primary/base_app.html +++ /dev/null @@ -1,27 +0,0 @@ -{% load solo_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% load static compress %} -{% load static %} -{% load conreq_tags %} - - - - - {% include "primary/head_content.html" %} - - - - - - {% include "primary/navbar.html" %} - {% include "primary/sidebar.html" %} - {% include "modal/default.html" %} -
- {% include "primary/loading_animation_container.html" %} -
-
- {% include "primary/loading_animation_container.html" %} -
- - - \ No newline at end of file diff --git a/conreq/core/base/templates/primary/head_content.html b/conreq/core/base/templates/primary/head_content.html deleted file mode 100644 index 3e77130f..00000000 --- a/conreq/core/base/templates/primary/head_content.html +++ /dev/null @@ -1,153 +0,0 @@ -{% load static compress %} -{% load static %} -{% load pwa %} -{% load conreq_tags %} - - -{% app_name %} - - - - -{% include "primary/icons.html" %} -{% progressive_web_app_meta %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{% compress js %} - - - - - - - - -{% endcompress %} - -{% compress css %} - - - - - - - - - - - - - - - - - - -{% endcompress %} - - -{% compress js %} - - - - - - - - - -{% endcompress %} - - -{% if server_settings.conreq_simple_posters %} -{% include "compressed/simple_posters_css.html" %} -{% endif %} - - -{% if server_settings.conreq_custom_js %} - -{% endif %} - - -{% if server_settings.conreq_custom_css %} - {% endif %} \ No newline at end of file diff --git a/conreq/core/base/templates/primary/head_content_slim.html b/conreq/core/base/templates/primary/head_content_slim.html deleted file mode 100644 index b54feed0..00000000 --- a/conreq/core/base/templates/primary/head_content_slim.html +++ /dev/null @@ -1,48 +0,0 @@ -{% load static compress %} -{% load solo_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% load static %} -{% load conreq_tags %} - - -{% app_name %} - - - - -{% include "primary/icons.html" %} - - - - - - - - - - - - - - -{% compress css %} - - - - - - -{% endcompress %} - -{% compress js %} - - - - - -{% endcompress %} \ No newline at end of file diff --git a/conreq/core/base/templates/primary/icons.html b/conreq/core/base/templates/primary/icons.html deleted file mode 100644 index 949105c1..00000000 --- a/conreq/core/base/templates/primary/icons.html +++ /dev/null @@ -1,5 +0,0 @@ -{% load static %} - - - - \ No newline at end of file diff --git a/conreq/core/base/templates/primary/loading_animation.html b/conreq/core/base/templates/primary/loading_animation.html deleted file mode 100644 index 647a5e02..00000000 --- a/conreq/core/base/templates/primary/loading_animation.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Loading... -
\ No newline at end of file diff --git a/conreq/core/base/templates/primary/loading_animation_container.html b/conreq/core/base/templates/primary/loading_animation_container.html deleted file mode 100644 index 43a19ad9..00000000 --- a/conreq/core/base/templates/primary/loading_animation_container.html +++ /dev/null @@ -1,3 +0,0 @@ -
- {% include "primary/loading_animation.html" %} -
\ No newline at end of file diff --git a/conreq/core/base/templates/primary/navbar.html b/conreq/core/base/templates/primary/navbar.html deleted file mode 100644 index 06a31433..00000000 --- a/conreq/core/base/templates/primary/navbar.html +++ /dev/null @@ -1,11 +0,0 @@ -{% load static %} -{% load conreq_tags %} - \ No newline at end of file diff --git a/conreq/core/base/templates/primary/searchbar.html b/conreq/core/base/templates/primary/searchbar.html deleted file mode 100644 index 6a794ca6..00000000 --- a/conreq/core/base/templates/primary/searchbar.html +++ /dev/null @@ -1,9 +0,0 @@ -{% load conreq_tags %} - - \ No newline at end of file diff --git a/conreq/core/base/templates/primary/sidebar.html b/conreq/core/base/templates/primary/sidebar.html deleted file mode 100644 index b540f91b..00000000 --- a/conreq/core/base/templates/primary/sidebar.html +++ /dev/null @@ -1,183 +0,0 @@ -{% load static %} -{% load conreq_tags %} - \ No newline at end of file diff --git a/conreq/core/base/templatetags/conreq_tags.py b/conreq/core/base/templatetags/conreq_tags.py deleted file mode 100644 index f6e5eca0..00000000 --- a/conreq/core/base/templatetags/conreq_tags.py +++ /dev/null @@ -1,48 +0,0 @@ -from django import template -from django.urls import reverse - -from conreq.utils.environment import get_base_url, get_str_from_env - -register = template.Library() -base_url_len = len(get_base_url()) -conreq_app_name = get_str_from_env("APP_NAME", "Conreq") -conreq_app_description = get_str_from_env("APP_DESCRIPTION", "Content Requesting") - - -@register.simple_tag -def viewport_url(namespace): - url = reverse(namespace) - return "#" + url[base_url_len:] - - -@register.simple_tag -def viewport_top_url(namespace): - url = reverse(namespace) - return "#" + "/display" + url[base_url_len:] - - -@register.simple_tag -def app_name(): - return conreq_app_name - - -@register.simple_tag -def app_description(): - return conreq_app_description - - -@register.filter -def contains_valid_id(results): - if isinstance(results, list): - for result in results: - if isinstance(result, dict) and result.get("conreq_valid_id"): - return True - return False - - -@register.filter -def email_enabled(_): - """Temporary hacky shortcut to determine if email is enabled.""" - from django.conf import settings - - return settings.EMAIL_ENABLED diff --git a/conreq/core/base/urls.py b/conreq/core/base/urls.py deleted file mode 100644 index 50cff009..00000000 --- a/conreq/core/base/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "base" - -urlpatterns = [ - path("", views.landing, name="landing"), - path("home/", views.home, name="homescreen"), -] diff --git a/conreq/core/base/validators.py b/conreq/core/base/validators.py deleted file mode 100644 index b5270bff..00000000 --- a/conreq/core/base/validators.py +++ /dev/null @@ -1,38 +0,0 @@ -import re - -from django.core.validators import URLValidator -from django.utils.deconstruct import deconstructible -from django.utils.regex_helper import _lazy_re_compile - - -@deconstructible -class ExtendedURLValidator(URLValidator): - """URL validator that supports hostnames (ex. https://sonarr:8000)""" - - # pylint: disable=too-few-public-methods - ul = URLValidator.ul - ipv4_re = URLValidator.ipv4_re - ipv6_re = URLValidator.ipv6_re - hostname_re = URLValidator.hostname_re - domain_re = URLValidator.domain_re - - tld_re = ( - r"\.?" # OPTIONAL dot (allows for hostnames) - r"(?!-)" # can't start with a dash - r"(?:[a-z" + ul + "-]{2,63}" # domain label - r"|xn--[a-z0-9]{1,59})" # or punycode label - r"(?", "", html) - - -def __unmark_element(element, stream=None): - """Processing function to removes markdown from an element.""" - if stream is None: - stream = StringIO() - if element.text: - stream.write(element.text) - for sub in element: - __unmark_element(sub, stream) - if element.tail: - stream.write(element.tail) - return stream.getvalue() - - -# Patching the markdown module to remove markdown -Markdown.output_formats["plain"] = __unmark_element -__md = Markdown(output_format="plain") -__md.stripTopLevelTags = False - - -def preprocess_tmdb_result(tmdb_result): - """Pre-processing to allow for viewing within the More Info screen.""" - # Prepare data attributes for the HTML - # Summary - if ( - tmdb_result.__contains__("overview") - and isinstance(tmdb_result["overview"], str) - and not tmdb_result["overview"] - ): - tmdb_result["overview"] = None - # Budget - if tmdb_result.__contains__("budget") and isinstance(tmdb_result["budget"], int): - if not tmdb_result["budget"]: - tmdb_result["budget"] = None - else: - tmdb_result["budget"] = "{:,}".format(tmdb_result["budget"]) - # Revenue - if tmdb_result.__contains__("revenue") and isinstance(tmdb_result["revenue"], int): - if not tmdb_result["revenue"]: - tmdb_result["revenue"] = None - else: - tmdb_result["revenue"] = "{:,}".format(tmdb_result["revenue"]) - # Runtime - if tmdb_result.__contains__("runtime") and isinstance(tmdb_result["runtime"], int): - tmdb_result["runtime"] = "{:d}h {:d}m".format( - *divmod(tmdb_result["runtime"], 60) - ) - # Reviews - if ( - tmdb_result.__contains__("reviews") - and tmdb_result["reviews"].__contains__("results") - and isinstance(tmdb_result["reviews"]["results"], list) - ): - if not tmdb_result["reviews"]["results"]: - tmdb_result["reviews"]["results"] = None - else: - for review in tmdb_result["reviews"]["results"]: - review["content"] = __strip_urls( - __strip_html(__md.convert(review["content"])) - ) - # Keywords (Tags) - if ( - tmdb_result.__contains__("keywords") - and tmdb_result["keywords"].__contains__("results") - and isinstance(tmdb_result["keywords"]["results"], list) - and not tmdb_result["keywords"]["results"] - ): - tmdb_result["keywords"]["results"] = None - # Cast Members - if ( - tmdb_result.__contains__("credits") - and tmdb_result["credits"].__contains__("cast") - and isinstance(tmdb_result["credits"]["cast"], list) - and not tmdb_result["credits"]["cast"] - ): - tmdb_result["credits"]["cast"] = None - # Videos - if ( - tmdb_result.__contains__("videos") - and tmdb_result["videos"].__contains__("results") - and isinstance(tmdb_result["videos"]["results"], list) - ): - if not tmdb_result["videos"]["results"]: - tmdb_result["videos"]["results"] = None - else: - contains_youtube = False - for video in tmdb_result["videos"]["results"]: - if video["site"] == "YouTube": - contains_youtube = True - break - if not contains_youtube: - tmdb_result["videos"]["results"] = None - # Artwork (Images) - if ( - tmdb_result.__contains__("images") - and tmdb_result["images"].__contains__("backdrops") - and isinstance(tmdb_result["images"]["backdrops"], list) - and not tmdb_result["images"]["backdrops"] - ): - tmdb_result["images"]["backdrops"] = None - # Last Air Date - if ( - tmdb_result.__contains__("last_air_date") - and isinstance(tmdb_result["last_air_date"], str) - and tmdb_result["last_air_date"] - ): - year, month, day = tmdb_result["last_air_date"].split(sep="-") - month = month_name[int(month)] - tmdb_result["last_air_date_formatted"] = f"{month} {day}, {year}" - # First Air Date - if ( - tmdb_result.__contains__("first_air_date") - and isinstance(tmdb_result["first_air_date"], str) - and tmdb_result["first_air_date"] - ): - year, month, day = tmdb_result["first_air_date"].split(sep="-") - month = month_name[int(month)] - tmdb_result["first_air_date_formatted"] = f"{month} {day}, {year}" - # Next Air Date - if tmdb_result.get("next_episode_to_air") and tmdb_result[ - "next_episode_to_air" - ].get("air_date"): - year, month, day = tmdb_result["next_episode_to_air"]["air_date"].split(sep="-") - month = month_name[int(month)] - tmdb_result["next_air_date_formatted"] = f"{month} {day}, {year}" - # Release Date - if ( - tmdb_result.__contains__("release_date") - and isinstance(tmdb_result["release_date"], str) - and tmdb_result["release_date"] - ): - year, month, day = tmdb_result["release_date"].split(sep="-") - month = month_name[int(month)] - tmdb_result["release_date_formatted"] = f"{month} {day}, {year}" - # Backdrop - if ( - tmdb_result.__contains__("backdrop_path") - and isinstance(tmdb_result["backdrop_path"], str) - and tmdb_result["backdrop_path"] - and tmdb_result["backdrop_path"].find(TMDB_BACKDROP_URL) == -1 - ): - tmdb_result["backdrop_path"] = TMDB_BACKDROP_URL + tmdb_result["backdrop_path"] - # Poster - if ( - tmdb_result.__contains__("poster_path") - and isinstance(tmdb_result["poster_path"], str) - and tmdb_result["poster_path"] - and tmdb_result["poster_path"].find(TMDB_POSTER_URL) == -1 - ): - tmdb_result["poster_path"] = TMDB_POSTER_URL + tmdb_result["poster_path"] - - -def preprocess_tmdb_person(tmdb_result): - """Pre-processing to allow for viewing within the More Info screen.""" - # Prepare data attributes for the HTML - # Birthday - if ( - tmdb_result.__contains__("birthday") - and isinstance(tmdb_result["birthday"], str) - and tmdb_result["birthday"] - ): - year, month, day = tmdb_result["birthday"].split(sep="-") - month = month_name[int(month)] - tmdb_result["birthday_formatted"] = f"{month} {day}, {year}" - # Deathday - if ( - tmdb_result.__contains__("deathday") - and isinstance(tmdb_result["deathday"], str) - and tmdb_result["deathday"] - ): - year, month, day = tmdb_result["deathday"].split(sep="-") - month = month_name[int(month)] - tmdb_result["deathday_formatted"] = f"{month} {day}, {year}" - # Poster - if ( - tmdb_result.__contains__("profile_path") - and isinstance(tmdb_result["profile_path"], str) - and tmdb_result["profile_path"] - and tmdb_result["profile_path"].find(TMDB_POSTER_URL) == -1 - ): - tmdb_result["profile_path"] = TMDB_POSTER_URL + tmdb_result["profile_path"] diff --git a/conreq/core/more_info/urls.py b/conreq/core/more_info/urls.py deleted file mode 100644 index 54e04a83..00000000 --- a/conreq/core/more_info/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "more_info" -urlpatterns = [ - path("", views.more_info, name="main"), - path("person/", views.person, name="person"), - path("recommended/", views.recommended, name="recommended"), - path("collection/", views.collection, name="collection"), - path("series_modal/", views.series_modal, name="series_modal"), - path( - "content_preview_modal/", - views.content_preview_modal, - name="content_preview_modal", - ), -] diff --git a/conreq/core/more_info/views.py b/conreq/core/more_info/views.py deleted file mode 100644 index 773d7234..00000000 --- a/conreq/core/more_info/views.py +++ /dev/null @@ -1,253 +0,0 @@ -from django.contrib.auth.decorators import login_required -from django.http import HttpResponse, HttpResponseNotFound -from django.template import loader -from django.views.decorators.cache import cache_page - -from conreq.core.arrs.helpers import wait_for_series_info -from conreq.core.arrs.sonarr import SonarrManager -from conreq.core.discover.helpers import ( - obtain_sonarr_parameters, - set_many_availability, - set_single_availability, -) -from conreq.core.tmdb.discovery import TmdbDiscovery -from conreq.core.user_requests.models import UserRequest -from conreq.utils import log -from conreq.utils.debug import performance_metrics -from conreq.utils.generic import is_key_value_in_list, str_to_bool - -from .helpers import preprocess_tmdb_person, preprocess_tmdb_result - -_logger = log.get_logger(__name__) - -# Globals -MAX_SERIES_FETCH_RETRIES = 10 - - -@cache_page(15) -@login_required -@performance_metrics() -def more_info(request): - content_discovery = TmdbDiscovery() - template = loader.get_template("viewport/more_info.html") - - # Get the ID from the URL - tmdb_id = request.GET.get("tmdb_id", None) - content_type = request.GET.get("content_type", None) - - # Get all the basic metadata for a given ID - content = content_discovery.get_by_tmdb_id(tmdb_id, content_type) - - # Determine the availability of the current TMDB ID - set_single_availability(content) - - # Pre-process data attributes within tmdb_result - preprocess_tmdb_result(content) - - # Get collection information - if ( - content.__contains__("belongs_to_collection") - and content["belongs_to_collection"] is not None - ): - tmdb_collection_id = content["belongs_to_collection"]["id"] - else: - tmdb_collection_id = None - - # Check if the user has already requested this - requested = False - if UserRequest.objects.filter( - content_id=content["id"], - content_type=content["content_type"], - ): - requested = True - - # Generate context for page rendering - context = { - "content": content, - "collection_id": tmdb_collection_id, - "content_type": content["content_type"], - "requested": requested, - } - - # Render the page - return HttpResponse(template.render(context, request)) - - -@cache_page(7 * 24 * 60 * 60) -@login_required -@performance_metrics() -def person(request): - content_discovery = TmdbDiscovery() - template = loader.get_template("viewport/person.html") - context = {} - - # Get the ID from the URL - person_id = request.GET.get("id", None) - - # Fetch the person from TMDB - if person_id: - results = content_discovery.person(person_id) - - # Preprocessing before passing into HTML - preprocess_tmdb_person(results) - if results["tv_credits"]["cast"]: - content_discovery.determine_id_validity(results["tv_credits"]["cast"]) - set_many_availability(results["tv_credits"]["cast"]) - if results["tv_credits"]["crew"]: - content_discovery.determine_id_validity(results["tv_credits"]["crew"]) - set_many_availability(results["tv_credits"]["crew"]) - if results["movie_credits"]["cast"]: - content_discovery.determine_id_validity(results["movie_credits"]["cast"]) - set_many_availability(results["movie_credits"]["cast"]) - if results["movie_credits"]["crew"]: - content_discovery.determine_id_validity(results["movie_credits"]["crew"]) - set_many_availability(results["movie_credits"]["crew"]) - tv_cast_contain_valid_id = is_key_value_in_list( - "conreq_valid_id", True, results["tv_credits"]["cast"] - ) - tv_crew_contain_valid_id = is_key_value_in_list( - "conreq_valid_id", True, results["tv_credits"]["crew"] - ) - if results.get("popularity"): - results["popularity"] = int(results["popularity"] * 10) - - # Generate context for page rendering - context = { - "person": results, - "tv_cast_contain_valid_id": tv_cast_contain_valid_id, - "tv_crew_contain_valid_id": tv_crew_contain_valid_id, - } - - # Render the page - return HttpResponse(template.render(context, request)) - - -@cache_page(15) -@login_required -@performance_metrics() -def series_modal(request): - content_discovery = TmdbDiscovery() - sonarr_manager = SonarrManager() - report_modal = str_to_bool(request.GET.get("report_modal", "false")) - - # Get the ID from the URL - tmdb_id = request.GET.get("tmdb_id", None) - tvdb_id = content_discovery.get_external_ids(tmdb_id, "tv").get("tvdb_id") - - # Check if the show is already within Sonarr's collection - requested_show = sonarr_manager.get(tvdb_id=tvdb_id) - - # If it doesn't already exists, add then add it - if requested_show is None: - - sonarr_params = obtain_sonarr_parameters(tmdb_id, tvdb_id) - - requested_show = sonarr_manager.add( - tvdb_id=tvdb_id, - quality_profile_id=sonarr_params["sonarr_profile_id"], - root_dir=sonarr_params["sonarr_root"], - series_type=sonarr_params["series_type"], - season_folders=sonarr_params["season_folders"], - ) - - # Keep refreshing until we get the series from Sonarr - series = wait_for_series_info(tvdb_id) - - # Series successfully obtained from Sonarr - if series: - context = { - "seasons": series["seasons"], - "tmdb_id": tmdb_id, - "report_modal": report_modal, - } - template = loader.get_template("modal/series_selection.html") - return HttpResponse(template.render(context, request)) - - # Sonarr couldn't process this request - return HttpResponseNotFound() - - -@cache_page(15) -@login_required -@performance_metrics() -def content_preview_modal(request): - content_discovery = TmdbDiscovery() - - # Get the ID from the URL - tmdb_id = request.GET.get("tmdb_id", None) - content_type = request.GET.get("content_type", None) - - if tmdb_id and content_type: - # Fetch and process - content = content_discovery.get_by_tmdb_id( - tmdb_id, content_type, obtain_extras=False - ) - set_single_availability(content) - preprocess_tmdb_result(content) - - # Check if the user has already requested this - requested = False - if UserRequest.objects.filter( - content_id=content["id"], - content_type=content["content_type"], - ): - requested = True - - context = {"content": content, "requested": requested} - template = loader.get_template("modal/content_preview.html") - return HttpResponse(template.render(context, request)) - - -@cache_page(15) -@login_required -@performance_metrics() -def recommended(request): - tmdb_id = request.GET.get("tmdb_id", None) - content_type = request.GET.get("content_type", None) - if tmdb_id and content_type: - content_discovery = TmdbDiscovery() - - tmdb_recommended = content_discovery.similar_and_recommended( - tmdb_id, content_type - ) - - if not isinstance(tmdb_recommended, dict) or not tmdb_recommended: - tmdb_recommended = None - - else: - set_many_availability(tmdb_recommended["results"]) - - # Detect situation where all results don't have TVDB IDs - results_contain_valid_id = False - if is_key_value_in_list("conreq_valid_id", True, tmdb_recommended["results"]): - results_contain_valid_id = True - - context = { - "recommended": tmdb_recommended, - "results_contain_valid_id": results_contain_valid_id, - } - - template = loader.get_template("viewport/components/more_info_recommended.html") - return HttpResponse(template.render(context, request)) - - -@cache_page(15) -@login_required -@performance_metrics() -def collection(request): - collection_id = request.GET.get("collection_id", None) - - if collection_id: - content_discovery = TmdbDiscovery() - - tmdb_collection = content_discovery.collections(collection_id) - - if not isinstance(tmdb_collection, dict) or not tmdb_collection: - tmdb_collection = None - - else: - set_many_availability(tmdb_collection["parts"]) - - context = {"collection": tmdb_collection} - template = loader.get_template("viewport/components/more_info_collection.html") - return HttpResponse(template.render(context, request)) diff --git a/conreq/core/password_reset/apps.py b/conreq/core/password_reset/apps.py deleted file mode 100644 index 712d5df6..00000000 --- a/conreq/core/password_reset/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class PasswordResetConfig(AppConfig): - name = "conreq.core.password_reset" - verbose_name = "Password Reset" diff --git a/conreq/core/password_reset/forms.py b/conreq/core/password_reset/forms.py deleted file mode 100644 index 0b139c78..00000000 --- a/conreq/core/password_reset/forms.py +++ /dev/null @@ -1,61 +0,0 @@ -from django import forms -from django.contrib.auth import get_user_model, password_validation -from django.contrib.auth.forms import PasswordResetForm as _PasswordResetForm -from django.contrib.auth.forms import SetPasswordForm as _SetPasswordForm -from django.contrib.auth.forms import _unicode_ci_compare -from django.db.models import Q -from django.forms import CharField, TextInput -from django.utils.translation import gettext_lazy as _ - - -class PasswordResetForm(_PasswordResetForm): - email = CharField( - label=_("Email"), - max_length=254, - widget=TextInput( - attrs={"autocomplete": "email", "placeholder": "Username or Email"} - ), - ) - - def get_users(self, username_or_email): - """Given an email, return matching user(s) who should receive a reset. - - This allows subclasses to more easily customize the default policies - that prevent inactive users and users with unusable passwords from - resetting their password. - """ - # pylint: disable=arguments-renamed, protected-access - active_users = get_user_model().objects.filter( - Q(email__iexact=username_or_email) | Q(username__iexact=username_or_email), - is_active=True, - ) - return ( - u - for u in active_users - if u.has_usable_password() - and ( - _unicode_ci_compare(username_or_email, getattr(u, "email")) - or _unicode_ci_compare(username_or_email, getattr(u, "username")), - ) - ) - - -class SetPasswordForm(_SetPasswordForm): - new_password1 = forms.CharField( - label=_("New password"), - widget=forms.PasswordInput( - attrs={"autocomplete": "new-password", "placeholder": "New Password"} - ), - strip=False, - help_text=password_validation.password_validators_help_text_html(), - ) - new_password2 = forms.CharField( - label=_("New password confirmation"), - strip=False, - widget=forms.PasswordInput( - attrs={ - "autocomplete": "new-password", - "placeholder": "Confirm New Password", - } - ), - ) diff --git a/conreq/core/password_reset/templates/conreq/password_reset.html b/conreq/core/password_reset/templates/conreq/password_reset.html deleted file mode 100644 index 706dfa45..00000000 --- a/conreq/core/password_reset/templates/conreq/password_reset.html +++ /dev/null @@ -1,36 +0,0 @@ -{% load static %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- -

RESET MY PASSWORD

-

Enter your username or email.

- -
- {% csrf_token %} - {{ form.email }} - -
- -
-
- - - - \ No newline at end of file diff --git a/conreq/core/password_reset/templates/conreq/password_reset_confirm.html b/conreq/core/password_reset/templates/conreq/password_reset_confirm.html deleted file mode 100644 index 14af9769..00000000 --- a/conreq/core/password_reset/templates/conreq/password_reset_confirm.html +++ /dev/null @@ -1,47 +0,0 @@ -{% load static %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- - {% if validlink %} -

PASSWORD RESET

-

Please enter your new password.

-
- {% csrf_token %} - {{ form.new_password1.errors }} - {{ form.new_password1 }} - {{ form.new_password2.errors }} - {{ form.new_password2 }} - -
- {% else %} -

INVALID PASSWORD RESET

-

Key used or expired.

-

- The password reset link was invalid, possibly because it has already been used. Please request a new - password reset. -

- {% endif %} - -
-
- - - - \ No newline at end of file diff --git a/conreq/core/password_reset/templates/conreq/password_reset_sent.html b/conreq/core/password_reset/templates/conreq/password_reset_sent.html deleted file mode 100644 index 854659fa..00000000 --- a/conreq/core/password_reset/templates/conreq/password_reset_sent.html +++ /dev/null @@ -1,41 +0,0 @@ -{% load static %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- -
-

PASSWORD RESET SENT

-

Reset email has been sent.

-

- We’ve emailed you instructions for setting your password, if an account exists with the details you - entered. You - should receive them shortly. -

-

- If you don’t receive an email, please make sure you’ve entered the correct information. - Additionally, make sure to check your spam folder. -

-
- -
-
- - - - \ No newline at end of file diff --git a/conreq/core/password_reset/urls.py b/conreq/core/password_reset/urls.py deleted file mode 100644 index e5eb40e1..00000000 --- a/conreq/core/password_reset/urls.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.urls import path - -from .views import PasswordResetView, PasswordResetConfirmView, PassWordResetDoneView - -urlpatterns = [ - path("", PasswordResetView.as_view(), name="password_reset"), - path("sent", PassWordResetDoneView.as_view(), name="password_reset_sent"), - path( - "/", - PasswordResetConfirmView.as_view(), - name="password_reset_confirm", - ), -] diff --git a/conreq/core/password_reset/views.py b/conreq/core/password_reset/views.py deleted file mode 100644 index 299cc2e1..00000000 --- a/conreq/core/password_reset/views.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.contrib.auth import views as auth_views -from django.urls import reverse_lazy - -from conreq.core.password_reset.forms import PasswordResetForm, SetPasswordForm - - -class PasswordResetView(auth_views.PasswordResetView): - success_url = reverse_lazy("password_reset_sent") - template_name = "conreq/password_reset.html" - form_class = PasswordResetForm - - -class PassWordResetDoneView(auth_views.PasswordResetDoneView): - template_name = "conreq/password_reset_sent.html" - - -class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): - template_name = "conreq/password_reset_confirm.html" - success_url = reverse_lazy("base:homescreen") - post_reset_login = True - form_class = SetPasswordForm diff --git a/conreq/core/pwa/app_settings.py b/conreq/core/pwa/app_settings.py deleted file mode 100644 index 814ee1f6..00000000 --- a/conreq/core/pwa/app_settings.py +++ /dev/null @@ -1,49 +0,0 @@ -""" Settings required by django-app. """ -import os - -from django.conf import settings -from django.shortcuts import resolve_url -from django.urls import get_script_prefix -from django.utils.functional import lazy - -from conreq.utils.environment import get_base_url - -# Lazy-evaluate URLs so including pwa.urls in root urlconf works -resolve_url = lazy(resolve_url, str) - -# Get script prefix for apps not mounted under / -_PWA_SCRIPT_PREFIX = get_script_prefix() - -# Path to the service worker implementation. Default implementation is empty. -PWA_SERVICE_WORKER_PATH = getattr( - settings, - "PWA_SERVICE_WORKER_PATH", - os.path.join( - os.path.abspath(os.path.dirname(__file__)), "templates", "serviceworker.js" - ), -) -# App parameters to include in manifest.json and appropriate meta tags -PWA_APP_NAME = getattr(settings, "PWA_APP_NAME", "MyApp") -PWA_APP_DESCRIPTION = getattr(settings, "PWA_APP_DESCRIPTION", "My Progressive Web App") -PWA_APP_ROOT_URL = resolve_url( - getattr(settings, "PWA_APP_ROOT_URL", _PWA_SCRIPT_PREFIX) -) -PWA_APP_THEME_COLOR = getattr(settings, "PWA_APP_THEME_COLOR", "#000") -PWA_APP_BACKGROUND_COLOR = getattr(settings, "PWA_APP_BACKGROUND_COLOR", "#fff") -PWA_APP_DISPLAY = getattr(settings, "PWA_APP_DISPLAY", "standalone") -PWA_APP_SCOPE = resolve_url(getattr(settings, "PWA_APP_SCOPE", _PWA_SCRIPT_PREFIX)) -PWA_APP_DEBUG_MODE = getattr(settings, "PWA_APP_DEBUG_MODE", True) -PWA_APP_ORIENTATION = getattr(settings, "PWA_APP_ORIENTATION", "any") -PWA_APP_START_URL = resolve_url( - getattr(settings, "PWA_APP_START_URL", _PWA_SCRIPT_PREFIX) -) -PWA_APP_FETCH_URL = resolve_url( - getattr(settings, "PWA_APP_FETCH_URL", _PWA_SCRIPT_PREFIX) -) -PWA_APP_STATUS_BAR_COLOR = getattr(settings, "PWA_APP_STATUS_BAR_COLOR", "default") -PWA_APP_ICONS = getattr(settings, "PWA_APP_ICONS", []) -PWA_APP_ICONS_APPLE = getattr(settings, "PWA_APP_ICONS_APPLE", []) -PWA_APP_SPLASH_SCREEN = getattr(settings, "PWA_APP_SPLASH_SCREEN", []) -PWA_APP_DIR = getattr(settings, "PWA_APP_DIR", "auto") -PWA_APP_LANG = getattr(settings, "PWA_APP_LANG", "en-US") -PWA_BASE_URL = get_base_url() diff --git a/conreq/core/pwa/apps.py b/conreq/core/pwa/apps.py deleted file mode 100644 index 6627512c..00000000 --- a/conreq/core/pwa/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class PwaConfig(AppConfig): - name = "conreq.core.pwa" diff --git a/conreq/core/pwa/templates/manifest.json b/conreq/core/pwa/templates/manifest.json deleted file mode 100644 index 0f444fa7..00000000 --- a/conreq/core/pwa/templates/manifest.json +++ /dev/null @@ -1,16 +0,0 @@ -{% load pwa %} -{ - "name": {{ PWA_APP_NAME|js }}, - "short_name": {{ PWA_APP_NAME|js }}, - "description": {{ PWA_APP_DESCRIPTION|js }}, - "start_url": {{ PWA_APP_START_URL|js }}, - "display": {{ PWA_APP_DISPLAY|js }}, - "scope": {{ PWA_APP_SCOPE|js }}, - "orientation": {{ PWA_APP_ORIENTATION|js }}, - "background_color": {{ PWA_APP_BACKGROUND_COLOR|js }}, - "theme_color": {{ PWA_APP_THEME_COLOR|js }}, - "status_bar": {{ PWA_APP_STATUS_BAR_COLOR|js }}, - "icons": {{ PWA_APP_ICONS|js }}, - "dir": {{ PWA_APP_DIR|js }}, - "lang": {{ PWA_APP_LANG|js }} -} diff --git a/conreq/core/pwa/templates/offline.html b/conreq/core/pwa/templates/offline.html deleted file mode 100644 index 11b3b0c9..00000000 --- a/conreq/core/pwa/templates/offline.html +++ /dev/null @@ -1,25 +0,0 @@ -{% load static %} -{% load conreq_tags %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-

Could not connect to {% app_name %}.

-

Check your network connection or try again later.

-
-
- - - \ No newline at end of file diff --git a/conreq/core/pwa/templates/pwa.html b/conreq/core/pwa/templates/pwa.html deleted file mode 100644 index 8b237ff3..00000000 --- a/conreq/core/pwa/templates/pwa.html +++ /dev/null @@ -1,52 +0,0 @@ -{% load static %} - - - - - - - - - - - - - - - - -{% for icon in PWA_APP_ICONS_APPLE %} - -{% endfor %} -{% for icon in PWA_APP_ICONS %} - -{% endfor %} - - -{% for splash in PWA_APP_SPLASH_SCREEN %} - -{% endfor %} - - - - - - - \ No newline at end of file diff --git a/conreq/core/pwa/templates/serviceworker.js b/conreq/core/pwa/templates/serviceworker.js deleted file mode 100644 index e0cb26d0..00000000 --- a/conreq/core/pwa/templates/serviceworker.js +++ /dev/null @@ -1,45 +0,0 @@ -// Base Service Worker implementation. To use your own Service Worker, set the PWA_SERVICE_WORKER_PATH variable in settings.py - -var staticCacheName = "django-pwa-v" + new Date().getTime(); -var filesToCache = [ - "{{ base_url|escapejs }}/offline/", - "{{ base_url|escapejs }}/static/css/main_slim.css", -]; - -// Cache on install -self.addEventListener("install", (event) => { - this.skipWaiting(); - event.waitUntil( - caches.open(staticCacheName).then((cache) => { - return cache.addAll(filesToCache); - }) - ); -}); - -// Clear cache on activate -self.addEventListener("activate", (event) => { - event.waitUntil( - caches.keys().then((cacheNames) => { - return Promise.all( - cacheNames - .filter((cacheName) => cacheName.startsWith("django-pwa-")) - .filter((cacheName) => cacheName !== staticCacheName) - .map((cacheName) => caches.delete(cacheName)) - ); - }) - ); -}); - -// Serve from Cache -self.addEventListener("fetch", (event) => { - event.respondWith( - caches - .match(event.request) - .then((response) => { - return response || fetch(event.request); - }) - .catch(() => { - return caches.match("{{ base_url|escapejs }}/offline/"); - }) - ); -}); diff --git a/conreq/core/pwa/templatetags/pwa.py b/conreq/core/pwa/templatetags/pwa.py deleted file mode 100644 index 5eea486a..00000000 --- a/conreq/core/pwa/templatetags/pwa.py +++ /dev/null @@ -1,25 +0,0 @@ -import json - -from django import template -from django.core.serializers.json import DjangoJSONEncoder -from django.utils.safestring import mark_safe - -from .. import app_settings - -register = template.Library() - - -@register.filter(is_safe=True) -def js(obj): - """Transform a python object so it can be safely used in javascript/JSON.""" - return mark_safe(json.dumps(obj, cls=DjangoJSONEncoder)) - - -@register.inclusion_tag("pwa.html", takes_context=True) -def progressive_web_app_meta(context): - # Pass all PWA_* settings into the template - return { - setting_name: getattr(app_settings, setting_name) - for setting_name in dir(app_settings) - if setting_name.startswith("PWA_") - } diff --git a/conreq/core/pwa/urls.py b/conreq/core/pwa/urls.py deleted file mode 100644 index 45927c9d..00000000 --- a/conreq/core/pwa/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.urls import path - -from .views import manifest, offline, service_worker - -app_name = "pwa" -# Serve up serviceworker.js and manifest.json at the root -urlpatterns = [ - path("serviceworker.js", service_worker, name="serviceworker"), - path("manifest.json", manifest, name="manifest"), - path("offline/", offline, name="offline"), -] diff --git a/conreq/core/pwa/views.py b/conreq/core/pwa/views.py deleted file mode 100644 index 0c7ed215..00000000 --- a/conreq/core/pwa/views.py +++ /dev/null @@ -1,33 +0,0 @@ -from django.shortcuts import render - -from conreq.utils.environment import get_base_url - -from . import app_settings - -BASE_URL = get_base_url() - - -def service_worker(request): - return render( - request, - "serviceworker.js", - {"base_url": BASE_URL}, - content_type="application/javascript", - ) - - -def manifest(request): - return render( - request, - "manifest.json", - { - setting_name: getattr(app_settings, setting_name) - for setting_name in dir(app_settings) - if setting_name.startswith("PWA_") - }, - content_type="application/json", - ) - - -def offline(request): - return render(request, "offline.html") diff --git a/conreq/core/search/apps.py b/conreq/core/search/apps.py deleted file mode 100644 index 77a28af2..00000000 --- a/conreq/core/search/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class SearchConfig(AppConfig): - name = "conreq.core.search" diff --git a/conreq/core/search/urls.py b/conreq/core/search/urls.py deleted file mode 100644 index 8fcdb2b6..00000000 --- a/conreq/core/search/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "search" -urlpatterns = [ - path("", views.search, name="main"), -] diff --git a/conreq/core/search/views.py b/conreq/core/search/views.py deleted file mode 100644 index 061c753e..00000000 --- a/conreq/core/search/views.py +++ /dev/null @@ -1,45 +0,0 @@ -from django.contrib.auth.decorators import login_required -from django.http import HttpResponse -from django.template import loader -from django.views.decorators.cache import cache_page - -from conreq.core.discover.helpers import set_many_availability -from conreq.core.tmdb.discovery import TmdbDiscovery -from conreq.core.tmdb.search import TmdbSearch -from conreq.utils.debug import performance_metrics - - -@cache_page(15) -@login_required -@performance_metrics() -def search(request): - content_discovery = TmdbDiscovery() - searcher = TmdbSearch() - - # Get the ID from the URL - query = request.GET.get("query", "") - content_type = request.GET.get("content_type", None) - page = int(request.GET.get("page", 1)) - - # Determine which search method to use (tv/movie/all) - if content_type == "tv": - tmdb_results = searcher.television(query, page) - elif content_type == "movie": - tmdb_results = searcher.movie(query, page) - else: - tmdb_results = searcher.all(query, page) - - if tmdb_results: - tmdb_results = tmdb_results.get("results") - - # Determine the availability - content_discovery.determine_id_validity(tmdb_results) - set_many_availability(tmdb_results) - - context = { - "all_cards": tmdb_results, - "content_type": content_type, - "search_query": query, - } - template = loader.get_template("viewport/search.html") - return HttpResponse(template.render(context, request)) diff --git a/conreq/core/server_settings/admin.py b/conreq/core/server_settings/admin.py deleted file mode 100644 index fe94f1c5..00000000 --- a/conreq/core/server_settings/admin.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib import admin - -from conreq.core.server_settings.models import ConreqConfig - - -# Register your models here. -@admin.register(ConreqConfig) -class ServerSettings(admin.ModelAdmin): - pass diff --git a/conreq/core/server_settings/apps.py b/conreq/core/server_settings/apps.py deleted file mode 100644 index ff2c4601..00000000 --- a/conreq/core/server_settings/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class ServerSettingsConfig(AppConfig): - name = "conreq.core.server_settings" diff --git a/conreq/core/server_settings/migrations/0001_initial.py b/conreq/core/server_settings/migrations/0001_initial.py deleted file mode 100644 index 4e0ad204..00000000 --- a/conreq/core/server_settings/migrations/0001_initial.py +++ /dev/null @@ -1,57 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-16 11:38 - -from django.db import migrations, models -import encrypted_fields.fields - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='ConreqConfig', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('conreq_api_key', models.CharField(default='', max_length=100)), - ('conreq_secret_key', models.CharField(default='', max_length=100)), - ('conreq_app_name', models.CharField(default='Conreq', max_length=100)), - ('conreq_language', models.CharField(default='', max_length=100)), - ('conreq_app_logo', models.ImageField(upload_to='')), - ('conreq_app_url', models.URLField(default='')), - ('conreq_custom_css', models.URLField(default='')), - ('conreq_custom_js', models.URLField(default='')), - ('conreq_simple_posters', models.BooleanField(default=False)), - ('conreq_auto_resolve_issues', models.BooleanField(default=True)), - ('conreq_guest_login', models.BooleanField(default=False)), - ('conreq_dark_theme', models.BooleanField(default=False)), - ('sonarr_url', models.URLField(default='')), - ('sonarr_api_key', models.CharField(default='', max_length=100)), - ('sonarr_anime_quality_profile', models.PositiveIntegerField(default=1)), - ('sonarr_anime_folder', models.FilePathField(default='')), - ('sonarr_tv_quality_profile', models.PositiveIntegerField(default=1)), - ('sonarr_tv_folder', models.FilePathField(default='')), - ('sonarr_enabled', models.BooleanField(default=False)), - ('sonarr_season_folders', models.BooleanField(default=True)), - ('radarr_url', models.URLField(default='')), - ('radarr_api_key', models.CharField(default='', max_length=100)), - ('radarr_anime_quality_profile', models.PositiveIntegerField(default=1)), - ('radarr_anime_folder', models.FilePathField(default='')), - ('radarr_movies_quality_profile', models.PositiveIntegerField(default=1)), - ('radarr_movies_folder', models.FilePathField(default='')), - ('radarr_enabled', models.BooleanField(default=False)), - ('email_smtp_server', models.URLField(default='')), - ('email_smtp_port', models.PositiveIntegerField(default=587)), - ('email_username', encrypted_fields.fields.EncryptedCharField(default='', max_length=100)), - ('email_password', encrypted_fields.fields.EncryptedCharField(default='', max_length=100)), - ('email_sender_name', models.CharField(default='', max_length=50)), - ('email_enable_tls', models.BooleanField(default=True)), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/conreq/core/server_settings/migrations/0002_auto_20210118_2004.py b/conreq/core/server_settings/migrations/0002_auto_20210118_2004.py deleted file mode 100644 index 32621376..00000000 --- a/conreq/core/server_settings/migrations/0002_auto_20210118_2004.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-19 04:04 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='radarr_anime_folder', - field=models.PositiveIntegerField(default=1), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_movies_folder', - field=models.PositiveIntegerField(default=1), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_anime_folder', - field=models.PositiveIntegerField(default=1), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_tv_folder', - field=models.PositiveIntegerField(default=1), - ), - ] diff --git a/conreq/core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py b/conreq/core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py deleted file mode 100644 index e6453b92..00000000 --- a/conreq/core/server_settings/migrations/0003_conreqconfig_conreq_initialized.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-19 08:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0002_auto_20210118_2004'), - ] - - operations = [ - migrations.AddField( - model_name='conreqconfig', - name='conreq_initialized', - field=models.BooleanField(default=False), - ), - ] diff --git a/conreq/core/server_settings/migrations/0004_auto_20210119_1742.py b/conreq/core/server_settings/migrations/0004_auto_20210119_1742.py deleted file mode 100644 index 782a3f88..00000000 --- a/conreq/core/server_settings/migrations/0004_auto_20210119_1742.py +++ /dev/null @@ -1,88 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-20 01:42 - -from django.db import migrations, models -import encrypted_fields.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0003_conreqconfig_conreq_initialized'), - ] - - operations = [ - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_secret_key', - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_api_key', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_app_logo', - field=models.ImageField(blank=True, upload_to=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_app_url', - field=models.URLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_css', - field=models.URLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_js', - field=models.URLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_language', - field=models.CharField(default='en', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_password', - field=encrypted_fields.fields.EncryptedCharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_sender_name', - field=models.CharField(blank=True, default='', max_length=50), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_smtp_server', - field=models.URLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_username', - field=encrypted_fields.fields.EncryptedCharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_api_key', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_url', - field=models.URLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_api_key', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_url', - field=models.URLField(blank=True, default=''), - ), - ] diff --git a/conreq/core/server_settings/migrations/0005_auto_20210127_0107.py b/conreq/core/server_settings/migrations/0005_auto_20210127_0107.py deleted file mode 100644 index 1c2717c6..00000000 --- a/conreq/core/server_settings/migrations/0005_auto_20210127_0107.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-27 09:07 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0004_auto_20210119_1742'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_dark_theme', - field=models.BooleanField(default=True), - ), - ] diff --git a/conreq/core/server_settings/migrations/0006_auto_20210130_0236.py b/conreq/core/server_settings/migrations/0006_auto_20210130_0236.py deleted file mode 100644 index 590414ae..00000000 --- a/conreq/core/server_settings/migrations/0006_auto_20210130_0236.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-30 10:36 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0005_auto_20210127_0107'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_css', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_js', - field=models.CharField(blank=True, default='', max_length=100), - ), - ] diff --git a/conreq/core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py b/conreq/core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py deleted file mode 100644 index a0c67ca3..00000000 --- a/conreq/core/server_settings/migrations/0007_conreqconfig_conreq_http_header_auth.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-02 12:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0006_auto_20210130_0236'), - ] - - operations = [ - migrations.AddField( - model_name='conreqconfig', - name='conreq_http_header_auth', - field=models.BooleanField(default=False), - ), - ] diff --git a/conreq/core/server_settings/migrations/0008_auto_20210203_0053.py b/conreq/core/server_settings/migrations/0008_auto_20210203_0053.py deleted file mode 100644 index 0cac44a6..00000000 --- a/conreq/core/server_settings/migrations/0008_auto_20210203_0053.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-03 08:53 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0007_conreqconfig_conreq_http_header_auth'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_simple_posters', - field=models.BooleanField(default=True), - ), - ] diff --git a/conreq/core/server_settings/migrations/0009_auto_20210204_1938.py b/conreq/core/server_settings/migrations/0009_auto_20210204_1938.py deleted file mode 100644 index 80280e76..00000000 --- a/conreq/core/server_settings/migrations/0009_auto_20210204_1938.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-05 03:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0008_auto_20210203_0053'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_app_url', - field=models.CharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_smtp_server', - field=models.CharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_url', - field=models.CharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_url', - field=models.CharField(blank=True, default='', max_length=255), - ), - ] diff --git a/conreq/core/server_settings/migrations/0011_auto_20210205_2343.py b/conreq/core/server_settings/migrations/0011_auto_20210205_2343.py deleted file mode 100644 index 9030efa8..00000000 --- a/conreq/core/server_settings/migrations/0011_auto_20210205_2343.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-06 07:43 - -from django.db import migrations -import url_or_relative_url_field.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0010_auto_20210205_2326'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_css', - field=url_or_relative_url_field.fields.URLOrRelativeURLField(blank=True, default=''), - ), - migrations.AlterField( - model_name='conreqconfig', - name='conreq_custom_js', - field=url_or_relative_url_field.fields.URLOrRelativeURLField(blank=True, default=''), - ), - ] diff --git a/conreq/core/server_settings/migrations/0012_auto_20210209_2144.py b/conreq/core/server_settings/migrations/0012_auto_20210209_2144.py deleted file mode 100644 index b518f72d..00000000 --- a/conreq/core/server_settings/migrations/0012_auto_20210209_2144.py +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-10 05:44 - -from django.db import migrations, models -import encrypted_fields.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0011_auto_20210205_2343'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='conreq_api_key', - field=models.CharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_password', - field=encrypted_fields.fields.EncryptedCharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='email_username', - field=encrypted_fields.fields.EncryptedCharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_api_key', - field=models.CharField(blank=True, default='', max_length=255), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_api_key', - field=models.CharField(blank=True, default='', max_length=255), - ), - ] diff --git a/conreq/core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py b/conreq/core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py deleted file mode 100644 index 0a99193c..00000000 --- a/conreq/core/server_settings/migrations/0013_conreqconfig_conreq_allow_tv_specials.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.7 on 2021-03-13 09:54 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0012_auto_20210209_2144'), - ] - - operations = [ - migrations.AddField( - model_name='conreqconfig', - name='conreq_allow_tv_specials', - field=models.BooleanField(default=True), - ), - ] diff --git a/conreq/core/server_settings/migrations/0014_auto_20210313_0231.py b/conreq/core/server_settings/migrations/0014_auto_20210313_0231.py deleted file mode 100644 index 3f15bb1a..00000000 --- a/conreq/core/server_settings/migrations/0014_auto_20210313_0231.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 3.1.7 on 2021-03-13 10:31 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0013_conreqconfig_conreq_allow_tv_specials'), - ] - - operations = [ - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_app_logo', - ), - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_app_url', - ), - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_guest_login', - ), - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_language', - ), - ] diff --git a/conreq/core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py b/conreq/core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py deleted file mode 100644 index 3194538e..00000000 --- a/conreq/core/server_settings/migrations/0015_remove_conreqconfig_conreq_app_name.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.1.7 on 2021-03-21 09:02 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0014_auto_20210313_0231'), - ] - - operations = [ - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_app_name', - ), - ] diff --git a/conreq/core/server_settings/migrations/0016_alter_conreqconfig_id.py b/conreq/core/server_settings/migrations/0016_alter_conreqconfig_id.py deleted file mode 100644 index 363738d8..00000000 --- a/conreq/core/server_settings/migrations/0016_alter_conreqconfig_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2 on 2021-04-13 05:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0015_remove_conreqconfig_conreq_app_name'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - ] diff --git a/conreq/core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py b/conreq/core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py deleted file mode 100644 index ca57f97c..00000000 --- a/conreq/core/server_settings/migrations/0017_remove_conreqconfig_conreq_dark_theme.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2 on 2021-04-26 04:01 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0016_alter_conreqconfig_id'), - ] - - operations = [ - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_dark_theme', - ), - ] diff --git a/conreq/core/server_settings/migrations/0018_auto_20210428_2039.py b/conreq/core/server_settings/migrations/0018_auto_20210428_2039.py deleted file mode 100644 index 6764f123..00000000 --- a/conreq/core/server_settings/migrations/0018_auto_20210428_2039.py +++ /dev/null @@ -1,53 +0,0 @@ -# Generated by Django 3.2 on 2021-04-29 03:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0017_remove_conreqconfig_conreq_dark_theme'), - ] - - operations = [ - migrations.AlterField( - model_name='conreqconfig', - name='radarr_anime_folder', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_anime_quality_profile', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_movies_folder', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='radarr_movies_quality_profile', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_anime_folder', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_anime_quality_profile', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_tv_folder', - field=models.PositiveIntegerField(default=0), - ), - migrations.AlterField( - model_name='conreqconfig', - name='sonarr_tv_quality_profile', - field=models.PositiveIntegerField(default=0), - ), - ] diff --git a/conreq/core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py b/conreq/core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py deleted file mode 100644 index 9260a1ad..00000000 --- a/conreq/core/server_settings/migrations/0019_remove_conreqconfig_conreq_api_key.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.2 on 2021-05-10 02:32 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('server_settings', '0018_auto_20210428_2039'), - ] - - operations = [ - migrations.RemoveField( - model_name='conreqconfig', - name='conreq_api_key', - ), - ] diff --git a/conreq/core/server_settings/models.py b/conreq/core/server_settings/models.py deleted file mode 100644 index 41aa0a7a..00000000 --- a/conreq/core/server_settings/models.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.db import models -from encrypted_fields.fields import EncryptedCharField -from model_utils import FieldTracker -from solo.models import SingletonModel -from url_or_relative_url_field.fields import URLOrRelativeURLField - -from conreq.core.base.fields import ExtendedURLField - - -# Create your models here. -class ConreqConfig(SingletonModel): - # Basic settings - conreq_custom_css = URLOrRelativeURLField(default="", blank=True) - conreq_custom_js = URLOrRelativeURLField(default="", blank=True) - conreq_simple_posters = models.BooleanField(default=True) - conreq_auto_resolve_issues = models.BooleanField(default=True) - conreq_allow_tv_specials = models.BooleanField(default=True) - conreq_http_header_auth = models.BooleanField(default=False) - conreq_initialized = models.BooleanField(default=False) - - # Sonarr settings - sonarr_url = ExtendedURLField(default="", blank=True) - sonarr_api_key = models.CharField(max_length=255, default="", blank=True) - sonarr_anime_quality_profile = models.PositiveIntegerField(default=0) - sonarr_anime_folder = models.PositiveIntegerField(default=0) - sonarr_tv_quality_profile = models.PositiveIntegerField(default=0) - sonarr_tv_folder = models.PositiveIntegerField(default=0) - sonarr_enabled = models.BooleanField(default=False) - sonarr_season_folders = models.BooleanField(default=True) - - # Radarr Settings - radarr_url = ExtendedURLField(default="", blank=True) - radarr_api_key = models.CharField(max_length=255, default="", blank=True) - radarr_anime_quality_profile = models.PositiveIntegerField(default=0) - radarr_anime_folder = models.PositiveIntegerField(default=0) - radarr_movies_quality_profile = models.PositiveIntegerField(default=0) - radarr_movies_folder = models.PositiveIntegerField(default=0) - radarr_enabled = models.BooleanField(default=False) - - # Email settings - email_smtp_server = models.CharField(max_length=255, default="", blank=True) - email_smtp_port = models.PositiveIntegerField(default=587) - email_username = EncryptedCharField(max_length=255, default="", blank=True) - email_password = EncryptedCharField(max_length=255, default="", blank=True) - email_sender_name = models.CharField(max_length=50, default="", blank=True) - email_enable_tls = models.BooleanField(default=True) - - # Field Tracker - tracker = FieldTracker() diff --git a/conreq/core/server_settings/urls.py b/conreq/core/server_settings/urls.py deleted file mode 100644 index 0011c375..00000000 --- a/conreq/core/server_settings/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "server_settings" -urlpatterns = [ - path("", views.server_settings, name="main"), - path("sonarr_settings", views.sonarr_settings, name="sonarr_settings"), - path("radarr_settings", views.radarr_settings, name="radarr_settings"), - path("update_settings", views.update_settings, name="update_settings"), -] diff --git a/conreq/core/server_settings/views.py b/conreq/core/server_settings/views.py deleted file mode 100644 index d5957c43..00000000 --- a/conreq/core/server_settings/views.py +++ /dev/null @@ -1,267 +0,0 @@ -import json -from platform import platform - -from django.conf import settings -from django.contrib.auth.decorators import login_required, user_passes_test -from django.core.exceptions import ValidationError -from django.http import HttpResponse, HttpResponseBadRequest, JsonResponse -from django.template import loader - -from conreq.core.arrs.radarr import RadarrManager -from conreq.core.arrs.sonarr import SonarrManager -from conreq.core.server_settings.models import ConreqConfig -from conreq.utils import log -from conreq.utils.debug import performance_metrics - -_logger = log.get_logger(__name__) - - -@login_required -@user_passes_test(lambda u: u.is_staff) -@performance_metrics() -def server_settings(request): - template = loader.get_template("viewport/server_settings.html") - context = {"os_platform": platform(), "version": settings.CONREQ_VERSION} - return HttpResponse(template.render(context, request)) - - -def radarr_settings(request): - template = loader.get_template("viewport/components/server_settings_radarr.html") - - # Database values - conreq_config = ConreqConfig.get_solo() - - # Obtain sonarr and radarr information - radarr_manager = RadarrManager() - radarr_quality_profiles = [] - current_radarr_anime_quality_profile = "" - current_radarr_movies_quality_profile = "" - radarr_folders = [] - current_radarr_anime_folder = "" - current_radarr_movies_folder = "" - - if conreq_config.radarr_enabled: - # Radarr Quality Profiles - try: - for profile in radarr_manager.radarr_quality_profiles(): - # Current anime movies profile - if conreq_config.radarr_anime_quality_profile == profile["id"]: - current_radarr_anime_quality_profile = profile["name"] - # Current TV profile - if conreq_config.radarr_movies_quality_profile == profile["id"]: - current_radarr_movies_quality_profile = profile["name"] - # List of all dropdown entries - radarr_quality_profiles.append( - {"id": profile["id"], "label": profile["name"]} - ) - except Exception: - log.handler("Failed to obtain Radarr Quality Profiles!", log.ERROR, _logger) - - # Radarr Folder Paths - try: - for path in radarr_manager.radarr_root_dirs(): - # Current anime movies dirs - if conreq_config.radarr_anime_folder == path["id"]: - current_radarr_anime_folder = path["path"] - # Current TV dirs - if conreq_config.radarr_movies_folder == path["id"]: - current_radarr_movies_folder = path["path"] - # List of all dropdown entries - radarr_folders.append({"id": path["id"], "label": path["path"]}) - except Exception: - log.handler("Failed to obtain Radarr Folder Paths!", log.ERROR, _logger) - - context = { - "radarr_quality_profiles": radarr_quality_profiles, - "current_radarr_anime_quality_profile": current_radarr_anime_quality_profile, - "current_radarr_movies_quality_profile": current_radarr_movies_quality_profile, - "radarr_folders": radarr_folders, - "current_radarr_anime_folder": current_radarr_anime_folder, - "current_radarr_movies_folder": current_radarr_movies_folder, - } - - return HttpResponse(template.render(context, request)) - - -def sonarr_settings(request): - template = loader.get_template("viewport/components/server_settings_sonarr.html") - - # Database values - conreq_config = ConreqConfig.get_solo() - - # Obtain sonarr and radarr information - sonarr_manager = SonarrManager() - sonarr_quality_profiles = [] - current_sonarr_anime_quality_profile = "" - current_sonarr_tv_quality_profile = "" - sonarr_folders = [] - current_sonarr_anime_folder = "" - current_sonarr_tv_folder = "" - - if conreq_config.sonarr_enabled: - # Sonarr Quality Profiles - try: - for profile in sonarr_manager.sonarr_quality_profiles(): - # Current anime profile - if conreq_config.sonarr_anime_quality_profile == profile["id"]: - current_sonarr_anime_quality_profile = profile["name"] - # Current TV profile - if conreq_config.sonarr_tv_quality_profile == profile["id"]: - current_sonarr_tv_quality_profile = profile["name"] - # List of all dropdown entries - sonarr_quality_profiles.append( - {"id": profile["id"], "label": profile["name"]} - ) - except Exception: - log.handler("Failed to obtain Sonarr Quality Profiles!", log.ERROR, _logger) - - # Sonarr Folder Paths - try: - for path in sonarr_manager.sonarr_root_dirs(): - # Current anime dirs - if conreq_config.sonarr_anime_folder == path["id"]: - current_sonarr_anime_folder = path["path"] - # Current TV dirs - if conreq_config.sonarr_tv_folder == path["id"]: - current_sonarr_tv_folder = path["path"] - # List of all dropdown entries - sonarr_folders.append({"id": path["id"], "label": path["path"]}) - except Exception: - log.handler("Failed to obtain Sonarr Folder Paths!", log.ERROR, _logger) - - context = { - "sonarr_quality_profiles": sonarr_quality_profiles, - "current_sonarr_anime_quality_profile": current_sonarr_anime_quality_profile, - "current_sonarr_tv_quality_profile": current_sonarr_tv_quality_profile, - "sonarr_folders": sonarr_folders, - "current_sonarr_anime_folder": current_sonarr_anime_folder, - "current_sonarr_tv_folder": current_sonarr_tv_folder, - } - - return HttpResponse(template.render(context, request)) - - -@login_required -@user_passes_test(lambda u: u.is_staff) -@performance_metrics() -def update_settings(request): - if request.method == "POST": - response = { - "success": True, - } - message = json.loads(request.body.decode("utf-8")) - try: - # Database values - conreq_config = ConreqConfig.get_solo() - - # Basic Configuration - if message["setting_name"] == "Conreq Custom CSS": - conreq_config.conreq_custom_css = message["value"] - - elif message["setting_name"] == "Conreq Custom JS": - conreq_config.conreq_custom_js = message["value"] - - elif message["setting_name"] == "Conreq Automatically Resolve Issues": - conreq_config.conreq_auto_resolve_issues = message["value"] - - elif message["setting_name"] == "Conreq Allow TV Specials": - conreq_config.conreq_allow_tv_specials = message["value"] - - elif message["setting_name"] == "Conreq Simple/Minimal Poster Cards": - conreq_config.conreq_simple_posters = message["value"] - - elif message["setting_name"] == "Conreq HTTP Auth": - conreq_config.conreq_http_header_auth = message["value"] - - # Sonarr Settings - elif message["setting_name"] == "Sonarr URL": - conreq_config.sonarr_url = message["value"] - - elif message["setting_name"] == "Sonarr API Key": - conreq_config.sonarr_api_key = message["value"] - - elif message["setting_name"] == "Sonarr Anime Quality Profile": - conreq_config.sonarr_anime_quality_profile = message["value"] - - elif message["setting_name"] == "Sonarr TV Quality Profile": - conreq_config.sonarr_tv_quality_profile = message["value"] - - elif message["setting_name"] == "Sonarr Anime Folder Path": - conreq_config.sonarr_anime_folder = message["value"] - - elif message["setting_name"] == "Sonarr TV Folder Path": - conreq_config.sonarr_tv_folder = message["value"] - - elif message["setting_name"] == "Enable Sonarr": - conreq_config.sonarr_enabled = message["value"] - - elif message["setting_name"] == "Sonarr Season Folders": - conreq_config.sonarr_season_folders = message["value"] - - # Radarr Settings - elif message["setting_name"] == "Radarr URL": - conreq_config.radarr_url = message["value"] - - elif message["setting_name"] == "Radarr API Key": - conreq_config.radarr_api_key = message["value"] - - elif message["setting_name"] == "Radarr Anime Quality Profile": - conreq_config.radarr_anime_quality_profile = message["value"] - - elif message["setting_name"] == "Radarr Movies Quality Profile": - conreq_config.radarr_movies_quality_profile = message["value"] - - elif message["setting_name"] == "Radarr Anime Folder Path": - conreq_config.radarr_anime_folder = message["value"] - - elif message["setting_name"] == "Radarr Movies Folder Path": - conreq_config.radarr_movies_folder = message["value"] - - elif message["setting_name"] == "Enable Radarr": - conreq_config.radarr_enabled = message["value"] - - # Unhandled setting failure - else: - log.handler( - 'Server setting "' - + message["setting_name"] - + '" is currently not handled!', - log.WARNING, - _logger, - ) - response["success"] = False - response["error_message"] = "Unhandled server setting!" - return JsonResponse(response) - - # Model fails validation schema - try: - conreq_config.clean_fields() - except ValidationError as error: - for field, message in dict(error).items(): - response["success"] = False - response["error_message"] = field + ": " + message[0] - # Send a message to the user - return JsonResponse(response) - - # Save the model if it passes all checks - if response["success"]: - conreq_config.save() - log.handler( - message, - log.INFO, - _logger, - ) - return JsonResponse(response) - - # Unknown exception occured - except Exception: - response["success"] = False - response["error_message"] = "Unknown error!" - log.handler( - "Unknown error has occurred within server websocket!", - log.ERROR, - _logger, - ) - return JsonResponse(response) - - return HttpResponseBadRequest() diff --git a/conreq/core/sign_up/apps.py b/conreq/core/sign_up/apps.py deleted file mode 100644 index b86c08fb..00000000 --- a/conreq/core/sign_up/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class SignUpConfig(AppConfig): - name = "conreq.core.sign_up" diff --git a/conreq/core/sign_up/templates/modal/default.html b/conreq/core/sign_up/templates/modal/default.html deleted file mode 100644 index 7c25a870..00000000 --- a/conreq/core/sign_up/templates/modal/default.html +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/conreq/core/sign_up/templates/modal/manage_user.html b/conreq/core/sign_up/templates/modal/manage_user.html deleted file mode 100644 index c5fc8de7..00000000 --- a/conreq/core/sign_up/templates/modal/manage_user.html +++ /dev/null @@ -1,83 +0,0 @@ -{% include "primary/loading_animation.html" %} - \ No newline at end of file diff --git a/conreq/core/sign_up/templates/registration/initialization.html b/conreq/core/sign_up/templates/registration/initialization.html deleted file mode 100644 index 5408344a..00000000 --- a/conreq/core/sign_up/templates/registration/initialization.html +++ /dev/null @@ -1,111 +0,0 @@ -{% load static compress %} -{% load static %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- -
- {% csrf_token %} -

FIRST TIME SETUP

- - -
-

Create your admin account

- {{ form.email.errors }} - - - {{ form.username.errors }} - - - {{ form.password2.errors }} - - - -
- - -
-

Set up Sonarr (optional)

- - {{ form.sonarr_url.errors }} - - - {{ form.sonarr_api_key.errors }} - -
- - -
-

Set up Radarr (optional)

- - {{ form.radarr_url.errors }} - - - {{ form.radarr_api_key.errors }} - -
- - - -
- - -
- - -
- - - -
- -
-
- - - {% if form.errors %} - - {% endif %} - - {% compress js %} - - {% endcompress %} -
- - - \ No newline at end of file diff --git a/conreq/core/sign_up/templates/registration/sign_in.html b/conreq/core/sign_up/templates/registration/sign_in.html deleted file mode 100644 index 373b75d5..00000000 --- a/conreq/core/sign_up/templates/registration/sign_in.html +++ /dev/null @@ -1,49 +0,0 @@ -{% load static %} -{% load conreq_tags %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- - - - {% if ""|email_enabled %} - - {% endif %} - -
-
- - - - \ No newline at end of file diff --git a/conreq/core/sign_up/templates/registration/sign_up.html b/conreq/core/sign_up/templates/registration/sign_up.html deleted file mode 100644 index bc772145..00000000 --- a/conreq/core/sign_up/templates/registration/sign_up.html +++ /dev/null @@ -1,67 +0,0 @@ -{% load static compress %} -{% load solo_tags %} -{% load static %} -{% load conreq_tags %} - - - - - {% include "primary/head_content_slim.html" %} - - - - -
-
-
-
- -
-
-
- -
- -
- {% csrf_token %} -

REGISTRATION

-

Create your new {% app_name %} account!

- - {{ form.email.errors }} - - - {{ form.username.errors }} - - - {{ form.password2.errors }} - - - - - - -
-
- - - {% if form.errors %} - - {% endif %} - - {% compress js %} - - {% endcompress %} -
- - - \ No newline at end of file diff --git a/conreq/core/sign_up/urls.py b/conreq/core/sign_up/urls.py deleted file mode 100644 index 44857a63..00000000 --- a/conreq/core/sign_up/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "sign_up" -urlpatterns = [ - path("", views.invite, name="invite_code"), - path( - "generate_invite_code/", views.generate_invite_code, name="generate_invite_code" - ), -] diff --git a/conreq/core/sign_up/views.py b/conreq/core/sign_up/views.py deleted file mode 100644 index e52c3d8f..00000000 --- a/conreq/core/sign_up/views.py +++ /dev/null @@ -1,67 +0,0 @@ -from secrets import token_hex - -from django.contrib.auth import authenticate, login -from django.contrib.auth.decorators import login_required, user_passes_test -from django.core.cache import cache -from django.http import HttpResponse, JsonResponse -from django.shortcuts import redirect -from django.template import loader - -from conreq.core.sign_up.forms import UserForm -from conreq.utils.debug import performance_metrics - -# Days, Hours, Minutes, Seconds -INVITE_CODE_DURATION = 7 * 24 * 60 * 60 - - -@performance_metrics() -def invite(request): - # User submitted the registration form - invite_code = request.GET.get("invite_code", "") - invite_key = "invite_code" + invite_code - - if request.method == "POST": - # Check if the invite code was valid - if cache.get(invite_key): - # Check if form submission is clean - form = UserForm(request.POST) - if form.is_valid(): - # Remove the invite code, then create & login the user - cache.delete(invite_key) - form.save() - username = form.cleaned_data.get("username") - password = form.cleaned_data.get("password1") - user = authenticate(username=username, password=password) - login(request, user) - return redirect("base:landing") - - # Invite code invalid! - else: - return redirect("base:landing") - - # Submission wasn't valid, so return the error codes - template = loader.get_template("registration/sign_up.html") - return HttpResponse(template.render({"form": form}, request)) - - # User needs to fill out registration form, so check if the invite code exists - if cache.get(invite_key): - template = loader.get_template("registration/sign_up.html") - return HttpResponse(template.render({}, request)) - - # User tried to use an invalid invite code! - return redirect("base:landing") - - -@login_required -@user_passes_test(lambda u: u.is_staff) -@performance_metrics() -def generate_invite_code(request): - # Create an invite code that doesn't already exist - while True: - invite_code = token_hex(12) - cache_key = "invite_code" + invite_code - if cache.get(cache_key) is None: - cache.set(cache_key, True, INVITE_CODE_DURATION) - break - - return JsonResponse({"invite_code": invite_code}) diff --git a/conreq/core/tmdb/base.py b/conreq/core/tmdb/base.py deleted file mode 100644 index 8d935bb8..00000000 --- a/conreq/core/tmdb/base.py +++ /dev/null @@ -1,498 +0,0 @@ -"""Globals and Helpers for TMDB content discovery.""" -from random import shuffle - -import tmdbsimple as tmdb -from django.conf import settings - -from conreq.utils import cache, log -from conreq.utils.generic import is_key_value_in_list -from conreq.utils.threads import ReturnThread - -# TMDB API key is safe to hard-code. It can only access publicly available data. -tmdb.API_KEY = "112fd4c96274603f68620c78067d5422" -_logger = log.get_logger(__name__) -_timezone = getattr(settings, "TIME_ZONE") - -# Globals -ANIME_CHECK_FALLBACK = True -LANGUAGE = "en-US" -MAX_RECOMMENDED_PAGES = 10 -MAX_SHUFFLED_PAGES = 30 -# Days, Hours, Minutes, Seconds -EXTERNAL_ID_CACHE_TIMEOUT = 7 * 24 * 60 * 60 -DISCOVER_CACHE_TIMEOUT = 3 * 24 * 60 * 60 -GET_BY_TMDB_ID_CACHE_TIMEOUT = 4 * 60 * 60 -GET_BY_TVDB_ID_CACHE_TIMEOUT = 4 * 60 * 60 -GET_GENRES_CACHE_TIMEOUT = 30 * 24 * 60 * 60 -IS_ANIME_CACHE_TIMEOUT = 7 * 24 * 60 * 60 -RECOMMENDED_CACHE_TIMEOUT = 14 * 24 * 60 * 60 -SIMILAR_CACHE_TIMEOUT = 14 * 24 * 60 * 60 -COLLECTION_CACHE_TIMEOUT = 14 * 24 * 60 * 60 -PERSON_CACHE_TIMEOUT = 14 * 24 * 60 * 60 -SHUFFLED_PAGE_CACHE_TIMEOUT = 1 * 24 * 60 * 60 - - -class TmdbBase: - """Helper methods for TMDB content discovery.""" - - def is_anime(self, tmdb_id, content_type): - """Checks if a TMDB ID can be considered Anime. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - - Returns: - True/False - """ - try: - # Determine if a specific ID is anime (True/False) - if content_type == "tv": - return cache.handler( - "is tv anime", - function=self._is_tv_anime, - cache_duration=IS_ANIME_CACHE_TIMEOUT, - args=[tmdb_id], - ) - - # Determine if a specific ID is anime (True/False) - if content_type == "movie": - return cache.handler( - "is movie anime", - function=self._is_movie_anime, - cache_duration=IS_ANIME_CACHE_TIMEOUT, - args=[tmdb_id], - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in is_anime().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to check if content is anime!", - log.ERROR, - _logger, - ) - return False - return None - - @staticmethod - def get_external_ids(tmdb_id, content_type): - """Gets all external IDs given a TMDB ID. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - """ - try: - # Obtain a movie's external IDs - if content_type == "movie": - return cache.handler( - "get movie external ids", - page_key=tmdb_id, - function=tmdb.Movies(tmdb_id).external_ids, - cache_duration=EXTERNAL_ID_CACHE_TIMEOUT, - ) - - # Obtain a TV show's external IDs - if content_type == "tv": - return cache.handler( - "get tv external ids", - function=tmdb.TV(tmdb_id).external_ids, - page_key=tmdb_id, - cache_duration=EXTERNAL_ID_CACHE_TIMEOUT, - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in get_external_ids().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to obtain external ID!", - log.ERROR, - _logger, - ) - return None - - @staticmethod - def get_genres(content_type): - """Gets all available TMDB genres and genre IDs. - - Args: - content_type: String containing "movie" or "tv". - """ - try: - # Obtain a movie's genres - if content_type == "movie": - return cache.handler( - "get all movie genres", - function=tmdb.Genres().movie_list, - cache_duration=GET_GENRES_CACHE_TIMEOUT, - ) - - # Obtain a TV show's genres - if content_type == "tv": - return cache.handler( - "get all tv genres", - function=tmdb.Genres().tv_list, - cache_duration=GET_GENRES_CACHE_TIMEOUT, - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in get_genres().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to obtain genres!", - log.ERROR, - _logger, - ) - return None - - @staticmethod - def determine_id_validity(tmdb_response): - """Determine if a movie has a TMDB ID, and if TV has a TVDB ID. - Required because TVDB IDs are required for Sonarr""" - external_id_multi_fetch = {} - external_id_multi_fetch_results = None - - # Create a list of all needed IDs - for result in tmdb_response: - # TMDB TV card - if isinstance(result, dict) and result.__contains__("name"): - # Valid ID defaults to false until a TVDB match is determined - result["conreq_valid_id"] = False - external_id_multi_fetch[str(result["id"])] = { - "function": tmdb.TV(result["id"]).external_ids, - "kwargs": {}, - "args": [], - "card": result, # Store the card in here to make it slightly easier to find later - } - - # TMDB Movie card - elif isinstance(result, dict) and result.__contains__("title"): - result["conreq_valid_id"] = True - - # Grab external IDs if needed - if external_id_multi_fetch: - external_id_multi_fetch_results = cache.multi_handler( - "get tv external ids", - functions=external_id_multi_fetch, - cache_duration=EXTERNAL_ID_CACHE_TIMEOUT, - ) - - # Check if a TMDB TV show has a TVDB ID - if external_id_multi_fetch_results: - for ( - cache_key, - external_id_results, - ) in external_id_multi_fetch_results.items(): - key = cache.obtain_key_from_cache_key(cache_key) - try: - # Does an ID exist? - if external_id_results["tvdb_id"]: - # Set the ID validity - external_id_multi_fetch[key]["card"]["conreq_valid_id"] = True - external_id_multi_fetch[key]["card"][ - "tvdb_id" - ] = external_id_results["tvdb_id"] - - except Exception: - pass - - return tmdb_response - - def _multi_page_fetch( - self, cache_name, function, page_number, page_multiplier, **kwargs - ): - """Obtains multiple pages of results at once via threads.""" - total_pages = page_number * page_multiplier - thread_list = [] - for subtractor in reversed(range(0, page_multiplier)): - thread_kwargs = { - **{"page": total_pages - subtractor, "language": LANGUAGE}, - **kwargs, - } - thread = ReturnThread( - target=cache.handler, - args=[ - cache_name, - ], - kwargs={ - "function": function, - "page_key": total_pages - subtractor, - "cache_duration": DISCOVER_CACHE_TIMEOUT, - "kwargs": thread_kwargs, - }, - ) - thread.start() - thread_list.append(thread) - - # Merge together these pages - merged_results = thread_list[0].join() - thread_list.remove(thread_list[0]) - for thread in thread_list: - merged_results = self._merge_results(merged_results, thread.join()) - - # Determine if TV has a TVDB ID (required for Sonarr) - self.determine_id_validity(merged_results["results"]) - - return merged_results - - def _merge_results(self, *args): - """Merge multiple API results into one""" - try: - first_run = True - merged_results = {} - - for result in args: - # On the first run, set up the initial dictionary - if first_run: - merged_results = result.copy() - first_run = False - - # On subsequent runs, update or merge the values if needed - else: - # Set the total pages to the smallest value - if merged_results["total_pages"] > result["total_pages"]: - merged_results["total_pages"] = result["total_pages"] - - # Set the total results to the smallest value - if merged_results["total_results"] > result["total_results"]: - merged_results["total_results"] = result["total_results"] - - # Merge the search results - merged_results["results"] = ( - merged_results["results"] + result["results"] - ) - - return self._remove_duplicate_results(merged_results) - - except Exception: - log.handler( - "Failed to merge results!", - log.ERROR, - _logger, - ) - return None - - @staticmethod - def _shuffle_results(query): - """Shuffle API results""" - try: - shuffle(query["results"]) - return query - - except Exception: - log.handler( - "Failed to shuffle results!", - log.ERROR, - _logger, - ) - return None - - @staticmethod - def _remove_duplicate_results(query): - """Removes duplicates from a dict""" - try: - results = query["results"].copy() - - # Results with no duplicates - clean_results = [] - - # Keys used to determine if duplicates exist - unique_tv_keys = {} - unique_movie_keys = {} - - for entry in results: - # Remove duplicate TV - if entry.__contains__("name"): - if not unique_tv_keys.__contains__(entry["name"]): - clean_results.append(entry) - unique_tv_keys[entry["name"]] = True - - # Remove duplicate movies - elif entry.__contains__("title"): - if not unique_movie_keys.__contains__(entry["title"]): - clean_results.append(entry) - unique_movie_keys[entry["title"]] = True - - # Something unexpected happened - else: - log.handler( - "While removing duplicates, entry found that did not contain name or title!" - + str(entry), - log.WARNING, - _logger, - ) - - query["results"] = clean_results - return query - - except Exception: - log.handler( - "Failed to remove duplicate results!", - log.ERROR, - _logger, - ) - return None - - @staticmethod - def _shuffled_page_numbers(): - """Cacheable part of shuffled_page_numbers()""" - temp_list = [*range(1, MAX_SHUFFLED_PAGES + 1)] - shuffle(temp_list) - return dict(enumerate(temp_list, start=1)) - - @staticmethod - def _is_tv_anime(tmdb_id): - """Cacheable part of is_tv_anime()""" - api_results = tmdb.TV(tmdb_id).keywords() - - # Check if the content contains Keyword: Anime - if is_key_value_in_list("name", "anime", api_results["results"]): - log.handler( - str(tmdb_id) + " is anime.", - log.INFO, - _logger, - ) - return True - - # Check if fallback method is enabled - if ANIME_CHECK_FALLBACK: - tv_info = tmdb.TV(tmdb_id).info() - # Check if genere is Animation and Country is Japan - if ( - is_key_value_in_list("name", "Animation", tv_info["genres"]) - and "JP" in tv_info["origin_country"] - ): - log.handler( - str(tmdb_id) + " is anime, based on fallback detection.", - log.INFO, - _logger, - ) - return True - - log.handler( - str(tmdb_id) + " is not anime.", - log.INFO, - _logger, - ) - return False - - @staticmethod - def _is_movie_anime(tmdb_id): - """Cacheable part of is_movie_anime()""" - api_results = tmdb.Movies(tmdb_id).keywords() - - # Check if the content contains Keyword: Anime - if is_key_value_in_list("name", "anime", api_results["keywords"]): - log.handler( - str(tmdb_id) + " is anime.", - log.INFO, - _logger, - ) - return True - - # Check if fallback method is enabled - if ANIME_CHECK_FALLBACK: - movie_info = tmdb.Movies(tmdb_id).info() - - # Check if genere is Animation and Country is Japan - if is_key_value_in_list( - "name", "Animation", movie_info["genres"] - ) and is_key_value_in_list( - "iso_3166_1", "JP", movie_info["production_countries"] - ): - log.handler( - str(tmdb_id) + " is anime, based on fallback detection.", - log.INFO, - _logger, - ) - return True - - log.handler( - str(tmdb_id) + " is not anime.", - log.INFO, - _logger, - ) - return False - - @staticmethod - def _set_content_attributes(content_type, results): - """Sets the content type as tv/movie and content source as "tmdb" on a list of results""" - try: - # Set a list of results - if isinstance(results, dict) and results.__contains__("results"): - for result in results["results"]: - # Use the media type in TMDB Search endpoint if available - result["content_type"] = ( - content_type if content_type else result.get("media_type") - ) - # Special case for "Collections" - elif isinstance(results, dict) and results.__contains__("parts"): - for result in results["parts"]: - result["content_type"] = content_type - # Special case for "Person" with tv/movies appended - elif isinstance(results, dict) and ( - results.__contains__("tv_credits") - or results.__contains__("movie_credits") - ): - for result in results["tv_credits"]["cast"]: - result["content_type"] = "tv" - for result in results["tv_credits"]["crew"]: - result["content_type"] = "tv" - for result in results["movie_credits"]["cast"]: - result["content_type"] = "movie" - for result in results["movie_credits"]["crew"]: - result["content_type"] = "movie" - # Special case for get_content_by_tvdb_id - elif isinstance(results, list): - for result in results: - result["content_type"] = content_type - # # Set a single media item - elif isinstance(results, dict): - results["content_type"] = content_type - except Exception: - log.handler( - "Failed to set content attributes!", - log.ERROR, - _logger, - ) - - return results - - @staticmethod - def _remove_bad_content_types(results): - """Removes results that aren't TV or movies""" - new_results = None - try: - # Set a list of results - if isinstance(results, dict) and results.__contains__("results"): - new_results = results.copy() - new_results["results"] = [] - for result in results["results"]: - content_type = result.get("content_type") - if content_type in ("movie", "tv"): - new_results["results"].append(result) - return new_results - except Exception: - log.handler( - "Failed to set content attributes!", - log.ERROR, - _logger, - ) - - return results diff --git a/conreq/core/tmdb/discovery.py b/conreq/core/tmdb/discovery.py deleted file mode 100644 index cf9de180..00000000 --- a/conreq/core/tmdb/discovery.py +++ /dev/null @@ -1,502 +0,0 @@ -"""Conreq Content Discovery: Searches TMDB for content.""" -import tmdbsimple as tmdb - -from conreq.utils import cache, log -from conreq.utils.threads import ReturnThread, threaded_execution - -from .base import ( - COLLECTION_CACHE_TIMEOUT, - GET_BY_TMDB_ID_CACHE_TIMEOUT, - GET_BY_TVDB_ID_CACHE_TIMEOUT, - LANGUAGE, - MAX_RECOMMENDED_PAGES, - MAX_SHUFFLED_PAGES, - PERSON_CACHE_TIMEOUT, - RECOMMENDED_CACHE_TIMEOUT, - SHUFFLED_PAGE_CACHE_TIMEOUT, - SIMILAR_CACHE_TIMEOUT, - TmdbBase, - _timezone, -) -from .preset_filters import movie_filters, tv_filters - -_logger = log.get_logger(__name__) - - -class TmdbDiscovery(TmdbBase): - """Discovers top, trending, and recommended content using TMDB as the backend.""" - - # Public class methods - def all(self, page_number, page_multiplier=1): - """Get top and popular TV/Movies from TMDB.""" - # Shuffle the order of the first N many pages for randomized discovery - if page_number <= MAX_SHUFFLED_PAGES: - page = cache.handler( - "discover all page numbers", - function=self._shuffled_page_numbers, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - )[page_number] - else: - page = page_number - - return cache.handler( - "discover all", - page_key=page, - function=self.__all, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - args=[page, page_multiplier], - ) - - def tv(self, page_number, page_multiplier=1): - """Get top and popular TV from TMDB.""" - # Shuffle the order of the first N many pages for randomized discovery - if page_number <= MAX_SHUFFLED_PAGES: - page = cache.handler( - "discover tv page numbers", - function=self._shuffled_page_numbers, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - )[page_number] - else: - page = page_number - - return cache.handler( - "discover tv", - page_key=page, - function=self.__tv, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - args=[page, page_multiplier], - ) - - def movies(self, page_number, page_multiplier=1): - """Get top and popular TV from TMDB.""" - # Shuffle the order of the first N many pages for randomized discovery - if page_number <= MAX_SHUFFLED_PAGES: - page = cache.handler( - "discover movies page numbers", - function=self._shuffled_page_numbers, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - )[page_number] - else: - page = page_number - - return cache.handler( - "discover movies", - page_key=page, - function=self.__movies, - cache_duration=SHUFFLED_PAGE_CACHE_TIMEOUT, - args=[page, page_multiplier], - ) - - def popular(self, page_number, page_multiplier=1): - """Get popular content from TMDB.""" - # Merge popular_movies and popular_tv results together - function_list = [self.popular_movies, self.popular_tv] - results = threaded_execution(function_list, [page_number, page_multiplier]) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def top(self, page_number, page_multiplier=1): - """Get top content from TMDB.""" - # Merge top_movies and top_tv results together - function_list = [self.top_movies, self.top_tv] - results = threaded_execution(function_list, [page_number, page_multiplier]) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def popular_movies(self, page_number, page_multiplier=1): - """Get popular movies from TMDB.""" - return self.discover_movie_by_filter( - "popular", - page_number, - page_multiplier, - ) - - def top_movies(self, page_number, page_multiplier=1): - """Get top movies from TMDB.""" - return self.discover_movie_by_filter( - "top-rated", - page_number, - page_multiplier, - ) - - def popular_tv(self, page_number, page_multiplier=1): - """Get popular TV from TMDB.""" - return self.discover_tv_by_filter("popular", page_number, page_multiplier) - - def top_tv(self, page_number, page_multiplier=1): - """Get top TV from TMDB.""" - return self.discover_tv_by_filter("top-rated", page_number, page_multiplier) - - def discover_by_filter( - self, filter_name, page_number, page_multiplier=1, add_values=(), **kwargs - ): - """Obtains TV/Movie results based on a predefined filter name.""" - function_list = [ - self.discover_movie_by_filter, - self.discover_tv_by_filter, - ] - results = threaded_execution( - function_list, - [filter_name, page_number, page_multiplier, add_values], - **kwargs, - ) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def discover_movie_by_filter( - self, filter_name, page_number, page_multiplier=1, add_values=(), **kwargs - ): - """Obtains movie results based on a predefined filter name.""" - if filter_name == "custom": - filter_params = kwargs - else: - filter_params = movie_filters(filter_name, slug=True, add_values=add_values) - - return self._set_content_attributes( - "movie", - self._multi_page_fetch( - "discover filter " + filter_name + " movie", - tmdb.Discover().movie, - page_number, - page_multiplier, - timezone=_timezone, - **filter_params, - ), - ) - - def discover_tv_by_filter( - self, filter_name, page_number, page_multiplier=1, add_values=(), **kwargs - ): - """Obtains TV results based on a predefined filter name.""" - if filter_name == "custom": - filter_params = kwargs - else: - filter_params = tv_filters(filter_name, slug=True, add_values=add_values) - - return self._set_content_attributes( - "tv", - self._multi_page_fetch( - "discover filter " + filter_name + " tv", - tmdb.Discover().tv, - page_number, - page_multiplier, - timezone=_timezone, - **filter_params, - ), - ) - - def similar_and_recommended(self, tmdb_id, content_type): - """Merges the results of similar and recommended. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - """ - try: - thread_list = [] - merged_results = None - - # Get recommended page one - recommend_page_one = self.__recommended(tmdb_id, content_type, 1) - - # Gather additional recommended pages - if recommend_page_one and recommend_page_one["total_pages"] > 1: - for page_number in range(2, recommend_page_one["total_pages"]): - if page_number <= MAX_RECOMMENDED_PAGES: - thread = ReturnThread( - target=self.__recommended, - args=[tmdb_id, content_type, page_number], - ) - thread.start() - thread_list.append(thread) - - # There wasn't enough results in recommended, get one similar page - if not recommend_page_one["total_pages"] > 1: - thread = ReturnThread( - target=self.__similar, - args=[tmdb_id, content_type, 1], - ) - thread.start() - thread_list.append(thread) - - # Wait for all the threads to complete and merge them in - merged_results = recommend_page_one - for thread in thread_list: - merged_results = self._merge_results(merged_results, thread.join()) - - self.determine_id_validity(merged_results["results"]) - return merged_results - - except Exception: - log.handler( - "Failed to obtain merged Similar and Recommended!", - log.ERROR, - _logger, - ) - return None - - def collections(self, collection_id): - """Obtains items in the movie collection of a given TMDB Collection ID. - - Args: - collection_id: An Integer or String containing the TMDB Collection ID. - """ - try: - return self._set_content_attributes( - "movie", - cache.handler( - "get collection by id", - page_key=collection_id, - function=tmdb.Collections(collection_id).info, - cache_duration=COLLECTION_CACHE_TIMEOUT, - ), - ) - - except Exception: - log.handler( - "Failed to obtain collection with ID " + str(collection_id) + "!", - log.ERROR, - _logger, - ) - return None - - def person(self, person_id): - """Obtain a person given a TMDB person ID. - - Args: - id: An Integer or String containing the TMDB ID. - """ - return self._set_content_attributes( - None, - cache.handler( - "person", - page_key=person_id, - function=tmdb.People(person_id).info, - cache_duration=PERSON_CACHE_TIMEOUT, - kwargs={"append_to_response": "tv_credits,movie_credits"}, - ), - ) - - def get_by_tmdb_id(self, tmdb_id, content_type, obtain_extras=True): - """Obtains a movie or series given a TMDB ID. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - """ - # Searches for content based on TMDB ID - try: - # Obtain extras if needed - if obtain_extras: - extras = "reviews,keywords,videos,credits,images" - else: - extras = None - - # Obtain a movie by ID - if content_type == "movie": - return self._set_content_attributes( - content_type, - cache.handler( - "get movie by tmdb id", - page_key=tmdb_id, - function=tmdb.Movies(tmdb_id).info, - cache_duration=GET_BY_TMDB_ID_CACHE_TIMEOUT, - kwargs={"append_to_response": extras}, - ), - ) - - # Obtain a TV show by ID - if content_type == "tv": - return self._set_content_attributes( - content_type, - cache.handler( - "get tv by tmdb id", - page_key=tmdb_id, - function=tmdb.TV(tmdb_id).info, - cache_duration=GET_BY_TMDB_ID_CACHE_TIMEOUT, - kwargs={"append_to_response": extras}, - ), - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in get_by_id().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to obtain content by ID!", - log.ERROR, - _logger, - ) - return None - - def get_by_tvdb_id(self, tvdb_id): - """Get a show or list of shows on TMDB through a TVDB ID. - - Args: - id: An Integer or String containing the TVDB ID. - """ - try: - results = cache.handler( - "get tv by tvdb id", - page_key=tvdb_id, - function=tmdb.Find(tvdb_id).info, - cache_duration=GET_BY_TVDB_ID_CACHE_TIMEOUT, - kwargs={"external_source": "tvdb_id"}, - ) - self._set_content_attributes("tv", results["tv_results"]) - return results - except Exception: - log.handler( - "Failed to obtain content with TVDB ID " + str(tvdb_id) + "!", - log.ERROR, - _logger, - ) - return None - - # Cached or Threaded Functions - def __all(self, page_number, page_multiplier): - """Cacheable part of all()""" - # Merge popular_movies, popular_tv, top_movies, and top_tv results together - function_list = [ - self.popular_movies, - self.popular_tv, - self.top_movies, - self.top_tv, - ] - results = threaded_execution(function_list, [page_number, page_multiplier]) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def __tv(self, page_number, page_multiplier): - """Cacheable part of tv()""" - # Merge popular_tv and top_tv results together - function_list = [self.popular_tv, self.top_tv] - results = threaded_execution(function_list, [page_number, page_multiplier]) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def __movies(self, page_number, page_multiplier): - """Cacheable part of movies()""" - # Merge popular_movies and top_movies results together - function_list = [self.popular_movies, self.top_movies] - results = threaded_execution(function_list, [page_number, page_multiplier]) - - # Shuffle the results on each page - return self._shuffle_results(self._merge_results(*results)) - - def __recommended(self, tmdb_id, content_type, page_number): - """Obtains recommendations given a TMDB ID. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - page_number: An Integer that is the page number to return. - """ - try: - if content_type == "movie": - return self._set_content_attributes( - content_type, - cache.handler( - "discover recommended movies", - page_key=str(tmdb_id) + "page" + str(page_number), - function=tmdb.Movies(tmdb_id).recommendations, - cache_duration=RECOMMENDED_CACHE_TIMEOUT, - kwargs={ - "language": LANGUAGE, - "page": page_number, - }, - ), - ) - - if content_type == "tv": - return self._set_content_attributes( - content_type, - cache.handler( - "discover recommended tv", - page_key=str(tmdb_id) + "page" + str(page_number), - function=tmdb.TV(tmdb_id).recommendations, - cache_duration=RECOMMENDED_CACHE_TIMEOUT, - kwargs={ - "language": LANGUAGE, - "page": page_number, - }, - ), - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in recommend().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to obtain recommendations!", - log.ERROR, - _logger, - ) - return None - - def __similar(self, tmdb_id, content_type, page_number): - """Obtains similar content given a TMDB ID. - - Args: - id: An Integer or String containing the TMDB ID. - content_type: String containing "movie" or "tv". - page_number: An Integer that is the page number to return. - """ - try: - if content_type == "movie": - return self._set_content_attributes( - content_type, - cache.handler( - "discover similar movies", - page_key=str(tmdb_id) + "page" + str(page_number), - function=tmdb.Movies(tmdb_id).similar_movies, - cache_duration=SIMILAR_CACHE_TIMEOUT, - kwargs={ - "language": LANGUAGE, - "page": page_number, - }, - ), - ) - - if content_type == "tv": - return self._set_content_attributes( - content_type, - cache.handler( - "discover similar tv", - page_key=str(tmdb_id) + "page" + str(page_number), - function=tmdb.TV(tmdb_id).similar, - cache_duration=SIMILAR_CACHE_TIMEOUT, - kwargs={ - "language": LANGUAGE, - "page": page_number, - }, - ), - ) - - # Content Type was invalid - log.handler( - "Invalid content_type " + str(content_type) + " in similar().", - log.WARNING, - _logger, - ) - - except Exception: - log.handler( - "Failed to obtain similar content!", - log.ERROR, - _logger, - ) - return None diff --git a/conreq/core/tmdb/preset_filters.py b/conreq/core/tmdb/preset_filters.py deleted file mode 100644 index 06b01812..00000000 --- a/conreq/core/tmdb/preset_filters.py +++ /dev/null @@ -1,209 +0,0 @@ -from datetime import datetime, timedelta - -from django.utils.text import slugify - -no_anime_values = { - "overwrite:with_original_language": "en", - "without_keywords": "210024", -} -anime_only_values = { - "overwrite:with_original_language": "ja", - "with_keywords": "210024", -} - - -def add_filter_values(new_values, current_filter): - """Combines values from one filter dict into another.""" - for key, value in new_values.items(): - if key.startswith("overwrite:"): - current_filter[key.replace("overwrite:", "")] = value - - elif current_filter.__contains__(key): - current_filter[key] = current_filter[key] + "," + value - - else: - current_filter[key] = value - - -def preprocess_filters(preset_filters, slug, add_values): - """Do any preprocessing needed on the filters""" - processed_filters = {} - - for key in preset_filters: - # Add any filter values needed - if add_values: - add_filter_values(add_values, preset_filters[key]) - - # Slugify all filter names - if slug: - processed_filters[slugify(key)] = preset_filters[key] - - if processed_filters: - return processed_filters - return preset_filters - - -def combined_filters(filter_name=None, slug=False, add_values=()): - """These filters are automatically merged into TV and Movies.""" - today = datetime.today() - preset_filters = { - "new and loved": { - "sort_by": "vote_average.desc", - "vote_count.gte": "25", - "first_air_date.gte": (today - timedelta(days=365)).strftime(r"%Y-%m-%d"), - "first_air_date.lte": today.strftime(r"%Y-%m-%d"), - "primary_release_date.gte": (today - timedelta(days=365)).strftime( - r"%Y-%m-%d" - ), - "primary_release_date.lte": today.strftime(r"%Y-%m-%d"), - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "all time favorite": { - "sort_by": "vote_average.desc", - "vote_count.gte": "300", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "coming soon": { - "sort_by": "popularity.desc", - "first_air_date.gte": today.strftime(r"%Y-%m-%d"), - "first_air_date.lte": (today + timedelta(days=365)).strftime(r"%Y-%m-%d"), - "primary_release_date.gte": today.strftime(r"%Y-%m-%d"), - "primary_release_date.lte": (today + timedelta(days=365)).strftime( - r"%Y-%m-%d" - ), - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "top rated": { - "sort_by": "vote_average.desc", - "vote_count.gte": "50", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "popular": { - "sort_by": "popularity.desc", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "family friendly": { - "sort_by": "popularity.desc", - "with_genres": "10751|10762", - "without_genres": "27,53,99,18", - "with_original_language": "en|ja", - }, - "action and adventure": { - "sort_by": "popularity.desc", - "with_genres": "10759|28|12", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "science fiction and fantasy": { - "sort_by": "popularity.desc", - "with_genres": "10765|878|14", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "drama": { - "sort_by": "popularity.desc", - "with_genres": "18", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "mystery": { - "sort_by": "popularity.desc", - "with_genres": "9648", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "crime": { - "sort_by": "popularity.desc", - "with_genres": "80", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "comedy": { - "sort_by": "popularity.desc", - "with_genres": "35", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "western": { - "sort_by": "popularity.desc", - "with_genres": "37", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - "documentary": { - "sort_by": "popularity.desc", - "with_genres": "99", - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - } - - preset_filters = preprocess_filters(preset_filters, slug, add_values) - - if filter_name: - return preset_filters[filter_name] - return preset_filters - - -def tv_filters(filter_name=None, slug=False, add_values=()): - """Predefined categories shown for the TV filter modal.""" - today = datetime.today() - preset_filters = { - "currently ongoing": { - "sort_by": "popularity.desc", - "air_date.gte": (today - timedelta(days=7)).strftime(r"%Y-%m-%d"), - "air_date.lte": today.strftime(r"%Y-%m-%d"), - "without_genres": "10751|10762|10763", # No kids shows or news - "with_original_language": "en|ja", - }, - "airing today": { - "sort_by": "popularity.desc", - "air_date.gte": today.strftime(r"%Y-%m-%d"), - "air_date.lte": today.strftime(r"%Y-%m-%d"), - "without_genres": "10751|10762|10763", # No kids shows or news - "with_original_language": "en|ja", - }, - } - - preset_filters = preprocess_filters(preset_filters, slug, add_values) - - preset_filters = { - **preset_filters, - **combined_filters(slug=slug, add_values=add_values), - } - - if filter_name: - return preset_filters[filter_name] - return preset_filters - - -def movie_filters(filter_name=None, slug=False, add_values=()): - """Predefined categories shown in the movie filter modal.""" - today = datetime.today() - preset_filters = { - "in theaters": { - "sort_by": "popularity.desc", - "with_release_type": "2|3", - "primary_release_date.gte": (today - timedelta(days=150)).strftime( - r"%Y-%m-%d" - ), - "without_genres": "10751|10762", # No kids shows - "with_original_language": "en|ja", - }, - } - - preset_filters = preprocess_filters(preset_filters, slug, add_values) - - preset_filters = { - **preset_filters, - **combined_filters(slug=slug, add_values=add_values), - } - - if filter_name: - return preset_filters[filter_name] - return preset_filters diff --git a/conreq/core/tmdb/search.py b/conreq/core/tmdb/search.py deleted file mode 100644 index 758f15db..00000000 --- a/conreq/core/tmdb/search.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Conreq Searching: Searches for content.""" - -import tmdbsimple as tmdb - -from conreq.core.server_settings.models import ConreqConfig -from conreq.core.tmdb.base import LANGUAGE, TmdbBase -from conreq.utils import cache, log - -_logger = log.get_logger(__name__) - -# Days, Hours, Minutes, Seconds -SEARCH_CACHE_TIMEOUT = 3 * 60 * 60 - - -class TmdbSearch(TmdbBase): - """Searches for a given query""" - - def __init__(self): - # Database values - self.conreq_config = ConreqConfig.get_solo() - - def all(self, query, page_number): - """Search for a query. Sort the - results based on their similiarity to the query. - - Args: - query: A string containing a search term. - """ - try: - results = self._remove_bad_content_types( - self._set_content_attributes( - None, - cache.handler( - "search all", - page_key=page_number, - function=tmdb.Search().multi, - cache_duration=SEARCH_CACHE_TIMEOUT, - kwargs={ - "page": page_number, - "query": query, - "language": LANGUAGE, - }, - ), - ) - ) - return results - - except Exception: - log.handler( - "Searching for all failed!", - log.ERROR, - _logger, - ) - return [] - - def television(self, query, page_number): - """Search Sonarr for a query. - - Args: - query: A string containing a search term. - conreq_rank: Calculate conreq similarity ranking and sort the results (True/False) - """ - try: - results = self._set_content_attributes( - "tv", - cache.handler( - "search tv", - page_key=page_number, - function=tmdb.Search().tv, - cache_duration=SEARCH_CACHE_TIMEOUT, - kwargs={ - "page": page_number, - "query": query, - "language": LANGUAGE, - }, - ), - ) - return results - - except Exception: - log.handler( - "Searching for TV failed!", - log.ERROR, - _logger, - ) - return [] - - def movie(self, query, page_number): - """Search Radarr for a query. - - Args: - query: A string containing a search term. - """ - try: - results = self._set_content_attributes( - "movie", - cache.handler( - "search movie", - page_key=page_number, - function=tmdb.Search().movie, - cache_duration=SEARCH_CACHE_TIMEOUT, - kwargs={ - "page": page_number, - "query": query, - "language": LANGUAGE, - }, - ), - ) - return results - - except Exception: - log.handler( - "Searching for movies failed!", - log.ERROR, - _logger, - ) - return [] diff --git a/conreq/core/tmdb/templates/cards/artwork.html b/conreq/core/tmdb/templates/cards/artwork.html deleted file mode 100644 index 24cb4205..00000000 --- a/conreq/core/tmdb/templates/cards/artwork.html +++ /dev/null @@ -1,8 +0,0 @@ -{% load static %} - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/cards/casted.html b/conreq/core/tmdb/templates/cards/casted.html deleted file mode 100644 index 0257e7f4..00000000 --- a/conreq/core/tmdb/templates/cards/casted.html +++ /dev/null @@ -1,54 +0,0 @@ -{% load static %} -{% load conreq_tags %} -
- - - - - {% if card.requested_by and user.is_staff %} -
- {{ card.requested_by }} -
- {% endif %} - -
- {% if card.content_type == "tv" %} - - {% elif card.content_type == "movie" %} - - {% endif %} -
- -
- {% if card.poster_path %} - {% firstof card.name card.title 'Unknown' %} - {% else %} - {% firstof card.name card.title 'Unknown' %} - {% endif %} -
-
- - - - - -
-
-
{% firstof card.name card.title "Unknown" %}
- {% if card.availability == "Available" %} -
- {% elif card.availability == "Partial" %} -
- {% else %} -
- {% endif %} -
{% firstof card.character card.job card.department "Unknown Role"%} -
-
- -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/cards/issue.html b/conreq/core/tmdb/templates/cards/issue.html deleted file mode 100644 index 6b99cd5a..00000000 --- a/conreq/core/tmdb/templates/cards/issue.html +++ /dev/null @@ -1,82 +0,0 @@ -{% load conreq_tags %} -
- -
- {% if card.content_type == "tv" %} - - {% elif card.content_type == "movie" %} - - {% endif %} -
- -
- {% if card.resolved and user.is_staff %} - - {% elif user.is_staff %} - - {% endif %} - -
- - - -
-
Issue{{ card.issues|pluralize:",s" }}
- {% for issue in card.issues %} - {{ issue }} - {% endfor %} -
- - {% if card.seasons %} -
-
Season{{ card.seasons|pluralize:",s" }}
- {{ card.seasons|join:", " }} -
- {% endif %} - - {% if card.episodes %} -
-
Episode{{ card.episodes|pluralize:",s" }}
- {{ card.episodes|join:", " }} -
- {% endif %} - -
-
Reported By
-
- {{ card.reported_by__username }} -
-
- -
-
Date Reported
-
- {{ card.date_reported }} -
-
- -
-
Resolved - {% if card.resolved %} -
- {% else %} -
- {% endif %} -
- {% if card.resolved and card.auto_resolved %} - Yes (Auto) - {% elif card.auto_resolve_in_progress and not card.resolved and not card.auto_resolved %} - No (Auto) - {% else %} - {{ card.resolved|yesno:"Yes,No" }} - {% endif %} -
- -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/cards/person.html b/conreq/core/tmdb/templates/cards/person.html deleted file mode 100644 index 2934d69e..00000000 --- a/conreq/core/tmdb/templates/cards/person.html +++ /dev/null @@ -1,17 +0,0 @@ -{% load static %} -{% load conreq_tags %} - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/cards/poster.html b/conreq/core/tmdb/templates/cards/poster.html deleted file mode 100644 index cad49a3c..00000000 --- a/conreq/core/tmdb/templates/cards/poster.html +++ /dev/null @@ -1,48 +0,0 @@ -{% load static %} -{% load conreq_tags %} -
- - - - - {% if card.requested_by and user.is_staff %} -
- {{ card.requested_by }} -
- {% endif %} - -
- {% if card.content_type == "tv" %} - - {% elif card.content_type == "movie" %} - - {% endif %} -
- -
- {% firstof card.name card.title 'Unknown' %} -
-
- - - - - -
-
-
{% firstof card.name card.title "Unknown" %}
- {% if card.availability == "Available" %} -
- {% elif card.availability == "Partial" %} -
- {% else %} -
- {% endif %} -
{{card.overview}}
-
- -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/cards/review.html b/conreq/core/tmdb/templates/cards/review.html deleted file mode 100644 index ac904ed8..00000000 --- a/conreq/core/tmdb/templates/cards/review.html +++ /dev/null @@ -1,10 +0,0 @@ -
-
-
-
"
- {{review.content}} -
"
-
-
- {{review.author}}
-
-
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/compressed/simple_posters_css.html b/conreq/core/tmdb/templates/compressed/simple_posters_css.html deleted file mode 100644 index 32cf6f80..00000000 --- a/conreq/core/tmdb/templates/compressed/simple_posters_css.html +++ /dev/null @@ -1,5 +0,0 @@ -{% load static compress %} -{% load static %} -{% compress css %} - -{% endcompress %} \ No newline at end of file diff --git a/conreq/core/tmdb/templates/dropdown/item.html b/conreq/core/tmdb/templates/dropdown/item.html deleted file mode 100644 index 6c7bdf10..00000000 --- a/conreq/core/tmdb/templates/dropdown/item.html +++ /dev/null @@ -1 +0,0 @@ -{{ dropdown_item.label }} \ No newline at end of file diff --git a/conreq/core/tmdb/templates/modal/content_preview.html b/conreq/core/tmdb/templates/modal/content_preview.html deleted file mode 100644 index cd70ff02..00000000 --- a/conreq/core/tmdb/templates/modal/content_preview.html +++ /dev/null @@ -1,127 +0,0 @@ -{% load solo_tags %} -{% load conreq_tags %} -{% load static %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} - -{% include "primary/loading_animation.html" %} - - - - -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/modal/discover_filter_simple.html b/conreq/core/tmdb/templates/modal/discover_filter_simple.html deleted file mode 100644 index ef718768..00000000 --- a/conreq/core/tmdb/templates/modal/discover_filter_simple.html +++ /dev/null @@ -1,55 +0,0 @@ -{% include "primary/loading_animation.html" %} - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/modal/report_issue.html b/conreq/core/tmdb/templates/modal/report_issue.html deleted file mode 100644 index 98fddbe1..00000000 --- a/conreq/core/tmdb/templates/modal/report_issue.html +++ /dev/null @@ -1,38 +0,0 @@ -{% include "primary/loading_animation.html" %} - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/modal/series_selection.html b/conreq/core/tmdb/templates/modal/series_selection.html deleted file mode 100644 index 1ca1a662..00000000 --- a/conreq/core/tmdb/templates/modal/series_selection.html +++ /dev/null @@ -1,142 +0,0 @@ -{% load solo_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} - -{% include "primary/loading_animation.html" %} - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/components/more_info_collection.html b/conreq/core/tmdb/templates/viewport/components/more_info_collection.html deleted file mode 100644 index c905d9e7..00000000 --- a/conreq/core/tmdb/templates/viewport/components/more_info_collection.html +++ /dev/null @@ -1,21 +0,0 @@ -{% if collection.parts %} - -{% endif %} \ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/components/more_info_recommended.html b/conreq/core/tmdb/templates/viewport/components/more_info_recommended.html deleted file mode 100644 index 42594a3b..00000000 --- a/conreq/core/tmdb/templates/viewport/components/more_info_recommended.html +++ /dev/null @@ -1,23 +0,0 @@ -{% if recommended.results and results_contain_valid_id %} - -{% endif %} \ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/components/server_settings_radarr.html b/conreq/core/tmdb/templates/viewport/components/server_settings_radarr.html deleted file mode 100644 index 76b4fad4..00000000 --- a/conreq/core/tmdb/templates/viewport/components/server_settings_radarr.html +++ /dev/null @@ -1,89 +0,0 @@ -
-
Anime Quality Profile
- -
-
-
Movie Quality Profile
- -
-
-
Anime Folder Path
- -
- -
-
Movie Folder Path
- -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/components/server_settings_sonarr.html b/conreq/core/tmdb/templates/viewport/components/server_settings_sonarr.html deleted file mode 100644 index 1495b5f4..00000000 --- a/conreq/core/tmdb/templates/viewport/components/server_settings_sonarr.html +++ /dev/null @@ -1,88 +0,0 @@ -
-
Anime Quality Profile
- -
-
-
TV Quality Profile
- -
-
-
Anime Folder Path
- -
-
-
TV Folder Path
- -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/discover.html b/conreq/core/tmdb/templates/viewport/discover.html deleted file mode 100644 index 39d4de5f..00000000 --- a/conreq/core/tmdb/templates/viewport/discover.html +++ /dev/null @@ -1,19 +0,0 @@ -{% load static %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} -{% include "primary/searchbar.html" %} - - -
- {% if not all_cards %} -
- No results were found! -
- {% endif %} - - {% for card in all_cards %} - {% if card.conreq_valid_id %} - {% include "cards/poster.html" %} - {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/manage_users.html b/conreq/core/tmdb/templates/viewport/manage_users.html deleted file mode 100644 index 1e7c71c4..00000000 --- a/conreq/core/tmdb/templates/viewport/manage_users.html +++ /dev/null @@ -1,52 +0,0 @@ -{% load static %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
-
-
-
-

User Management

-
- - Invite -
-
-
- - - - - - - - - - - - - {% for account in users %} - - - - - - - - - {% endfor %} - - -
UsernameJoinedLast SeenStaff
{{ account.username }}{{ account.date_joined|date:"Y-m-d @ H:i" }}{{ account.last_login|date:"Y-m-d @ H:i" }}{{ account.is_staff|yesno:"Yes,No" }} -
- -
-
- -
-
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/more_info.html b/conreq/core/tmdb/templates/viewport/more_info.html deleted file mode 100644 index 6c0de57d..00000000 --- a/conreq/core/tmdb/templates/viewport/more_info.html +++ /dev/null @@ -1,458 +0,0 @@ -{% load static %} -{% load conreq_tags %} -{% load solo_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
-
- -
- -
- {% firstof content.title content.name 'Unknown' %} -
-
- -
-
- -
{% firstof content.title content.name "Unknown" %}
-
-
SCORE:
-
- {% firstof content.vote_average "-" %} / 10
-
- - - {% if content.availability == "Available" %} - {% if content_type == "movie" and server_settings.radarr_enabled %} -
AVAILABLE
- {% elif content_type == "tv" and server_settings.sonarr_enabled %} -
- - VIEW EPISODES -
- {% endif %} - - - {% elif content.availability != "Available" %} - {% if content_type == "movie" and server_settings.radarr_enabled %} -
- - REQUEST -
- {% elif content_type == "tv" and server_settings.sonarr_enabled %} -
- - REQUEST -
- {% endif %} - {% endif %} - - - {% if content_type == "movie" and server_settings.radarr_enabled %} -
- - ISSUE -
- {% elif content_type == "tv" and server_settings.sonarr_enabled %} -
- - ISSUE -
- {% endif%} - -
- -
-
-
Overview
- {% firstof content.overview "No summary available."%} -
-
- -
-
- - -
-
- {% if content.original_name and content.original_name != content.name %} -
-
Original Name
-
{{content.original_name}}
-
- {% endif %} - - -
-
Availabity
-
- {% if content.availability == "Available" %} Available -
- {% elif content.availability == "Partial" %} Partial -
- {% else %} Not Downloaded -
- {% endif %} -
-
- - -
-
Requested
-
-
- {{ requested|yesno:"Yes,No" }} -
-
-
- - - {% if content.status %} -
-
Release Status
-
{{content.status}}
-
- {% endif %} - - -
-
Content Type
- {% if content_type == "movie" %} - -
- Movie -
-
- {% elif content_type == "tv" %} - -
- Television -
-
- {% endif %} -
- - - {% if content.genres %} -
-
Genres
-
- {% for genre in content.genres %} - {% if content_type == "movie" %} - -
{{ genre.name }}
-
- {% elif content_type == "tv" %} - -
{{ genre.name }}
-
- {% endif %} - {% endfor %} -
-
- {% endif %} - - - {% if content.year %} -
-
Year
-
{{content.year}}
-
- {% endif %} - - - {% if content.first_air_date_formatted %} -
-
First Aired
-
{{content.first_air_date_formatted}}
-
- {% endif %} - - - {% if content.last_air_date_formatted %} -
-
Last Aired
-
{{content.last_air_date_formatted}}
-
- {% endif %} - - - {% if content.next_air_date_formatted %} -
-
Next Airing
-
{{content.next_air_date_formatted}}
-
- {% endif %} - - - {% if content.release_date_formatted %} -
-
Release Date
-
{{content.release_date_formatted}}
-
- {% endif %} - - - {% if content.spoken_languages %} -
-
Languages
-
- {% for language in content.spoken_languages %} - {% if content_type == "movie" %} - -
- {% firstof language.english_name language.name %} -
-
- {% elif content_type == "tv" %} - -
- {% firstof language.english_name language.name %} -
-
- {% endif %} - {% endfor %} -
-
- {% endif %} - - - {% if content.runtime %} -
-
Runtime
-
{{content.runtime}}
-
- {% endif %} - - - {% if content.budget %} -
-
Budget
-
${{content.budget}}
-
- {% endif %} - - - {% if content.revenue %} -
-
Revenue
-
${{content.revenue}}
-
- {% endif %} - - - {% if content.production_companies %} -
-
Production Companies
-
- {% for company in content.production_companies %} - {% if content_type == "tv" %} - -
{{company.name}}
-
- {% elif content_type == "movie" %} - -
{{company.name}}
-
- {% endif %} - {% endfor %} -
-
- {% endif %} - - - {% if content.networks %} -
-
Networks
-
- {% for network in content.networks %} - -
- {% firstof network.name %} -
-
- {% endfor %} -
-
- {% endif %} - - - {% if content.keywords.results or content.keywords.keywords %} -
-
Tags
-
- - {% if content.keywords.results %} - {% for keyword in content.keywords.results %} - -
{{keyword.name}}
-
- {% endfor %} - - - {% elif content.keywords.keywords %} - {% for keyword in content.keywords.keywords %} - -
{{keyword.name}}
-
- {% endfor %} - {% endif %} -
-
- {% endif %} - -
- - -
- MORE DETAILS -
-
- - - {% if content.videos.results %} - - {% endif %} - - - {% if collection_id %} -
-
- {% endif %} - - -
-
- - - {% if content.credits.cast %} - - {% endif %} - - - {% if content.credits.crew %} - - {% endif %} - - - {% if content.images.backdrops %} - - {% endif %} - - - {% if content.reviews.results %} - - {% endif %} - -
- - -
-
- -
-
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/person.html b/conreq/core/tmdb/templates/viewport/person.html deleted file mode 100644 index 452e2504..00000000 --- a/conreq/core/tmdb/templates/viewport/person.html +++ /dev/null @@ -1,213 +0,0 @@ -{% load static %} -{% load conreq_tags %} -{% load solo_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
-
- -
- -
- {% firstof person.name 'Unknown' %} -
-
- -
-
- -
{% firstof person.name "Unknown" %}
-
-
POPULARITY:
-
- {% firstof person.popularity "-" %}
-
- -
- - -
-
-
Biography
- {% firstof person.biography "No biography available."%} -
-
- -
-
- - -
-
- - - {% if person.release_date_formatted %} -
-
Release Date
-
{{person.release_date_formatted}}
-
- {% endif %} - - - {% if person.known_for_department %} -
-
Department
-
{{person.known_for_department}}
-
- {% endif %} - - - - {% if person.gender %} -
-
Gender
-
- {% if person.gender == 1 %} - Female - {% elif person.gender == 2 %} - Male - {% else %} - Other - {% endif %} -
-
- {% endif %} - - - {% if person.place_of_birth %} -
-
Birth Place
-
{{person.place_of_birth}}
-
- {% endif %} - - - {% if person.birthday_formatted %} -
-
Birthday
-
{{person.birthday_formatted}}
-
- {% endif %} - - - {% if person.deathday_formatted %} -
-
Died
-
{{person.deathday_formatted}}
-
- {% endif %} - -
- -
- - - {% if person.tv_credits.cast and tv_cast_contain_valid_id %} - - {% endif %} - - - {% if person.movie_credits.cast %} - - {% endif %} - - - {% if person.tv_credits.crew and tv_crew_contain_valid_id %} - - {% endif %} - - - {% if person.movie_credits.crew %} - - {% endif %} - -
- - -
-
-
-
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/reported_issues.html b/conreq/core/tmdb/templates/viewport/reported_issues.html deleted file mode 100644 index 7e360a22..00000000 --- a/conreq/core/tmdb/templates/viewport/reported_issues.html +++ /dev/null @@ -1,18 +0,0 @@ -{% load static %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
- {% if not all_cards %} -
- No issues were found! Try reporting something first! -
- {% endif %} - - {% if all_cards %} - {% for card in all_cards %} - {% include "cards/issue.html" %} - {% endfor %} - {% endif %} -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/requests.html b/conreq/core/tmdb/templates/viewport/requests.html deleted file mode 100644 index 7fe9afc9..00000000 --- a/conreq/core/tmdb/templates/viewport/requests.html +++ /dev/null @@ -1,18 +0,0 @@ -{% load static %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
- {% if not all_cards %} -
- No requests were found! Try requesting something first! -
- {% endif %} - - {% for card in all_cards %} - {% if card %} - {% include "cards/poster.html" %} - {% endif %} - {% endfor %} -
\ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/search.html b/conreq/core/tmdb/templates/viewport/search.html deleted file mode 100644 index e2bf749d..00000000 --- a/conreq/core/tmdb/templates/viewport/search.html +++ /dev/null @@ -1,23 +0,0 @@ -{% load static %} -{% load solo_tags %} -{% load conreq_tags %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} -{% include "primary/searchbar.html" %} - - - \ No newline at end of file diff --git a/conreq/core/tmdb/templates/viewport/server_settings.html b/conreq/core/tmdb/templates/viewport/server_settings.html deleted file mode 100644 index 68448c40..00000000 --- a/conreq/core/tmdb/templates/viewport/server_settings.html +++ /dev/null @@ -1,185 +0,0 @@ -{% load solo_tags %} -{% load static %} -{% get_solo 'server_settings.ConreqConfig' as server_settings %} -{% csrf_token %} -{% include "primary/loading_animation_container.html" %} - - -
- -
-
Basic Configuration
-
-
-
API Key
-
-
-
- Under Development -
-
-
-
-
-
Custom CSS
-
- -
-
-
-
Custom JavaScript
-
- -
-
-
-
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- - -
-
Sonarr Configuration
-
-
-
URL
-
- -
-
-
-
API Key
-
- -
-
- {% if server_settings.sonarr_enabled %} -
- Loading... -
- {% endif %} -
- -
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- - -
-
Radarr Configuration
-
-
-
URL
-
- -
-
-
-
API Key
-
- -
-
- - {% if server_settings.radarr_enabled %} -
- Loading... -
- {% endif %} -
- -
-
-
- -
- -
-
-
-
-
- - -
-
About Conreq
-
-
-
System Information
-
{{ os_platform }}
-
-
-
Version
-
{{ version }}
-
-
-
- -
\ No newline at end of file diff --git a/conreq/core/user_requests/admin.py b/conreq/core/user_requests/admin.py deleted file mode 100644 index d5143810..00000000 --- a/conreq/core/user_requests/admin.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib import admin - -from conreq.core.user_requests.models import UserRequest - - -# Register your models here. -@admin.register(UserRequest) -class AllUserRequests(admin.ModelAdmin): - pass diff --git a/conreq/core/user_requests/apps.py b/conreq/core/user_requests/apps.py deleted file mode 100644 index 1aed752b..00000000 --- a/conreq/core/user_requests/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class UserRequestsConfig(AppConfig): - name = "conreq.core.user_requests" diff --git a/conreq/core/user_requests/helpers.py b/conreq/core/user_requests/helpers.py deleted file mode 100644 index 8579ed14..00000000 --- a/conreq/core/user_requests/helpers.py +++ /dev/null @@ -1,95 +0,0 @@ -"""Helpers for User Requests""" -from django.contrib.auth.models import AnonymousUser - -from conreq.core.discover.helpers import ( - obtain_radarr_parameters, - obtain_sonarr_parameters, - set_many_availability, -) -from conreq.core.tmdb.discovery import TmdbDiscovery -from conreq.core.user_requests.models import UserRequest -from conreq.utils import log -from conreq.utils.database import add_unique_to_db -from conreq.utils.threads import threaded_execution_unique_args - -from .tasks import radarr_request_background_task, sonarr_request_background_task - -_logger = log.get_logger(__name__) - - -def sonarr_request(tvdb_id, tmdb_id, request, request_params): - """Request on Sonarr and save request history item to DB""" - sonarr_params = obtain_sonarr_parameters(tmdb_id, tvdb_id) - - # Request in the background - sonarr_request_background_task(tvdb_id, request_params, sonarr_params) - - # Save to DB - requested_by = request.user if not isinstance(request.user, AnonymousUser) else None - add_unique_to_db( - UserRequest, - content_id=tmdb_id, - content_type="tv", - requested_by=requested_by, - ) - - -def radarr_request(tmdb_id, request): - """Request on Radarr and save request history item to DB""" - radarr_params = obtain_radarr_parameters(tmdb_id) - - # Request in the background - radarr_request_background_task(tmdb_id, radarr_params) - - # Save to DB - requested_by = request.user if not isinstance(request.user, AnonymousUser) else None - add_unique_to_db( - UserRequest, - content_id=tmdb_id, - content_type="movie", - requested_by=requested_by, - ) - - -def __generate_request_card(entry, content_discovery): - """Generates a single request card. This is intended for multi-threaded use.""" - card = None - # Fetch TMDB entry - card = content_discovery.get_by_tmdb_id( - tmdb_id=entry["content_id"], - content_type=entry["content_type"], - obtain_extras=False, - ) - card["requested_by"] = entry.get("requested_by__username") - - if card is None: - log.handler( - entry["content_type"] - + " with ID " - + entry["content_id"] - + " no longer exists!", - log.WARNING, - _logger, - ) - - return card - - -def generate_requests_cards(user_requests): - """Takes in a DB query containing requests, and pops out a list of their current request status""" - content_discovery = TmdbDiscovery() - all_cards = [] - function_list = [] - for request in user_requests: - function_list.append( - { - "function": __generate_request_card, - "args": [request, content_discovery], - } - ) - - all_cards = threaded_execution_unique_args(function_list) - content_discovery.determine_id_validity(all_cards) - set_many_availability(all_cards) - - return all_cards diff --git a/conreq/core/user_requests/migrations/0001_initial.py b/conreq/core/user_requests/migrations/0001_initial.py deleted file mode 100644 index 482b40c5..00000000 --- a/conreq/core/user_requests/migrations/0001_initial.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-30 07:39 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='UserRequest', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_id', models.CharField(max_length=30)), - ('source', models.CharField(max_length=30)), - ('content_type', models.CharField(max_length=30)), - ('requested_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/conreq/core/user_requests/migrations/0002_userrequest_date_requested.py b/conreq/core/user_requests/migrations/0002_userrequest_date_requested.py deleted file mode 100644 index 69a2c3f2..00000000 --- a/conreq/core/user_requests/migrations/0002_userrequest_date_requested.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-31 09:47 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('user_requests', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='userrequest', - name='date_requested', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), - preserve_default=False, - ), - ] diff --git a/conreq/core/user_requests/migrations/0003_alter_userrequest_id.py b/conreq/core/user_requests/migrations/0003_alter_userrequest_id.py deleted file mode 100644 index 3257db0f..00000000 --- a/conreq/core/user_requests/migrations/0003_alter_userrequest_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2 on 2021-04-13 05:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('user_requests', '0002_userrequest_date_requested'), - ] - - operations = [ - migrations.AlterField( - model_name='userrequest', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - ] diff --git a/conreq/core/user_requests/migrations/0004_alter_userrequest_requested_by.py b/conreq/core/user_requests/migrations/0004_alter_userrequest_requested_by.py deleted file mode 100644 index 09dbb585..00000000 --- a/conreq/core/user_requests/migrations/0004_alter_userrequest_requested_by.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.2 on 2021-05-09 02:37 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('user_requests', '0003_alter_userrequest_id'), - ] - - operations = [ - migrations.AlterField( - model_name='userrequest', - name='requested_by', - field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/conreq/core/user_requests/migrations/0005_remove_userrequest_source.py b/conreq/core/user_requests/migrations/0005_remove_userrequest_source.py deleted file mode 100644 index fd61f048..00000000 --- a/conreq/core/user_requests/migrations/0005_remove_userrequest_source.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-06 06:44 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('user_requests', '0004_alter_userrequest_requested_by'), - ] - - operations = [ - migrations.RemoveField( - model_name='userrequest', - name='source', - ), - ] diff --git a/conreq/core/user_requests/models.py b/conreq/core/user_requests/models.py deleted file mode 100644 index 371bac8d..00000000 --- a/conreq/core/user_requests/models.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.contrib.auth import get_user_model -from django.db import models - -User = get_user_model() - -# Create your models here. -class UserRequest(models.Model): - content_id = models.CharField(max_length=30) - content_type = models.CharField(max_length=30) - requested_by = models.ForeignKey( - User, on_delete=models.CASCADE, default=None, null=True, blank=True - ) - date_requested = models.DateTimeField(auto_now_add=True) diff --git a/conreq/core/user_requests/tasks.py b/conreq/core/user_requests/tasks.py deleted file mode 100644 index 3ac85675..00000000 --- a/conreq/core/user_requests/tasks.py +++ /dev/null @@ -1,96 +0,0 @@ -from huey.contrib.djhuey import db_task - -from conreq.core.arrs.radarr import RadarrManager -from conreq.core.arrs.sonarr import SonarrManager -from conreq.utils import log - -_logger = log.get_logger(__name__) - - -@db_task() -def sonarr_request_background_task(tvdb_id, request_params, sonarr_params): - """Function that can be run in the background to request something on Sonarr""" - try: - sonarr_manager = SonarrManager() - # Check if the show is already within Sonarr's collection - show = sonarr_manager.get(tvdb_id=tvdb_id) - - # If it doesn't already exists, add then request it - if show is None: - show = sonarr_manager.add( - tvdb_id=tvdb_id, - quality_profile_id=sonarr_params["sonarr_profile_id"], - root_dir=sonarr_params["sonarr_root"], - series_type=sonarr_params["series_type"], - season_folders=sonarr_params["season_folders"], - ) - - # Request - sonarr_manager.request( - sonarr_id=show["id"], - seasons=request_params.get("seasons"), - episode_ids=request_params.get("episode_ids"), - ) - - log.handler( - "Requested TV series " + show["title"], - log.INFO, - _logger, - ) - except Exception: - if "show" not in locals(): - show = {"title": "Conreq Uninitialized"} - log.handler( - "\n".join( - ( - "Failed to request on Radarr!", - f"tvdb_id: {tvdb_id}", - f"request_params: {request_params}", - f"sonarr_params: {sonarr_params}", - f"show: {show}", - ) - ), - log.ERROR, - _logger, - ) - - -@db_task() -def radarr_request_background_task(tmdb_id, radarr_params): - """Function that can be run in the background to request something on Radarr""" - try: - radarr_manager = RadarrManager() - # Check if the movie is already within Radarr's collection - movie = radarr_manager.get(tmdb_id=tmdb_id) - - # If it doesn't already exists, add then request it - if movie is None: - movie = radarr_manager.add( - tmdb_id=tmdb_id, - quality_profile_id=radarr_params["radarr_profile_id"], - root_dir=radarr_params["radarr_root"], - ) - - # Request - radarr_manager.request(radarr_id=movie["id"]) - - log.handler( - "Requested movie " + movie["title"], - log.INFO, - _logger, - ) - except Exception: - if "movie" not in locals(): - movie = {"title": "Conreq Uninitialized"} - log.handler( - "\n".join( - ( - "Failed to request on Radarr!", - f"tmdb_id: {tmdb_id}", - f"radarr_params: {radarr_params}", - f"movie: {movie}", - ) - ), - log.ERROR, - _logger, - ) diff --git a/conreq/core/user_requests/urls.py b/conreq/core/user_requests/urls.py deleted file mode 100644 index 44f0b7a4..00000000 --- a/conreq/core/user_requests/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "user_requests" -urlpatterns = [ - path("", views.request_content, name="request_content"), - path("my_requests/", views.my_requests, name="my_requests"), - path("all_requests/", views.all_requests, name="all_requests"), -] diff --git a/conreq/core/user_requests/views.py b/conreq/core/user_requests/views.py deleted file mode 100644 index 489efedb..00000000 --- a/conreq/core/user_requests/views.py +++ /dev/null @@ -1,110 +0,0 @@ -import json - -from django.contrib.auth.decorators import login_required -from django.core.paginator import Paginator -from django.http import HttpResponse, HttpResponseForbidden, JsonResponse -from django.template import loader -from django.views.decorators.cache import cache_page -from django.views.decorators.vary import vary_on_cookie - -from conreq.core.tmdb.discovery import TmdbDiscovery -from conreq.core.user_requests.models import UserRequest -from conreq.utils import log -from conreq.utils.debug import performance_metrics - -from .helpers import generate_requests_cards, radarr_request, sonarr_request - -_logger = log.get_logger(__name__) - -# Days, Hours, Minutes, Seconds -INVITE_CODE_DURATION = 7 * 24 * 60 * 60 - - -@login_required -@performance_metrics() -def request_content(request): - # User submitted a new request - if request.method == "POST": - request_parameters = json.loads(request.body.decode("utf-8")) - log.handler( - "Request received: " + str(request_parameters), - log.INFO, - _logger, - ) - - # TV show was requested - if request_parameters["content_type"] == "tv": - # Try to obtain a TVDB ID (from params or fetch it from TMDB) - tmdb_id = request_parameters["tmdb_id"] - tvdb_id = TmdbDiscovery().get_external_ids(tmdb_id, "tv").get("tvdb_id") - - # Request the show by the TVDB ID - if tvdb_id: - sonarr_request( - tvdb_id, - tmdb_id, - request, - request_parameters, - ) - - else: - return HttpResponseForbidden() - - # Movie was requested - elif request_parameters["content_type"] == "movie": - tmdb_id = request_parameters["tmdb_id"] - radarr_request(tmdb_id, request) - - # The request succeeded - return JsonResponse({"success": True}) - - return HttpResponseForbidden() - - -@cache_page(1) -@vary_on_cookie -@login_required -@performance_metrics() -def my_requests(request): - user_requests = ( - UserRequest.objects.filter(requested_by=request.user) - .order_by("id") - .reverse() - .values() - ) - page_number = int(request.GET.get("page", 1)) - paginator = Paginator(user_requests, 25) - page_obj = paginator.get_page(page_number) - if page_number <= paginator.num_pages: - all_cards = generate_requests_cards(page_obj) - else: - all_cards = None - context = {"all_cards": all_cards, "page_name": "My Requests"} - template = loader.get_template("viewport/requests.html") - return HttpResponse(template.render(context, request)) - - -@cache_page(1) -@login_required -@performance_metrics() -def all_requests(request): - user_requests = ( - UserRequest.objects.all() - .order_by("id") - .reverse() - .values( - "content_id", - "content_type", - "requested_by__username", - ) - ) - page_number = int(request.GET.get("page", 1)) - paginator = Paginator(user_requests, 25) - page_obj = paginator.get_page(page_number) - if page_number <= paginator.num_pages: - all_cards = generate_requests_cards(page_obj) - else: - all_cards = None - context = {"all_cards": all_cards, "page_name": "All Requests"} - template = loader.get_template("viewport/requests.html") - return HttpResponse(template.render(context, request)) diff --git a/conreq/core/websockets/consumers.py b/conreq/core/websockets/consumers.py deleted file mode 100644 index 541e3898..00000000 --- a/conreq/core/websockets/consumers.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Anything used to construct a websocket endpoint""" -from channels.auth import login -from channels.db import database_sync_to_async as convert_to_async -from channels.generic.websocket import AsyncJsonWebsocketConsumer -from django.contrib.auth.models import AnonymousUser - -from conreq.utils import log - -_logger = log.get_logger(__name__) - - -class CommandConsumer(AsyncJsonWebsocketConsumer): - """Conreq websocket communication.""" - - # INITIAL CONNECTION - async def connect(self): - """When the browser attempts to connect to the server.""" - # Accept the connection - await self.accept() - - # Attempt logging in the user - try: - # Log in the user to this session. - await login(self.scope, self.scope["user"]) - # Save the session to the database - await convert_to_async(self.scope["session"].save)() - except Exception: - # User could not be logged in - log.handler( - "Websocket login failure on initial connection!", - log.ERROR, - _logger, - ) - await self.__forbidden() - - # RECEIVING COMMANDS - async def receive_json(self, content, **kwargs): - """When the browser attempts to send a message to the server.""" - log.handler( - content, - log.INFO, - _logger, - ) - # Reject users that aren't logged in - if ( - isinstance(self.scope["user"], AnonymousUser) - or not self.scope["user"].is_authenticated - ): - await self.__forbidden() - - # COMMAND RESPONSE: FORBIDDEN - async def __forbidden(self): - response = {"command_name": "forbidden"} - await self.send_json(response) diff --git a/conreq/settings.py b/conreq/settings.py index 3ca832b1..9d3e381b 100644 --- a/conreq/settings.py +++ b/conreq/settings.py @@ -1,295 +1,294 @@ """ Django settings for Conreq project. -Generated by 'django-admin startproject' using Django 3.0.7. - -For more information on this file, see -https://docs.djangoproject.com/en/3.0/topics/settings/ - For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.0/ref/settings/ +https://docs.djangoproject.com/en/dev/ref/settings/ """ -import json -import os +import logging import secrets +import site import sys +from logging.config import dictConfig as logging_config from pathlib import Path +from typing import Any +import django_stubs_ext from django.core.management.utils import get_random_secret_key +from split_settings.tools import include from tzlocal import get_localzone_name +from conreq.types import Seconds +from conreq.utils.apps import find_apps from conreq.utils.environment import ( get_base_url, - get_bool_from_env, - get_database_type, - get_debug, - get_str_from_env, + get_database_engine, + get_debug_mode, + get_env, + get_safe_mode, set_env, ) -from conreq.utils.generic import list_modules - -# Project Directories -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -CORE_DIR = os.path.join(BASE_DIR, "conreq", "core") -DATA_DIR = get_str_from_env("DATA_DIR", os.path.join(BASE_DIR, "data"), dot_env=False) -APPS_DIR = os.path.join(DATA_DIR, "packages") -MEDIA_DIR = os.path.join(DATA_DIR, "media") -BACKUP_DIR = os.path.join(DATA_DIR, "backup") -TEMP_DIR = os.path.join(DATA_DIR, "temp") -USER_STATICFILES_DIR = os.path.join(DATA_DIR, "static") -LOG_DIR = os.path.join(DATA_DIR, "logs") -METRICS_DIR = os.path.join(DATA_DIR, "metrics") -MAKE_DIRS = [ +from conreq.utils.packages import find_packages + +# TODO: Add GUI support for changing most of the settings in this file +# Monkey patches for type hints +django_stubs_ext.monkeypatch() + + +# // DIRECTORY STRUCTURE // +ROOT_DIR = Path(__file__).resolve().parent.parent +DATA_DIR: Path = get_env("DATA_DIR", ROOT_DIR / "data", dot_env=False, return_type=Path) +DATABASE_DIR = DATA_DIR / "databases" +APP_SETTINGS_DIR = DATA_DIR / "app-settings" +MEDIA_DIR = DATA_DIR / "files" +MEDIA_SERVE_DIR = MEDIA_DIR / "serve" +METRICS_DIR = MEDIA_DIR / "metrics" +BACKUP_DIR = DATA_DIR / "backup" +TEMP_DIR = DATA_DIR / "temp" +USER_STATICFILES_DIR = DATA_DIR / "static" +LOG_DIR = DATA_DIR / "logs" +PID_DIR = DATA_DIR / "pids" +MAKE_DIRS: list[Path] = [ DATA_DIR, - APPS_DIR, + DATABASE_DIR, + APP_SETTINGS_DIR, MEDIA_DIR, + MEDIA_SERVE_DIR, + METRICS_DIR, BACKUP_DIR, TEMP_DIR, USER_STATICFILES_DIR, LOG_DIR, - METRICS_DIR, + PID_DIR, ] +if not DATA_DIR.parent.exists(): + raise OSError(f"Parent directory of DATA_DIR ({DATA_DIR.parent}) does not exist.") for directory in MAKE_DIRS: - if not os.path.exists(directory): - os.makedirs(directory) - - -# Environment Variables -DOTENV_FILE = os.path.join(DATA_DIR, "settings.env") -os.environ["CONREQ_DOTENV_FILE"] = DOTENV_FILE -if not os.path.exists(DOTENV_FILE): + if not directory.exists(): + directory.mkdir(parents=True) +APP_TEMPLATE_DIR = ROOT_DIR / "conreq" / "templates" +PACKAGE_TEMPLATE = APP_TEMPLATE_DIR / "package" +PACKAGE_SLIM_TEMPLATE = APP_TEMPLATE_DIR / "package_slim" +APP_TEMPLATE = APP_TEMPLATE_DIR / "app" +APP_SLIM_TEMPLATE = APP_TEMPLATE_DIR / "app_slim" + + +# // PROJECT CONFIG // +DOTENV_FILE: Path = DATA_DIR / "settings.env" +if not DOTENV_FILE.exists(): with open(DOTENV_FILE, "w", encoding="utf-8") as fp: pass -DEBUG = get_debug() -DB_ENGINE = get_database_type() -MYSQL_CONFIG_FILE = get_str_from_env("MYSQL_CONFIG_FILE", "") -SSL_SECURITY = get_bool_from_env("SSL_SECURITY", False) -PWNED_VALIDATOR = get_bool_from_env("PWNED_VALIDATOR", True) -X_FRAME_OPTIONS = get_str_from_env("X_FRAME_OPTIONS", "DENY") -BASE_URL = get_base_url() - - -# Basic Configuration -with (Path(BASE_DIR) / "VERSION").open() as f: +DEBUG = get_debug_mode() +WEBSERVER_WORKERS = get_env("WEBSERVER_WORKERS", 1, return_type=int) +with (ROOT_DIR / "VERSION").open() as f: CONREQ_VERSION = f.read().strip() +APP_STORE_VERSION = get_env("APP_STORE_VERSION", 1, return_type=int) +ROOT_URLCONF = "conreq.urls" +ASGI_APPLICATION = "conreq.asgi.application" -# Python Packages -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -SILKY_AUTHENTICATION = True -SILKY_AUTHORISATION = True -# SILKY_ANALYZE_QUERIES = True # Broken with Django 3.2 -SILKY_PYTHON_PROFILER = True -SILKY_PYTHON_PROFILER_BINARY = True -SILKY_PYTHON_PROFILER_RESULT_PATH = METRICS_DIR -HTML_MINIFY = True -WHITENOISE_MAX_AGE = 31536000 if not DEBUG else 0 -COMPRESS_OUTPUT_DIR = "minified" -COMPRESS_OFFLINE = True -COMPRESS_STORAGE = "compressor.storage.BrotliCompressorFileStorage" -COMPRESS_FILTERS = { - "css": ["compressor.filters.cssmin.rCSSMinFilter"], - "js": ["compressor.filters.jsmin.JSMinFilter"], -} -HUEY_FILENAME = os.path.join(DATA_DIR, "bg_tasks.sqlite3") -HUEY = { - "name": "huey", # DB name for huey. - "huey_class": "huey.SqliteHuey", # Huey implementation to use. - "filename": HUEY_FILENAME, # Sqlite filename - "results": True, # Store return values of tasks. - "immediate": False, # If True, run tasks synchronously. - "strict_fifo": True, # Utilize Sqlite AUTOINCREMENT to have unique task IDs - "consumer": { - "workers": 20, - }, -} - - -# Email Settings -if ( - get_str_from_env("EMAIL_HOST") - and get_str_from_env("EMAIL_PORT") - and get_str_from_env("EMAIL_HOST_USER") - and get_str_from_env("EMAIL_HOST_PASSWORD") -): - EMAIL_ENABLED = True - EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" - EMAIL_USE_TLS = get_bool_from_env("EMAIL_USE_TLS", True) - EMAIL_HOST = get_str_from_env("EMAIL_HOST") - EMAIL_PORT = get_str_from_env("EMAIL_PORT") - EMAIL_HOST_USER = get_str_from_env("EMAIL_HOST_USER") - EMAIL_HOST_PASSWORD = get_str_from_env("EMAIL_HOST_PASSWORD") - DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -else: - EMAIL_ENABLED = False - - -# PWA -PWA_APP_NAME = get_str_from_env("APP_NAME", "Conreq") -PWA_APP_DESCRIPTION = get_str_from_env("APP_DESCRIPTION", "Content Requesting") -PWA_APP_THEME_COLOR = "#3fcfa6" -PWA_APP_BACKGROUND_COLOR = "#04110d" -PWA_APP_ICONS = [ - { - "src": BASE_URL + "/static/icons/standard.png", - "sizes": "512x512", - "purpose": "any", - }, - { - "src": BASE_URL + "/static/icons/maskable.png", - "sizes": "512x512", - "purpose": "maskable", - }, -] -PWA_APP_ICONS_APPLE = [ - {"src": BASE_URL + "/static/icons/apple-touch-icon.png", "sizes": "180x180"} -] -PWA_APP_SPLASH_SCREEN = [] -PWA_APP_START_URL = BASE_URL + "/" -PWA_APP_SCOPE = PWA_APP_START_URL -PWA_APP_DEBUG_MODE = DEBUG - - -# Logging -CONREQ_LOG_FILE = os.path.join(LOG_DIR, "conreq.log") -ACCESS_LOG_FILE = os.path.join(LOG_DIR, "access.log") -if DEBUG: - LOG_LEVEL = get_str_from_env("LOG_LEVEL", "INFO") -else: - LOG_LEVEL = get_str_from_env("LOG_LEVEL", "WARNING") -LOGGING = { +# // LOGGING // +CONREQ_LOG_FILE = LOG_DIR / "conreq.log" +ACCESS_LOG_FILE = LOG_DIR / "access.log" +LOG_LEVEL = get_env("LOG_LEVEL", "INFO" if DEBUG else "WARNING") +LOGGING: dict[str, Any] = { "version": 1, "disable_existing_loggers": False, "formatters": { - "main": { + "default": { + "class": "conreq.utils.logging.SensitiveFormatter", "format": "%(asctime)s %(levelname)s %(name)s: %(message)s", }, "minimal": { + "class": "conreq.utils.logging.SensitiveFormatter", "format": "%(levelname)s %(name)s: %(message)s", }, }, "handlers": { "console": { - "level": "INFO", + "level": LOG_LEVEL, "class": "logging.StreamHandler", "formatter": "minimal", }, "conreq_logs": { - "level": "INFO", - "class": "logging.handlers.RotatingFileHandler", - "formatter": "main", - "maxBytes": 1024 * 1024 * 5, # 5 MB - "backupCount": 5, + "level": LOG_LEVEL, + "formatter": "default", "encoding": "utf-8", "filename": CONREQ_LOG_FILE, + "class": "logging.handlers.RotatingFileHandler", + "maxBytes": 1024 * 1024 * 5, + "backupCount": 5, }, }, "loggers": { - "django": { - "level": LOG_LEVEL, - }, - "hypercorn": { - "level": LOG_LEVEL, - }, - "conreq": { - "level": LOG_LEVEL, - }, - "huey": { - "level": LOG_LEVEL, - }, + "django": {}, + "conreq": {}, + "huey": {}, }, } -for logger in LOGGING["loggers"]: - LOGGING["loggers"][logger]["handlers"] = ["console", "conreq_logs"] - - -# Security Settings +for logger_name in LOGGING["loggers"]: + LOGGING["loggers"][logger_name]["handlers"] = ["console", "conreq_logs"] + LOGGING["loggers"][logger_name]["level"] = LOG_LEVEL +if "run_huey" in sys.argv: + LOGGING["loggers"]["conreq"]["level"] = "ERROR" + LOGGING["loggers"]["django"]["level"] = "ERROR" + LOGGING["disable_existing_loggers"] = True +logging_config(LOGGING) +_logger = logging.getLogger(__name__) + + +# // SECURITY // +SESSION_COOKIE_AGE = get_env("SESSION_COOKIE_AGE", Seconds.month * 3, return_type=int) SECURE_CONTENT_TYPE_NOSNIFF = True -SECURE_BROWSER_XSS_FILTER = True +SECURE_REFERRER_POLICY = get_env( + "SECURE_REFERRER_POLICY", "strict-origin-when-cross-origin" +) +DEFAULT_HOSTS = ["*", "localhost", "127.0.0.1", "[::1]"] ALLOWED_HOSTS = [ - host.strip() for host in get_str_from_env("ALLOWED_HOSTS", "*").split(",") + host.strip() for host in get_env("ALLOWED_HOSTS", "").split(",") if host ] -CSRF_TRUSTED_ORIGINS = [ - origin.strip() - for origin in get_str_from_env("TRUSTED_ORIGINS", "").split(",") - if origin +ALLOWED_FORWARDING_IPS = [ + addr.strip() for addr in get_env("ALLOWED_FOWARDING_IPS", "").split(",") if addr ] -if SSL_SECURITY: - SECURE_SSL_REDIRECT = True # Redirect HTTP to HTTPS - SECURE_HSTS_PRELOAD = True # Allow for HSTS preload - SECURE_HSTS_SECONDS = 31536000 # Allow for HSTS preload - SESSION_COOKIE_SECURE = True # Only send cookie over HTTPS - CSRF_COOKIE_SECURE = True # Only send cookie over HTTPS - LANGUAGE_COOKIE_SECURE = True # Only send cookie over HTTPS - LANGUAGE_COOKIE_HTTPONLY = True # Do not allow JS to access cookie - - -# API Settings -REST_FRAMEWORK = { +if not ALLOWED_HOSTS: + ALLOWED_HOSTS = DEFAULT_HOSTS +if get_env("CSRF_TRUSTED_ORIGINS", ""): + CSRF_TRUSTED_ORIGINS = [ + origin.strip() + for origin in get_env("CSRF_TRUSTED_ORIGINS", "").split(",") + if origin + ] +else: + CSRF_TRUSTED_ORIGINS = [ + f"http://{origin.strip()}" + for origin in ALLOWED_HOSTS + if origin not in DEFAULT_HOSTS + ] + [ + f"https://{origin.strip()}" + for origin in ALLOWED_HOSTS + if origin not in DEFAULT_HOSTS + ] +SECURE_BROWSER_XSS_FILTER = True + + +# // HTTP RESTFUL API // +REST_FRAMEWORK: dict[str, Any] = { "DEFAULT_AUTHENTICATION_CLASSES": [ - "rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.TokenAuthentication", ], "DEFAULT_PERMISSION_CLASSES": [ - "conreq.core.api.permissions.HasAPIKey", + "conreq._core.api.permissions.HasAPIKey", + ], + "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", +} +if DEBUG: + REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"].append( + "conreq._core.api.authentication.CsrfExemptSessionAuthentication", + ) +SPECTACULAR_SETTINGS = { # Use Swagger UI for API endpoints + "TITLE": "Conreq API Endpoints", + "DESCRIPTION": "Outline for all endpoints available within this Conreq instance.", + "VERSION": CONREQ_VERSION, + "CONTACT": { + "name": "Conreq's Developer", + "email": "archiethemonger@gmail.com", + }, + "LICENSE": {"name": "GPL-3.0 License"}, + "SWAGGER_UI_DIST": "SIDECAR", + "SWAGGER_UI_FAVICON_HREF": "SIDECAR", + "REDOC_DIST": "SIDECAR", + "SCHEMA_PATH_PREFIX": "/api", + "SCHEMA_PATH_PREFIX_TRIM": True, + "SERVERS": [ + { + "url": "{protocol}://{host}:{port}/api", + "variables": { + "host": {"default": "127.0.0.1"}, + "port": {"default": 7575}, + "protocol": {"enum": ["http", "https"], "default": "http"}, + }, + } ], } -# settings.json (old) -> settings.env -SETTINGS_FILE = os.path.join(DATA_DIR, "settings.json") -if os.path.exists(SETTINGS_FILE): - with open(SETTINGS_FILE, "r+", encoding="utf-8") as settings_file: - settings = json.load(settings_file) - if settings.get("DB_ENCRYPTION_KEY"): - set_env("DB_ENCRYPTION_KEY", settings["DB_ENCRYPTION_KEY"]) - if settings.get("SECRET_KEY"): - set_env("WEB_ENCRYPTION_KEY", settings["SECRET_KEY"]) - os.remove(SETTINGS_FILE) - - -# Encryption -if get_str_from_env("DB_ENCRYPTION_KEY"): - FIELD_ENCRYPTION_KEYS = [get_str_from_env("DB_ENCRYPTION_KEY")] -else: +# // ENCRYPTION // +FIELD_ENCRYPTION_KEYS = [get_env("DB_ENCRYPTION_KEY")] +SECRET_KEY = get_env("WEB_ENCRYPTION_KEY") +if not FIELD_ENCRYPTION_KEYS[0]: FIELD_ENCRYPTION_KEYS = [secrets.token_hex(32)] set_env("DB_ENCRYPTION_KEY", FIELD_ENCRYPTION_KEYS[0]) -if get_str_from_env("WEB_ENCRYPTION_KEY"): - SECRET_KEY = get_str_from_env("WEB_ENCRYPTION_KEY") -else: +if not SECRET_KEY: SECRET_KEY = set_env("WEB_ENCRYPTION_KEY", get_random_secret_key())[1] -# Django Apps & Middleware -sys.path.append(APPS_DIR) # User Installed Apps +# // DJANGO APPS AND MIDDLEWARE // INSTALLED_APPS = [ - "daphne", # Websocket library - "django.contrib.admin", - "django.contrib.admindocs", + *( + [ + "daphne", # Overrides `runserver` command with an ASGI server + "jazzmin", # Pretty admin interface + "django.contrib.admin", + "django.contrib.admindocs", + "massadmin", # Mass edit actions for admin pages + "health_check", + "health_check.db", + "health_check.cache", + "health_check.storage", + "health_check.contrib.migrations", + "health_check.contrib.psutil", + ] + if DEBUG + else [] + ), "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "whitenoise.runserver_nostatic", "django.contrib.staticfiles", - *list_modules(CORE_DIR, prefix="conreq.core."), - "encrypted_fields", # Allow for encrypted text in the DB - "solo", # Allow for single-row fields in the DB - "django_cleanup.apps.CleanupConfig", # Automatically delete old image files - "huey.contrib.djhuey", # Queuing background tasks - "compressor", # Minifies CSS/JS files - "url_or_relative_url_field", # Validates relative URLs + "conreq._core.debug", + "conreq._core.api", + "conreq._core.app_store", + "conreq._core.backup", + "conreq._core.base", + "conreq._core.database", + "conreq._core.email", + "conreq._core.initialization", + "conreq._core.home", + "conreq._core.landing", + "conreq._core.password_reset", + "conreq._core.pwa", + "conreq._core.server_settings", + "conreq._core.sign_in", + "conreq._core.sign_up", + "conreq._core.user_management", + "conreq._core.user_settings", + # Database Fields + "colorfield", # HEX colors in the DB + "encrypted_fields", # Encrypted text in the DB + "solo", # Single-row models in the DB + "django_ace", # Code hightlighted form fields + "versionfield", # Filterable/sortable version numbers fields in the DB + # ASGI + "reactpy_django", # ReactJS for Python + # API "rest_framework", # OpenAPI Framework "rest_framework_api_key", # API Key Manager "rest_framework.authtoken", # API User Authentication - *list_modules(APPS_DIR), # User Installed Apps + # Miscellaneous + "crispy_forms", # Simplify generating HTML forms + "crispy_bootstrap5", # Bootstrap 5 support for Crispy Forms + "django_tables2", # Simplify generating HTML tables + "huey.contrib.djhuey", # Queuing background tasks + "compressor", # Minifies CSS/JS files + "ordered_model", # Ordered database models ] MIDDLEWARE = [ - "compression_middleware.middleware.CompressionMiddleware", "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", # Serve static files through Django securely - "django.middleware.gzip.GZipMiddleware", + "compression_middleware.middleware.CompressionMiddleware", + *(["silk.middleware.SilkyMiddleware"] if DEBUG else []), "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.http.ConditionalGetMiddleware", "django.middleware.common.CommonMiddleware", @@ -297,127 +296,96 @@ "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", - "htmlmin.middleware.HtmlMinifyMiddleware", # Compresses HTML files - "htmlmin.middleware.MarkRequestMiddleware", # Marks the request as minified ] +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" +SILKY_AUTHENTICATION = True +SILKY_AUTHORISATION = True +SILKY_PYTHON_PROFILER = True +SILKY_PYTHON_PROFILER_BINARY = True +SILKY_PYTHON_PROFILER_RESULT_PATH = METRICS_DIR +SILKY_ANALYZE_QUERIES = get_database_engine() != "SQLITE3" +SILKY_MAX_RECORDED_REQUESTS = 1000 +WHITENOISE_MAX_AGE = 0 if DEBUG else 31536000 +COMPRESS_OUTPUT_DIR = "minified" +COMPRESS_OFFLINE = True +COMPRESS_STORAGE = "compressor.storage.BrotliCompressorFileStorage" +COMPRESS_FILTERS = { + "css": ["compressor.filters.cssmin.rCSSMinFilter"], + "js": ["compressor.filters.jsmin.JSMinFilter"], +} +HUEY_FILENAME = DATABASE_DIR / "background_tasks.sqlite3" +HUEY = { + "name": "huey", # DB table name + "huey_class": "conreq._core.database.SqliteHuey", # Huey implementation to use + "filename": HUEY_FILENAME, # Sqlite filename + "immediate": False, # If True, run tasks synchronously + "strict_fifo": True, # Utilize Sqlite AUTOINCREMENT to have unique task IDs + "consumer": { + "workers": WEBSERVER_WORKERS * 5, # TODO: Add setting to configure this + }, +} +FILE_UPLOAD_TEMP_DIR = TEMP_DIR +CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" +CRISPY_TEMPLATE_PACK = "bootstrap5" +JAZZMIN_SETTINGS = {"custom_css": "conreq/jazzmin.css"} -# Enabling apps/middleware based on flags -if X_FRAME_OPTIONS.lower() != "false" and not DEBUG: - # Block embedding conreq - MIDDLEWARE.append("django.middleware.clickjacking.XFrameOptionsMiddleware") -if DEBUG: - # Performance analysis tools - INSTALLED_APPS.append("silk") - MIDDLEWARE.append("silk.middleware.SilkyMiddleware") - # API docs generator - INSTALLED_APPS.append("drf_yasg") - - -# URL Routing and Page Rendering -ROOT_URLCONF = "conreq.urls" -ASGI_APPLICATION = "conreq.asgi.application" -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "APP_DIRS": True, +# // DATA STORAGE // +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": DATABASE_DIR / "default.sqlite3", "OPTIONS": { - "context_processors": [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - ], + "timeout": 3, # 3 second query timeout }, - }, -] - - -# Databases -if DB_ENGINE == "MYSQL": - if not MYSQL_CONFIG_FILE: - print("MYSQL_CONFIG_FILE is not set!") - sys.exit(1) - elif not os.path.exists(MYSQL_CONFIG_FILE): - print(f"MYSQL_CONFIG_FILE '{MYSQL_CONFIG_FILE}' does not exist!") - sys.exit(1) - else: - import pymysql - - pymysql.install_as_MySQLdb() - - # MySQL - DATABASES = { - "default": { - "ENGINE": "django.db.backends.mysql", - "OPTIONS": { - "read_default_file": MYSQL_CONFIG_FILE, - }, - } - } -else: - # SQLite - DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(DATA_DIR, "db.sqlite3"), - "OPTIONS": { - "timeout": 3, # 3 second query timeout - }, - } } +} +DATABASE_ROUTERS = ["conreq._core.database.router.DatabaseRouter"] +CACHE_SHARDS = min(WEBSERVER_WORKERS, 10) CACHES = { "default": { "BACKEND": "diskcache.DjangoCache", - "LOCATION": os.path.join(DATA_DIR, "cache"), - "TIMEOUT": 300, # Django setting for default timeout of each key. - "SHARDS": 8, # Number of "sharded" cache dbs to create - "DATABASE_TIMEOUT": 0.25, # 250 milliseconds - "OPTIONS": {"size_limit": 2 ** 30}, # 1 gigabyte + "LOCATION": DATA_DIR / "cache", + "TIMEOUT": 300, # Default timeout of each key + "SHARDS": CACHE_SHARDS, # Number of cache DBs to create + "DATABASE_TIMEOUT": 0.05 + (CACHE_SHARDS * 0.01), # Query timeout + "OPTIONS": {"size_limit": 2**30}, # 1 gigabyte max cache size } } +SESSION_ENGINE = "django.contrib.sessions.backends.cached_db" +BACKUP_KEEP_MAX = 20 +BACKUP_DATE_FORMAT = "%Y-%m-%d_at_%H%M" +BACKUP_COMPRESSION = "xz" -# User Authentication +# // AUTHENTICATION // AUTH_PASSWORD_VALIDATORS = [ { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] -LOGIN_REDIRECT_URL = "base:landing" +LOGIN_REDIRECT_URL = "landing" LOGIN_URL = "sign_in" -if PWNED_VALIDATOR: - AUTH_PASSWORD_VALIDATORS.append( - { - "NAME": "pwned_passwords_django.validators.PwnedPasswordsValidator", - "OPTIONS": { - "error_message": "Cannot use a compromised password. This password was detected %(amount)d time(s) on 'haveibeenpwned.com'.", - "help_message": "Your password can't be a compromised password.", - }, - }, - ) -# Internationalization +# // COOKIES // +SESSION_COOKIE_NAME = "conreq_sessionidd" +CSRF_COOKIE_NAME = "conreq_csrftoken" +LANGUAGE_COOKIE_NAME = "conreq_language" + + +# // INTERNATIONALIZATION // LANGUAGE_CODE = "en-US" TIME_ZONE = get_localzone_name() -USE_I18N = True -USE_L10N = True USE_TZ = True -# Static Files (CSS, JavaScript, Images) -STATIC_ROOT = os.path.join(DATA_DIR, "collectstatic") -STATIC_URL = BASE_URL + "/static/" +# // STATIC FILES // +STATIC_ROOT = DATA_DIR / "static_processed" +STATIC_URL = f"{get_base_url()}static/" STATICFILES_DIRS = [ USER_STATICFILES_DIR, ] @@ -428,4 +396,71 @@ ] STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" MEDIA_ROOT = MEDIA_DIR -MEDIA_URL = "media/" +MEDIA_URL = "files/" +if get_base_url(empty_if_unset=True): + MEDIA_URL = get_base_url(append_slash=False) + MEDIA_URL +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + + +# // EMAIL // +EMAIL_BACKEND = "conreq.app.services.email.EmailBackend" +EMAIL_SUBJECT_PREFIX = "" + + +# // USER INSTALLED APP PACKAGES // +# TODO: Add a user editable setting script +if not get_safe_mode(): + user_apps = find_apps() + INSTALLED_APPS += user_apps + if user_apps: + _logger.info( + "Booting with the following apps:%s", ("\n+ " + "\n+ ".join(user_apps)) + ) + else: + _logger.warning("No user installed apps detected.") + + # Execute settings scripts from enabled Conreq Apps + packages = find_packages() + site_dir = Path(site.getsitepackages()[1]) + settings_files: list[Path] = [] + if not site.getsitepackages()[1].endswith("site-packages"): + raise OSError( + "Expected site-packages directory to end with 'site-packages', " + f"but got '{site_dir}'." + ) + for pkg_name in packages: + # These are settings files defined in the package's directory + dedicated_settings = site_dir / f"{pkg_name}" / "conreq_settings.py" + if dedicated_settings.exists(): + settings_files.append(dedicated_settings) + + # These are settings files defined in the database's settings_script field + simple_settings = APP_SETTINGS_DIR / f"{pkg_name}.py" + if simple_settings.exists(): + settings_files.append(simple_settings) + + include(*settings_files) # type: ignore + + +# // POSITION / TIMING SENSITIVE CODE // +# Debug django apps (must be near last) +if DEBUG: + INSTALLED_APPS.extend(("silk", "drf_spectacular", "drf_spectacular_sidecar")) +# Auto delete dangling files app (must be near last) +INSTALLED_APPS.append("django_cleanup.apps.CleanupConfig") +# Conreq app loader (must be last) +if not get_safe_mode(): + INSTALLED_APPS.append("conreq._core.app_loader") diff --git a/conreq/templates/app/app_name/__init__.py-tpl b/conreq/templates/app/app_name/__init__.py-tpl new file mode 100644 index 00000000..b693c3a9 --- /dev/null +++ b/conreq/templates/app/app_name/__init__.py-tpl @@ -0,0 +1 @@ +"""Conreq App: {{ verbose_name }}""" diff --git a/conreq/templates/app/app_name/admin.py-tpl b/conreq/templates/app/app_name/admin.py-tpl new file mode 100644 index 00000000..b1fb5d50 --- /dev/null +++ b/conreq/templates/app/app_name/admin.py-tpl @@ -0,0 +1,9 @@ +""" +Admin registration for {{ verbose_name }}. + +After registering a model, users can graphically edit database entries when Conreq +is in DEBUG mode. + +See more information in the Django ModelAdmin docs. +""" +from django.contrib import admin diff --git a/conreq/templates/app/app_name/api/__init__.py b/conreq/templates/app/app_name/api/__init__.py new file mode 100644 index 00000000..3f08be20 --- /dev/null +++ b/conreq/templates/app/app_name/api/__init__.py @@ -0,0 +1,3 @@ +""" +API endpoints for {{ verbose_name }}. +""" diff --git a/conreq/templates/app/app_name/api/docs.py-tpl b/conreq/templates/app/app_name/api/docs.py-tpl new file mode 100644 index 00000000..be6b4e9c --- /dev/null +++ b/conreq/templates/app/app_name/api/docs.py-tpl @@ -0,0 +1,10 @@ +""" +API documentation for {{ verbose_name }}. + +See more information in the Conreq API docs. +""" + +from drf_spectacular.utils import OpenApiExample, OpenApiParameter, OpenApiResponse +from rest_framework import status + +from conreq.utils.api import APIDocs diff --git a/conreq/templates/app/app_name/api/endpoints.py-tpl b/conreq/templates/app/app_name/api/endpoints.py-tpl new file mode 100644 index 00000000..b4338a19 --- /dev/null +++ b/conreq/templates/app/app_name/api/endpoints.py-tpl @@ -0,0 +1,13 @@ +""" +API endpoint registration for {{ verbose_name }}. + +See more information in the Conreq API docs. +""" + +from rest_framework.response import Response +from rest_framework.views import APIView + +from conreq.app import register +from conreq.utils.api import APIDocs, extend_docs + +from . import docs diff --git a/conreq/templates/app/app_name/apps.py-tpl b/conreq/templates/app/app_name/apps.py-tpl new file mode 100644 index 00000000..07fd01ba --- /dev/null +++ b/conreq/templates/app/app_name/apps.py-tpl @@ -0,0 +1,28 @@ +""" +App Configuration for {{ verbose_name }}. + +Stores basic information to let Django know about your app. + +Additonal variables can be created in here to store metadata and +configuration values for your app. + +See more information in the Django AppConfig docs. +""" +from django.apps import AppConfig + +from conreq.utils.modules import load + +MODULE = __name__ +APP = MODULE[: MODULE.rfind(".")] + +class {{ camel_case_app_name }}Config(AppConfig): + name = APP + verbose_name = "{{ verbose_name }}" + label = "{{ app_name }}" + default_auto_field = "django.db.models.BigAutoField" + auto_import = True + auto_import_silent = False + + def ready(self): + """Code that only executes after Django has been initialized.""" + pass diff --git a/conreq/templates/app/app_name/components/__init__.py-tpl b/conreq/templates/app/app_name/components/__init__.py-tpl new file mode 100644 index 00000000..08934e49 --- /dev/null +++ b/conreq/templates/app/app_name/components/__init__.py-tpl @@ -0,0 +1,8 @@ +""" +Frontend component registration for {{ verbose_name }}. + +Allows for dynamically updating webpages, akin to ReactJS. + +See more information in ReactPy docs. +""" +from reactpy import component diff --git a/conreq/templates/app/app_name/components/exports.py b/conreq/templates/app/app_name/components/exports.py new file mode 100644 index 00000000..7fcb8812 --- /dev/null +++ b/conreq/templates/app/app_name/components/exports.py @@ -0,0 +1,3 @@ +""" +ReactJS to ReactPy exports for {{ verbose_name }}. +""" diff --git a/conreq/templates/app/app_name/components/main.py b/conreq/templates/app/app_name/components/main.py new file mode 100644 index 00000000..29e41ef7 --- /dev/null +++ b/conreq/templates/app/app_name/components/main.py @@ -0,0 +1,3 @@ +""" +ReactPy components for {{ verbose_name }}. +""" diff --git a/conreq/templates/app/app_name/forms.py-tpl b/conreq/templates/app/app_name/forms.py-tpl new file mode 100644 index 00000000..9b8ae46e --- /dev/null +++ b/conreq/templates/app/app_name/forms.py-tpl @@ -0,0 +1,11 @@ +""" +Forms for {{ verbose_name }}. + +Typically used with forms.ModelForm to edit database entries. + +See more information in the Django Forms docs. +""" + +from crispy_forms.helper import FormHelper +from django import forms +from django.views.generic.edit import CreateView, DeleteView, UpdateView diff --git a/conreq/templates/app/app_name/homepage.py-tpl b/conreq/templates/app/app_name/homepage.py-tpl new file mode 100644 index 00000000..bc4aff56 --- /dev/null +++ b/conreq/templates/app/app_name/homepage.py-tpl @@ -0,0 +1,4 @@ +from reactpy import component + +from conreq.app.register import homepage +from conreq.types import CSS, SCSS, HTMLTemplate, JavaScript, NavGroup diff --git a/conreq/templates/app/app_name/management/__init__.py b/conreq/templates/app/app_name/management/__init__.py new file mode 100644 index 00000000..0103d75f --- /dev/null +++ b/conreq/templates/app/app_name/management/__init__.py @@ -0,0 +1,7 @@ +""" +Admin management features for {{ verbose_name }}. + +Anything python files or templates specific to managing your app can go here. + +Note: Typically only used for Django Management Commands. +""" diff --git a/conreq/templates/app/app_name/management/commands/__init__.py b/conreq/templates/app/app_name/management/commands/__init__.py new file mode 100644 index 00000000..08436ae3 --- /dev/null +++ b/conreq/templates/app/app_name/management/commands/__init__.py @@ -0,0 +1,7 @@ +""" +Management Commands for {{ verbose_name }}. + +For example, `python manage.py my_new_command` + +See more information in the Django Management Commands docs. +""" diff --git a/conreq/templates/app/app_name/migrations/__init__.py b/conreq/templates/app/app_name/migrations/__init__.py new file mode 100644 index 00000000..0ba929ae --- /dev/null +++ b/conreq/templates/app/app_name/migrations/__init__.py @@ -0,0 +1,7 @@ +""" +Database migrations for {{ verbose_name }}. + +These are typically auto generated by `python manage.py makemigrations` + +See more information in the Django Migrations docs. +""" diff --git a/conreq/templates/app/app_name/models.py-tpl b/conreq/templates/app/app_name/models.py-tpl new file mode 100644 index 00000000..296fb8c2 --- /dev/null +++ b/conreq/templates/app/app_name/models.py-tpl @@ -0,0 +1,8 @@ +""" +Database models for {{ verbose_name }}. + +After making changes to a model, you will need to run `python manage.py makemigrations`. + +See more information in the Django Models docs. +""" +from django.db import models diff --git a/conreq/core/base/static/css/dark.css b/conreq/templates/app/app_name/static/example.css similarity index 100% rename from conreq/core/base/static/css/dark.css rename to conreq/templates/app/app_name/static/example.css diff --git a/conreq/templates/app/app_name/static/example.js b/conreq/templates/app/app_name/static/example.js new file mode 100644 index 00000000..e69de29b diff --git a/conreq/templates/app/app_name/tasks.py-tpl b/conreq/templates/app/app_name/tasks.py-tpl new file mode 100644 index 00000000..1b1fe751 --- /dev/null +++ b/conreq/templates/app/app_name/tasks.py-tpl @@ -0,0 +1,12 @@ +""" +Background tasks for {{ verbose_name }}. + +Can be scheduled to execute automatically via seconds or crontab. +Or, they can be defined to only be executed on-demand. + +See more information in the Huey docs. +""" +from huey import crontab +from huey.contrib.djhuey import db_periodic_task, db_task, periodic_task, task + +from conreq.types import Seconds diff --git a/conreq/templates/app/app_name/templates/example.html b/conreq/templates/app/app_name/templates/example.html new file mode 100644 index 00000000..e69de29b diff --git a/conreq/templates/app/app_name/templatetags/__init__.py b/conreq/templates/app/app_name/templatetags/__init__.py new file mode 100644 index 00000000..107fe0bb --- /dev/null +++ b/conreq/templates/app/app_name/templatetags/__init__.py @@ -0,0 +1,5 @@ +""" +Template Tags for {{ verbose_name }}. + +See more information in the Django Custom Template Tags docs. +""" diff --git a/conreq/templates/app/app_name/tests.py-tpl b/conreq/templates/app/app_name/tests.py-tpl new file mode 100644 index 00000000..c5cf054c --- /dev/null +++ b/conreq/templates/app/app_name/tests.py-tpl @@ -0,0 +1,10 @@ +""" +Tests for {{ verbose_name }}. + +These will automatically be run at Conreq start up to ensure this app +does not have any critical failures or misconfiguration. + +See more information in the Django Tests and Channels Tests docs. +""" +from channels.testing import ChannelsLiveServerTestCase +from django.test import TestCase diff --git a/conreq/templates/app/app_name/urls.py-tpl b/conreq/templates/app/app_name/urls.py-tpl new file mode 100644 index 00000000..ab9102a0 --- /dev/null +++ b/conreq/templates/app/app_name/urls.py-tpl @@ -0,0 +1,11 @@ +""" +URL endpoint registration for {{ verbose_name }}. + +See more information in the Conreq URL docs. +""" +from django.shortcuts import render +from django.views import View +from rest_framework.generics import GenericAPIView +from rest_framework.response import Response + +from conreq.app.register.http import api, url diff --git a/conreq/templates/app/app_name/websockets.py-tpl b/conreq/templates/app/app_name/websockets.py-tpl new file mode 100644 index 00000000..f2056a80 --- /dev/null +++ b/conreq/templates/app/app_name/websockets.py-tpl @@ -0,0 +1,8 @@ +""" +Websocket registration for {{ verbose_name }}. + +See more information in the Conreq ASGI docs. +""" +from channels.generic.websocket import AsyncJsonWebsocketConsumer + +from conreq.app.register.websockets import websocket diff --git a/conreq/templates/app_slim/app_name/__init__.py-tpl b/conreq/templates/app_slim/app_name/__init__.py-tpl new file mode 100644 index 00000000..b693c3a9 --- /dev/null +++ b/conreq/templates/app_slim/app_name/__init__.py-tpl @@ -0,0 +1 @@ +"""Conreq App: {{ verbose_name }}""" diff --git a/conreq/templates/app_slim/app_name/apps.py-tpl b/conreq/templates/app_slim/app_name/apps.py-tpl new file mode 100644 index 00000000..07fd01ba --- /dev/null +++ b/conreq/templates/app_slim/app_name/apps.py-tpl @@ -0,0 +1,28 @@ +""" +App Configuration for {{ verbose_name }}. + +Stores basic information to let Django know about your app. + +Additonal variables can be created in here to store metadata and +configuration values for your app. + +See more information in the Django AppConfig docs. +""" +from django.apps import AppConfig + +from conreq.utils.modules import load + +MODULE = __name__ +APP = MODULE[: MODULE.rfind(".")] + +class {{ camel_case_app_name }}Config(AppConfig): + name = APP + verbose_name = "{{ verbose_name }}" + label = "{{ app_name }}" + default_auto_field = "django.db.models.BigAutoField" + auto_import = True + auto_import_silent = False + + def ready(self): + """Code that only executes after Django has been initialized.""" + pass diff --git a/conreq/app_template/app_name/.gitignore b/conreq/templates/package/app_name/.gitignore similarity index 96% rename from conreq/app_template/app_name/.gitignore rename to conreq/templates/package/app_name/.gitignore index 75dc5639..b7c8969a 100644 --- a/conreq/app_template/app_name/.gitignore +++ b/conreq/templates/package/app_name/.gitignore @@ -5,7 +5,7 @@ logs *.pyc .dccache __pycache__ -db.sqlite3 +*.sqlite3 media cache collectstatic @@ -90,9 +90,6 @@ ENV/ env.bak/ venv.bak/ -# mkdocs documentation -/site - # mypy .mypy_cache/ @@ -124,4 +121,4 @@ GitHub.sublime-settings %SystemDrive% # Mac file system -.DS_Store \ No newline at end of file +.DS_Store diff --git a/conreq/app_template/app_name/LICENSE b/conreq/templates/package/app_name/LICENSE similarity index 100% rename from conreq/app_template/app_name/LICENSE rename to conreq/templates/package/app_name/LICENSE diff --git a/conreq/templates/package/app_name/README.md b/conreq/templates/package/app_name/README.md new file mode 100644 index 00000000..e69de29b diff --git a/conreq/templates/package/app_name/__init__.py-tpl b/conreq/templates/package/app_name/__init__.py-tpl new file mode 100644 index 00000000..e072d782 --- /dev/null +++ b/conreq/templates/package/app_name/__init__.py-tpl @@ -0,0 +1,4 @@ +"""Conreq Package: {{ verbose_name }}""" + +conreq_apps = ["{{ app_name }}.apps.*"] +"""List of apps to be added to Django's `settings.py:INSTALLED_APPS`""" diff --git a/conreq/templates/package/app_name/app_store.json b/conreq/templates/package/app_name/app_store.json new file mode 100644 index 00000000..2f6eaa38 --- /dev/null +++ b/conreq/templates/package/app_name/app_store.json @@ -0,0 +1,3 @@ +{ + "empty": "Please generate this file via the management command prior to listing on the app store" +} diff --git a/conreq/templates/package/app_name/apps/__init__.py b/conreq/templates/package/app_name/apps/__init__.py new file mode 100644 index 00000000..fc7a2302 --- /dev/null +++ b/conreq/templates/package/app_name/apps/__init__.py @@ -0,0 +1 @@ +"""Conreq Apps for {{ verbose_name }}""" diff --git a/conreq/templates/package/app_name/conreq_settings.py-tpl b/conreq/templates/package/app_name/conreq_settings.py-tpl new file mode 100644 index 00000000..e5ed3484 --- /dev/null +++ b/conreq/templates/package/app_name/conreq_settings.py-tpl @@ -0,0 +1,4 @@ +"""{{ verbose_name }} code that needs to run within the context of Conreq's settings.py file. +This is an alternative to defining a `settings_script` within your app's database model. + +See django-split-settings docs for more details.""" diff --git a/conreq/templates/package/app_name/licenses/example/LICENSE.txt b/conreq/templates/package/app_name/licenses/example/LICENSE.txt new file mode 100644 index 00000000..b4a067f4 --- /dev/null +++ b/conreq/templates/package/app_name/licenses/example/LICENSE.txt @@ -0,0 +1,11 @@ +Store your licenses for each dependency within this folder structure. + +For example, if you use FontAwesome store your licenses as such: + +{{app_name}}/licenses/Font Awesome/LICENSE.txt + +Note +--- +Folder name should retain the spaces and capitalization of the project +Only markdown and txt licenses are supported. +Licenses are automatically displayed within Conreq's user interface diff --git a/conreq/app_template/app_name/package.json b/conreq/templates/package/app_name/package.json similarity index 100% rename from conreq/app_template/app_name/package.json rename to conreq/templates/package/app_name/package.json diff --git a/conreq/templates/package/app_name/requirements.txt b/conreq/templates/package/app_name/requirements.txt new file mode 100644 index 00000000..87a56b17 --- /dev/null +++ b/conreq/templates/package/app_name/requirements.txt @@ -0,0 +1 @@ +# Any requirements in here will be automatically installed by Conreq diff --git a/conreq/templates/package/app_name/setup.py-tpl b/conreq/templates/package/app_name/setup.py-tpl new file mode 100644 index 00000000..4e5d90c1 --- /dev/null +++ b/conreq/templates/package/app_name/setup.py-tpl @@ -0,0 +1,46 @@ +from pathlib import Path + +from setuptools import find_packages, setup + + +# Variables +ROOT_DIR = Path(__file__).parent +with (ROOT_DIR / "README.md").open() as f: + README = f.read().strip() + + +# PyPi Information +PACKAGE = { + "name": "{{ package_name }}", + "version": "", + "packages": find_packages(str(ROOT_DIR)), + "description": "", + "long_description": README, + "long_description_content_type": "text/markdown", + "author": "", + "author_email": "", + "url": "", + "license": "GPLv3", + "include_package_data": True, + "zip_safe": False, + "classifiers": [ + "Environment :: Web Environment", + "Programming Language :: Python", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Topic :: Internet :: WWW/HTTP", + ], +} + + +# Requirements +requirements = [] +with (ROOT_DIR / "requirements.txt").open() as f: + for line in map(str.strip, f): + if not line.startswith("#") and not line.startswith("git+"): + requirements.append(line) +PACKAGE["install_requires"] = requirements + + +# Install +if __name__ == "__main__": + setup(**PACKAGE) diff --git a/conreq/templates/package/app_name/startup.py-tpl b/conreq/templates/package/app_name/startup.py-tpl new file mode 100644 index 00000000..d57430a4 --- /dev/null +++ b/conreq/templates/package/app_name/startup.py-tpl @@ -0,0 +1,4 @@ +"""{{ verbose_name }}'s actions that need to take place during Conreq startup.""" +from multiprocessing import Process + +from conreq.app.register.startup import function, process diff --git a/conreq/templates/package/app_name/utils/__init__.py b/conreq/templates/package/app_name/utils/__init__.py new file mode 100644 index 00000000..d4dd24d0 --- /dev/null +++ b/conreq/templates/package/app_name/utils/__init__.py @@ -0,0 +1 @@ +"""Utilities for {{ verbose_name }}""" diff --git a/conreq/templates/package_slim/app_name/LICENSE b/conreq/templates/package_slim/app_name/LICENSE new file mode 100644 index 00000000..e62ec04c --- /dev/null +++ b/conreq/templates/package_slim/app_name/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/conreq/templates/package_slim/app_name/README.md b/conreq/templates/package_slim/app_name/README.md new file mode 100644 index 00000000..e69de29b diff --git a/conreq/templates/package_slim/app_name/__init__.py-tpl b/conreq/templates/package_slim/app_name/__init__.py-tpl new file mode 100644 index 00000000..e072d782 --- /dev/null +++ b/conreq/templates/package_slim/app_name/__init__.py-tpl @@ -0,0 +1,4 @@ +"""Conreq Package: {{ verbose_name }}""" + +conreq_apps = ["{{ app_name }}.apps.*"] +"""List of apps to be added to Django's `settings.py:INSTALLED_APPS`""" diff --git a/conreq/templates/package_slim/app_name/apps/__init__.py b/conreq/templates/package_slim/app_name/apps/__init__.py new file mode 100644 index 00000000..fc7a2302 --- /dev/null +++ b/conreq/templates/package_slim/app_name/apps/__init__.py @@ -0,0 +1 @@ +"""Conreq Apps for {{ verbose_name }}""" diff --git a/conreq/templates/package_slim/app_name/requirements.txt b/conreq/templates/package_slim/app_name/requirements.txt new file mode 100644 index 00000000..87a56b17 --- /dev/null +++ b/conreq/templates/package_slim/app_name/requirements.txt @@ -0,0 +1 @@ +# Any requirements in here will be automatically installed by Conreq diff --git a/conreq/templates/package_slim/app_name/setup.py-tpl b/conreq/templates/package_slim/app_name/setup.py-tpl new file mode 100644 index 00000000..4e5d90c1 --- /dev/null +++ b/conreq/templates/package_slim/app_name/setup.py-tpl @@ -0,0 +1,46 @@ +from pathlib import Path + +from setuptools import find_packages, setup + + +# Variables +ROOT_DIR = Path(__file__).parent +with (ROOT_DIR / "README.md").open() as f: + README = f.read().strip() + + +# PyPi Information +PACKAGE = { + "name": "{{ package_name }}", + "version": "", + "packages": find_packages(str(ROOT_DIR)), + "description": "", + "long_description": README, + "long_description_content_type": "text/markdown", + "author": "", + "author_email": "", + "url": "", + "license": "GPLv3", + "include_package_data": True, + "zip_safe": False, + "classifiers": [ + "Environment :: Web Environment", + "Programming Language :: Python", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Topic :: Internet :: WWW/HTTP", + ], +} + + +# Requirements +requirements = [] +with (ROOT_DIR / "requirements.txt").open() as f: + for line in map(str.strip, f): + if not line.startswith("#") and not line.startswith("git+"): + requirements.append(line) +PACKAGE["install_requires"] = requirements + + +# Install +if __name__ == "__main__": + setup(**PACKAGE) diff --git a/conreq/types.py b/conreq/types.py new file mode 100644 index 00000000..db0b8273 --- /dev/null +++ b/conreq/types.py @@ -0,0 +1,256 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Callable, Sequence + +from reactpy.core.component import Component +from reactpy.core.hooks import Context, create_context +from reactpy.core.types import ComponentConstructor, VdomDict +from sortedcontainers import SortedSet + +if TYPE_CHECKING: + from reactpy_django.types import Connection + +# pylint: disable=protected-access, too-few-public-methods + + +class Icon(VdomDict): + pass + + +@dataclass(frozen=True) +class Seconds: + minute: int = 60 + hour: int = minute * 60 + day: int = hour * 24 + week: int = day * 7 + month: int = week * 4 + year: int = month * 12 + + +@dataclass(frozen=True) +class AuthLevel: + anonymous: str = "anonymous" + user: str = "user" + admin: str = "admin" + + +@dataclass(frozen=True) +class Viewport: + # TODO: Add kwargs + component: ComponentConstructor | Callable[..., Component] | Callable[..., VdomDict] + """The component to render in the viewport.""" + + args: Sequence = field(default_factory=tuple) + """The arguments to pass to the viewport component.""" + + html_class: str = "" + """HTML class to apply to the viewport.""" + + padding: bool = True + """Whether or not to apply padding to the viewport.""" + + page_title: str | None = None + """The page title to display on the browser tab.""" + + background: str | None = None # TODO: Implement this + """The background property to apply to the webpage.""" + + +@dataclass(frozen=True) +class SidebarTab: + name: str + viewport: Viewport | None = None + on_click: Callable[[SidebarTabEvent], None] | None = None + auth: str = AuthLevel.user + + def __eq__(self, __o: object) -> bool: + return _compare_names(self, __o) + + def __lt__(self, __o: object) -> bool: + return self.name < getattr(__o, "name", "") + + def __gt__(self, __o: object) -> bool: + return self.name > getattr(__o, "name", "") + + +@dataclass(frozen=True) +class SubTab: + # TODO: Add args and kwargs + name: str + component: ComponentConstructor | Callable[..., Component] | Callable[..., VdomDict] + html_class: str = "" + padding: bool = True + on_click: Callable[[SubTabEvent], None] | None = None + auth: str = AuthLevel.user + + def __eq__(self, __o: object) -> bool: + return _compare_names(self, __o) + + def __lt__(self, __o: object) -> bool: + return self.name < getattr(__o, "name", "") + + def __gt__(self, __o: object) -> bool: + return self.name > getattr(__o, "name", "") + + +@dataclass(frozen=True) +class NavGroup: + name: str + icon: Icon | None = None + tabs: SortedSet = field(default_factory=SortedSet) + + def __eq__(self, __o: object) -> bool: + return _compare_names(self, __o) + + def __lt__(self, __o: object) -> bool: + return self.name < getattr(__o, "name", "") + + def __gt__(self, __o: object) -> bool: + return self.name > getattr(__o, "name", "") + + +@dataclass +class FileLink: + path: str + attributes: dict[str, str | None] | None = None + local: bool = True + + +class CSS(FileLink): + ... + + +class JavaScript(FileLink): + ... + + +@dataclass +class SCSS: + path: str + attributes: dict | None = None + + +@dataclass +class HTMLTemplate: + path: str + + +@dataclass +class ModalState: + # FIXME: Redo this when ReactPy supports react-bootstrap + # https://github.com/reactive-python/reactpy/issues/786 + + set_state: SetModalState = lambda _: None + """A function that can be used to set this state.""" + + show: bool = False + """A toggle to set the modal's visibility.""" + + modal_intent: ComponentConstructor | None = None + """The modal that needs to be loaded.""" + + args: Sequence = field(default_factory=tuple) + """The arguments to pass to the modal component.""" + + kwargs: dict = field(default_factory=dict) + """The keyword arguments to pass to the modal component.""" + + _modal: ComponentConstructor | None = None + """The currently visible modal.""" + + def reset_modal(self) -> None: + """Resets the modal to defaults.""" + self.show = False + self.modal_intent = None + self._modal = None + self.args = [] + self.kwargs = {} + + +SetModalState = Callable[[ModalState], None] +ModalStateContext: Context[ModalState] = create_context(ModalState()) + + +@dataclass +class HomepageState: + set_state: SetHomepageState = lambda _: None + """A function that can be used to set this state.""" + + viewport_loading: bool = False + """A toggle to manually set the viewport loading state. This is only used + by user defined viewport components.""" + + viewport_intent: Viewport | None = None + """The viewport that needs to be loaded.""" + + _viewport: Viewport | None = None + """The currently visible viewport.""" + + +SetHomepageState = Callable[[HomepageState], None] +HomepageStateContext: Context[HomepageState] = create_context(HomepageState()) + + +@dataclass +class AppStoreState: + # TODO: Delete this and use TabbedViewportState + set_state: SetAppStoreState = lambda _: None + """A function that can be used to set this state.""" + + tab: ComponentConstructor | None = None + """The current app store tab being rendered.""" + + tab_args: Sequence = field(default_factory=list) + """The arguments to pass to the tab component.""" + + tab_kwargs: dict = field(default_factory=dict) + """The keyword arguments to pass to the tab component.""" + + def reset_tab(self) -> None: + """Resets the tab to defaults.""" + self.tab = None + self.tab_args = [] + self.tab_kwargs = {} + + +SetAppStoreState = Callable[[AppStoreState], None] +AppStoreStateContext: Context[AppStoreState] = create_context(AppStoreState()) + + +@dataclass +class TabbedViewportState: + tab: SubTab | None + """The current subtab being rendered.""" + + set_state: SetTabbedViewportState = lambda _: None + """A function that can be used to set this state.""" + + +SetTabbedViewportState = Callable[[TabbedViewportState], None] +TabbedViewportStateContext: Context[TabbedViewportState] = create_context( + TabbedViewportState(None) +) + + +@dataclass +class SidebarTabEvent: + event: dict + tab: SidebarTab + connection: Connection + homepage_state: HomepageState + + +@dataclass +class SubTabEvent: + event: dict + tab: SubTab + connection: Connection + homepage_state: HomepageState + tabbed_viewport_state: TabbedViewportState + + +def _compare_names(self, __o): + if isinstance(__o, str): + return self.name.lower() == __o.lower() + return self.name.lower() == __o.name.lower() diff --git a/conreq/urls.py b/conreq/urls.py index bc603543..fb0a2d2e 100644 --- a/conreq/urls.py +++ b/conreq/urls.py @@ -1,117 +1,27 @@ -"""Conreq URL Configuration +"""Conreq URL Configuration""" -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/3.0/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.conf import settings -from django.contrib import admin -from django.contrib.auth import views as auth_views from django.urls import include, path from django.views.generic.base import RedirectView -from conreq.utils.environment import get_base_url, get_debug -from conreq.utils.generic import list_modules_with +from conreq.utils.environment import get_base_url, get_home_url -APPS_DIR = getattr(settings, "APPS_DIR") -DEBUG = get_debug() -BASE_URL = get_base_url() +BASE_URL = get_base_url(prepend_slash=False, empty_if_unset=True) +HOME_URL = get_home_url(prepend_slash=False) +external_urls = [ + path("reactpy/", include("reactpy_django.http.urls")), +] +"""Any URL patterns not contained within the Conreq namespace, such as URLs made by user apps or external packages.""" urlpatterns = [ - path("", include("conreq.core.base.urls")), - path("", include("conreq.core.pwa.urls")), path( - "sign_in/", - auth_views.LoginView.as_view(template_name="registration/sign_in.html"), - name="sign_in", + BASE_URL, include("conreq._core.base.urls", namespace="conreq"), name="base_url" ), - path("sign_out/", auth_views.logout_then_login, name="sign_out"), - path("sign_up/", include("conreq.core.sign_up.urls")), - path("request/", include("conreq.core.user_requests.urls")), - path("password_reset/", include("conreq.core.password_reset.urls")), - # Viewport Locations - path("discover/", include("conreq.core.discover.urls")), - path("more_info/", include("conreq.core.more_info.urls")), - path("report_issue/", include("conreq.core.issue_reporting.urls")), - path("search/", include("conreq.core.search.urls")), - path("manage_users/", include("conreq.core.manage_users.urls")), - path("server_settings/", include("conreq.core.server_settings.urls")), - path("api/v1/", include("conreq.core.api.urls")), + path(BASE_URL, include(external_urls)), ] - -# Add User Installed Apps URLS -for app_name, module_path in list_modules_with(APPS_DIR, "urls"): - urlpatterns.insert(0, path(app_name + "/", include(module_path))) - -# Debug tools -if DEBUG: - # Performance analysis tool - urlpatterns.append(path("silk/", include("silk.urls", namespace="silk"))) - # Ability to edit the DB from admin/ - urlpatterns.append(path("admin/docs/", include("django.contrib.admindocs.urls"))) - urlpatterns.append(path("admin/", admin.site.urls)) - - # Django Rest Framework documentation (Swagger and Redoc) - # pylint: disable=ungrouped-imports - from django.urls import re_path - from drf_yasg import openapi - from drf_yasg.views import get_schema_view - from rest_framework import permissions - - SchemaView = get_schema_view( - openapi.Info( - title="Conreq API Endpoints", - default_version="v1", - description=""" - Outline for all endpoints available within this Conreq instance. - - All endpoints require an API key either in **HTTP Header (Authorization: Api-Key)** or in the **URL Parameter (apikey)**. - - Token Authentication is performed using **HTTP Header (Authorization: Token)**. Session Authentication can alternatively be performed. - """, - contact=openapi.Contact(email="archiethemonger@gmail.com"), - license=openapi.License(name="GPL-3.0 License"), - ), - public=True, - permission_classes=[permissions.AllowAny], - ) - - docs_urlpatterns = [ - re_path( - r"^swagger(?P\.json|\.yaml)$", - SchemaView.without_ui(cache_timeout=0), - name="schema-json", - ), - re_path( - r"^swagger/$", - SchemaView.with_ui("swagger", cache_timeout=0), - name="schema-swagger-ui", - ), - re_path( - r"^redoc/$", - SchemaView.with_ui("redoc", cache_timeout=0), - name="schema-redoc", - ), - ] - - for pattern in docs_urlpatterns: - urlpatterns.append(pattern) +"""Conreq's root URL configuration.""" -# Wrap the urlpatterns in BASE_URL if required if BASE_URL: - urlpatterns = [ - path("", RedirectView.as_view(url=BASE_URL)), - path(BASE_URL[1:] + "/", include(urlpatterns)), - ] + urlpatterns.insert(0, path("", RedirectView.as_view(url=BASE_URL))) # type: ignore diff --git a/conreq/utils/api.py b/conreq/utils/api.py new file mode 100644 index 00000000..54ff8f98 --- /dev/null +++ b/conreq/utils/api.py @@ -0,0 +1,111 @@ +from dataclasses import dataclass +from typing import Any, Optional, Union + +from drf_spectacular.utils import ( + OpenApiExample, + OpenApiParameter, + _SerializerType, + extend_schema, +) +from rest_framework.decorators import api_view +from rest_framework.fields import empty +from rest_framework.response import Response + + +@dataclass +class APIDocs: + """Information that can be passed into an `documented_api`. + See drf-spectacular docs for more information.""" + + # pylint: disable=too-many-instance-attributes + + operation_id: Optional[str] = None + """replaces the auto-generated operation_id. make sure there + are no naming collisions.""" + + parameters: Optional[list[Union[OpenApiParameter, _SerializerType]]] = None + """list of additional or replacement parameters added to the + auto-discovered fields.""" + + responses: Any = empty + """replaces the discovered Serializer. Takes a variety of + inputs that can be used individually or combined + + - ``Serializer`` class + - ``Serializer`` instance (e.g. ``Serializer(many=True)`` for listings) + - basic types or instances of ``OpenApiTypes`` + - :class:`.OpenApiResponse` for bundling any of the other choices together with + either a dedicated response description and/or examples. + - :class:`.PolymorphicProxySerializer` for signaling that + the operation may yield data from different serializers depending + on the circumstances. + - ``dict`` with status codes as keys and one of the above as values. + Additionally in this case, it is also possible to provide a raw schema dict + as value. + - ``dict`` with tuples (status_code, media_type) as keys and one of the above + as values. Additionally in this case, it is also possible to provide a raw + schema dict as value.""" + + request: Any = empty + """replaces the discovered ``Serializer``. Takes a variety of inputs + + - ``Serializer`` class/instance + - basic types or instances of ``OpenApiTypes`` + - :class:`.PolymorphicProxySerializer` for signaling that the operation + accepts a set of different types of objects. + - ``dict`` with media_type as keys and one of the above as values. Additionally in + this case, it is also possible to provide a raw schema dict as value.""" + + auth: Optional[list[str]] = None + """replace discovered auth with explicit list of auth methods""" + + description: Optional[str] = None + """replaces discovered doc strings""" + + summary: Optional[str] = None + """an optional short summary of the description""" + + deprecated: Optional[bool] = None + """mark operation as deprecated""" + + tags: Optional[list[str]] = None + """override default list of tags""" + + filters: Optional[bool] = None + """ignore list detection and forcefully enable/disable filter discovery""" + + exclude: bool = False + """set True to exclude operation from schema""" + + operation: Optional[dict] = None + """manually override what auto-discovery would generate. you must + provide a OpenAPI3-compliant dictionary that gets directly translated to YAML.""" + + methods: Optional[list[str]] = None + """scope extend_schema to specific methods. matches all by default.""" + + versions: Optional[list[str]] = None + """scope extend_schema to specific API version. matches all by default.""" + + examples: Optional[list[OpenApiExample]] = None + """attach request/response examples to the operation""" + + extensions: Optional[dict[str, Any]] = None + """specification extensions, e.g. ``x-badges``, ``x-code-samples``, etc.""" + + +@api_view(["GET"]) +def stub(*_, **__): + """This is a stub for an endpoint that has not yet been developed.""" + return Response({"error": "This endpoint is not yet developed."}) + + +def extend_docs(docs: APIDocs): + """A decorator that applies a OpenAPI schema to an API method. + + For more information, see the drf-spectacular `extend_schema` docs.""" + + def decorator(view_method): + return extend_schema(**docs.__dict__)(view_method) + + return decorator diff --git a/conreq/utils/apps.py b/conreq/utils/apps.py new file mode 100644 index 00000000..5de22351 --- /dev/null +++ b/conreq/utils/apps.py @@ -0,0 +1,25 @@ +import importlib + +from conreq.utils.modules import find_wildcards, validate_conreq_modules +from conreq.utils.packages import find_packages, packages_to_modules + + +def find_apps(show_disabled: bool = False) -> set[str]: + """Returns all apps within installed packages. Apps must be declared + within a package's `conreq_apps` list. If the declared app contains a + trailing wildcard, all modules within the given directory are considered Django apps. + """ + apps = set() + user_packages = find_packages(show_disabled=show_disabled) + modules = validate_conreq_modules(packages_to_modules(*user_packages)) + + for module_str in modules: + module = importlib.import_module(module_str) + conreq_apps = getattr(module, "conreq_apps", None) + if isinstance(conreq_apps, list): + for app in conreq_apps: + if app.endswith(".*"): + apps.update(find_wildcards(app)) + else: + apps.add(app) + return apps diff --git a/conreq/utils/backup.py b/conreq/utils/backup.py new file mode 100644 index 00000000..7f7518b5 --- /dev/null +++ b/conreq/utils/backup.py @@ -0,0 +1,76 @@ +import contextlib +import os +import shutil +from datetime import datetime, timedelta +from glob import glob +from pathlib import Path + +from django.core.management import call_command + + +def backup_now(): + """Performs the backup process at the current timestamp.""" + # TODO: Create an API for developers to add on their own backup steps during this function call + # pylint: disable=import-outside-toplevel + from django.conf import settings + + backup_date = datetime.now().strftime(settings.BACKUP_DATE_FORMAT) + backup_path = Path(settings.BACKUP_DIR / backup_date) + db_backup_path = backup_path / "database" + os.makedirs(db_backup_path) + for db_name in settings.DATABASES: + call_command( + "dumpdata", + "--database", + db_name, + "--output", + f"{backup_path / 'database' / db_name}.json.{settings.BACKUP_COMPRESSION}", + "--verbosity", + "0", + ) + + delete_old_backups() + + +def backup_folders() -> list[Path]: + """Returns a sorted list of backup folders.""" + # pylint: disable=import-outside-toplevel + from django.conf import settings + + backup_dir_contents = sorted(glob(str(settings.BACKUP_DIR / "*")), reverse=True) + folders = [] + for item in backup_dir_contents: + with contextlib.suppress(ValueError): + path = Path(item) + name = path.name if path.is_dir() else "" + # Only append folders that follow our format + datetime.strptime(name, settings.BACKUP_DATE_FORMAT) + folders.append(path) + return folders + + +def backup_needed() -> bool: + """Returns True if a database backup is needed.""" + # pylint: disable=import-outside-toplevel + from django.conf import settings + + backups = backup_folders() + if not backups: + return True + latest_backup = backups[0] + folder_name = latest_backup.name + backup_date = datetime.strptime(folder_name, settings.BACKUP_DATE_FORMAT) + return datetime.now() - timedelta(weeks=1) > backup_date + + +def delete_old_backups(): + """Deletes old backups beyond the maximum number of backups allowed.""" + # pylint: disable=import-outside-toplevel + from django.conf import settings + + backups = backup_folders() + if len(backups) <= settings.BACKUP_KEEP_MAX: + return + + for folder in backups[settings.BACKUP_KEEP_MAX :]: + shutil.rmtree(folder) diff --git a/conreq/utils/cache.py b/conreq/utils/cache.py deleted file mode 100644 index f539c0e5..00000000 --- a/conreq/utils/cache.py +++ /dev/null @@ -1,242 +0,0 @@ -"""Django caching wrapper and cache related capabilities.""" -from collections.abc import Callable - -from django.core.cache import cache -from huey.contrib.djhuey import db_task - -from conreq.utils import log -from conreq.utils.generic import clean_string -from conreq.utils.threads import ReturnThread - -# Globals -DEFAULT_CACHE_DURATION = 60 * 60 # Time in seconds - -# Creating a logger (for log files) -_logger = log.get_logger(__name__) - - -def generate_cache_key( - cache_name: str, cache_args: list, cache_kwargs: dict, key: str -) -> str: - """Generates a key to be used with django caching""" - return clean_string( - cache_name - + "_args" - + str(cache_args) - + "_kwargs" - + str(cache_kwargs) - + "_key" - + str(key) - ) - - -def obtain_key_from_cache_key(cache_key: str) -> str: - """Parses the cache key and returns any values after the string '_key'""" - return cache_key[cache_key.find("_key") + len("_key") :] - - -@db_task() -def __cache_set_many(missing_keys, cache_duration): - cache.set_many(missing_keys, cache_duration) - - -@db_task() -def __cache_set(cache_key, function_results, cache_duration): - cache.set(cache_key, function_results, cache_duration) - - -def handler( - cache_name: str, - page_key: str = "", - function: Callable = None, - force_update_cache: bool = False, - cache_duration: int = DEFAULT_CACHE_DURATION, - args: list = (), - kwargs: dict = None, -) -> any: - """Handles caching for results and data. - - Args: - cache_name: Name prepended to cache get/set calls. - page_key: A value to use as a page key. - function: The function to be executed (if cached values are expired). - If no function is provided, whatever was stored in cache is always returned. - force_update_cache: Forces execution of function, regardless if value is expired or not. Does not work with multi execution. - cache_duration: Duration in seconds that the cached value should be valid for. - args: A list of arguements to pass into function. - kwargs: A dictionary of keyworded arguements to pass into function. - """ - - cached_results = None - if kwargs is None: - kwargs = {} - # Looks through cache and will perform a search if needed. - try: - log.handler( - cache_name + " - Accessed.", - log.DEBUG, - _logger, - ) - - # Get the cached value - cache_key = generate_cache_key(cache_name, args, kwargs, page_key) - cached_results = cache.get(cache_key) - log.handler( - cache_name + " - Generated cache key " + cache_key, - log.DEBUG, - _logger, - ) - - # No function was provided, just return a bare cache value - if function is None: - log.handler( - cache_name + " - Requested raw cache values.", - log.DEBUG, - _logger, - ) - return cached_results - - # If the user wants to force update the cache, nothing - # was in cache, or cache was expired, run function() - if cached_results is None or force_update_cache: - function_results = function(*args, **kwargs) - if function_results: - __cache_set(cache_key, function_results, cache_duration) - log.handler( - cache_name + " - " + function.__name__ + "()", - log.INFO, - _logger, - ) - return function_results - - if cached_results is None: - log.handler( - cache_name + " - Cache key " + cache_key + " was empty!", - log.INFO, - _logger, - ) - - # If a value was in cache and not expired, return that value - return cached_results - - except Exception: - # If the function threw an exception, return none. - if hasattr(function, "__name__"): - log.handler( - "Function " + function.__name__ + " failed to execute!", - log.ERROR, - _logger, - ) - else: - log.handler( - "Cache handler has failed! Function: " - + str(function) - + " Cache Name: " - + str(cache_name) - + " Page Key: " - + str(page_key), - log.ERROR, - _logger, - ) - return None - - -def multi_handler( - cache_name: str, - functions: dict[dict], - cache_duration: int = DEFAULT_CACHE_DURATION, - timeout: int = 5, -) -> dict[dict]: - """Retrieve, set, and potentially execute multiple cache functions at once. - Functions must follow this format: - - { - page_key : { - "function": function_value, - "args": [args_values], - "kwargs": {kwargs_value}, - }, - ... - } - """ - try: - log.handler( - cache_name + " - Accessed.", - log.DEBUG, - _logger, - ) - - requested_keys = [] - for key, value in functions.items(): - cache_key = generate_cache_key( - cache_name, value["args"], value["kwargs"], key - ) - log.handler( - cache_name - + " - Cache multi execution generated cache key " - + cache_key, - log.DEBUG, - _logger, - ) - requested_keys.append(cache_key) - - # Search cache for all keys - cached_results = cache.get_many(requested_keys) - log.handler( - cache_name - + " - Cache multi execution detected " - + str(len(cached_results)) - + " available keys.", - log.INFO, - _logger, - ) - - # If nothing was in cache, or cache was expired, run function() - thread_list = [] - for cache_key in requested_keys: - if not cached_results.__contains__(cache_key): - key = obtain_key_from_cache_key(cache_key) - thread = ReturnThread( - target=functions[key]["function"], - args=functions[key]["args"], - kwargs=functions[key]["kwargs"], - ) - thread.start() - thread_list.append((cache_key, thread)) - - missing_keys = {} - for key, thread in thread_list: - missing_keys[key] = thread.join(timeout=timeout) - - # Set values in cache for any newly executed functions - if bool(missing_keys): - log.handler( - cache_name - + " - Cache multi execution detected " - + str(len(missing_keys)) - + " missing keys.", - log.INFO, - _logger, - ) - __cache_set_many(missing_keys, cache_duration) - - # Return all results - cached_results.update(missing_keys) - - # If results were none, log it. - if cached_results is None: - log.handler( - cache_name + " - Cache multi execution generated no results!", - log.WARNING, - _logger, - ) - - return cached_results - - except Exception: - log.handler( - "Functions " + str(functions) + " failed to execute!", - log.ERROR, - _logger, - ) - return None diff --git a/conreq/utils/database.py b/conreq/utils/database.py index 52f9cf1c..32e76e52 100644 --- a/conreq/utils/database.py +++ b/conreq/utils/database.py @@ -1,8 +1,9 @@ -def add_unique_to_db(model, **kwargs): - """Adds a row to the database only if all parameters are unique.""" - if not model.objects.filter(**kwargs): - new_request = model(**kwargs) - new_request.clean_fields() - new_request.save() - return new_request - return None +def add_unique(model, **kwargs) -> bool: + """Save to the database only if the model is fully unique. + Returns `True` if the operation was successful.""" + new_request = model(**kwargs) + new_request.full_clean() + if model.objects.filter(**kwargs): + return False + new_request.save() + return True diff --git a/conreq/utils/debug.py b/conreq/utils/debug.py deleted file mode 100644 index fe7614a0..00000000 --- a/conreq/utils/debug.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Capabilities used while in DEBUG, that turn off in production environments.""" -from functools import wraps - -from conreq.utils.environment import get_debug - - -# pylint: disable=invalid-name,too-few-public-methods -# Helper function for doing nothing -def do_nothing(function=None): - def decorator(view_func): - @wraps(view_func) - def _wrapped_view(request, *args, **kwargs): - return view_func(request, *args, **kwargs) - - return _wrapped_view - - return decorator(function) - - -# Helper class for doing nothing -class DoNothing: - def __call__(self, target): - return target - - -# Set functionality depending on whether we are in DEBUG=True -if get_debug(): - from silk.profiling.profiler import silk_profile - - class performance_metrics(silk_profile): - pass - - -else: - - class performance_metrics(DoNothing): - pass diff --git a/conreq/utils/dependencies.py b/conreq/utils/dependencies.py new file mode 100644 index 00000000..8b788e1a --- /dev/null +++ b/conreq/utils/dependencies.py @@ -0,0 +1,30 @@ +import subprocess + +import requirements + + +class DependencyConflict(Exception): + pass + + +def find_py_dependencies(ignore_conflicts: bool = False) -> set[str]: + """Returns a set of all Python dependencies required by this Conreq instance.""" + with open("requirements.txt", encoding="utf-8") as req_file: + all_python_reqs: set[str] = set() + for req in requirements.parse(req_file): + req_string = req.name or req.uri + if not req_string: + continue + + if req.specs: + req_string += ",".join( + [(operator + version) for operator, version in req.specs], + ) + all_python_reqs.add(req_string) + + return all_python_reqs + + +def install_py_dependencies() -> None: + """Installs all dependencies required by this Conreq instance.""" + subprocess.run(["pip", "install", *find_py_dependencies()], check=True) diff --git a/conreq/utils/environment.py b/conreq/utils/environment.py index 612f53aa..e8f857ce 100644 --- a/conreq/utils/environment.py +++ b/conreq/utils/environment.py @@ -1,103 +1,178 @@ -import functools +import json import os -from typing import Optional +from pathlib import Path +from typing import Any, Tuple, Type import dotenv - -from conreq.utils.generic import str_to_bool, str_to_int - -ENV_PREFIX = os.environ.get("CONREQ_ENV_PREFIX", "").rstrip("_").upper() +from dotenv import dotenv_values + +DB_ENGINES = {"MYSQL", "SQLITE3"} +_HOME_URL = None +_BASE_URL = None +_SAFE_MODE = None +_DEBUG_MODE = None +_DB_ENGINE = None +ENV_PREFIX = os.environ.get("CONREQ_ENV_PREFIX", "CONREQ").rstrip("_").upper() if ENV_PREFIX: - ENV_PREFIX = ENV_PREFIX + "_" + ENV_PREFIX += "_" -@functools.cache -def _dotenv_path() -> str: - """Fetches the .env file path set during Conreq startup.""" - return os.environ["CONREQ_DOTENV_FILE"] +def dotenv_path() -> Path: + """Load the .env path from a different context to avoid circular imports.""" + # pylint: disable=import-outside-toplevel + from conreq.settings import DOTENV_FILE - -@functools.cache -def _get_str_from_dotenv(name: str, default_value: str = "") -> str: - """Fetches a value from the .env file.""" - value = dotenv.main.DotEnv(_dotenv_path()).get(str(name).upper()) - if not value: - value = default_value - else: - value = str(value) - return value + return DOTENV_FILE -@functools.cache -def get_str_from_env( - name: str, default_value: str = "", sys_env=True, dot_env=True -) -> str: - """Obtains a string from an environment variable""" - value = "" - if sys_env: - value = os.environ.get(ENV_PREFIX + str(name).upper(), "") - if dot_env and not value: - value = _get_str_from_dotenv(str(name).upper()) +def _parse_env_value(value: Any, default_value: Any, return_type: Type) -> Any: + """Attempts to convert a value to the requested return type, if needed.""" if not value: return default_value - return value + if return_type is bool and isinstance(value, str): + try: + return _str_to_bool(value) + except ValueError: + return default_value + if return_type in {list, dict} and isinstance(value, str): + value = json.loads(value) + return value if isinstance(value, return_type) else return_type(value) + + +def get_env( + name: str, + default_value: Any = None, + sys_env=True, + dot_env=True, + return_type: Type = str, +) -> Any: + """Returns an environment variable from either system variables or Conreq's dotenv file.""" + if not name or not isinstance(name, str): + raise ValueError("Did not provide a valid environment variable name!") + + value = os.environ.get(ENV_PREFIX + name.upper()) if sys_env else None + if dot_env and not value: + value = dotenv_values(dotenv_path()).get(name.upper()) + return _parse_env_value(value, default_value, return_type) -@functools.cache -def get_bool_from_env( - name: str, default_value: bool = False, sys_env=True, dot_env=True -) -> bool: - """Obtains a boolean from an environment variable""" - value = get_str_from_env(name, str(default_value), sys_env, dot_env) - return str_to_bool(value, default_value) +def get_debug_mode() -> bool: + """Shortcut to obtain DEBUG from environment variables""" + # pylint: disable=global-statement + global _DEBUG_MODE -@functools.cache -def get_int_from_env( - name: str, default_value: int = 0, sys_env=True, dot_env=True -) -> str: - """Obtains a integer from an environment variable""" - value = get_str_from_env(name, str(default_value), sys_env=sys_env, dot_env=dot_env) - return str_to_int(value, default_value) + if _DEBUG_MODE is None: + _DEBUG_MODE = get_env("DEBUG_MODE", False, return_type=bool) + return _DEBUG_MODE -@functools.cache -def get_debug() -> bool: - """Shortcut to obtain DEBUG from environment variables""" - return get_bool_from_env("DEBUG", False) + +def get_safe_mode() -> bool: + """Shortcut to obtain SAFE_MODE from environment variables""" + # pylint: disable=global-statement + global _SAFE_MODE + + if _SAFE_MODE is None: + _SAFE_MODE = get_env("SAFE_MODE", False, return_type=bool) + + return _SAFE_MODE -@functools.cache -def get_base_url() -> str: - """Obtains the base URL from the environment variables""" - base_url = get_str_from_env("BASE_URL") - if isinstance(base_url, str) and base_url: +def get_base_url( + prepend_slash: bool = True, append_slash: bool = True, empty_if_unset: bool = False +) -> str: + """Obtains the BASE_URL from the environment variables""" + # pylint: disable=global-statement + global _BASE_URL + + if _BASE_URL is None: + _BASE_URL = get_env("BASE_URL", "") + + base_url = _BASE_URL + if base_url: base_url = base_url.replace("/", "").replace("\\", "") - base_url = "/" + base_url + + if empty_if_unset and not base_url: + return base_url + + if append_slash: + base_url = f"{base_url}/" + if prepend_slash: + base_url = f"/{base_url}" + base_url = base_url.replace("//", "/") return base_url -@functools.cache -def get_database_type() -> str: +def get_home_url( + prepend_slash: bool = True, append_slash: bool = True, empty_if_unset: bool = False +) -> str: + """Obtains the HOME_URL from the environment variables""" + # pylint: disable=global-statement + global _HOME_URL + + if _HOME_URL is None: + _HOME_URL = get_env("HOME_URL", "home") + + home_url = _HOME_URL + if home_url: + home_url = home_url.replace("/", "").replace("\\", "") + + if empty_if_unset and not home_url: + return home_url + + if append_slash: + home_url = f"{home_url}/" + if prepend_slash: + home_url = f"/{home_url}" + home_url = home_url.replace("//", "/") + return home_url + + +def get_database_engine() -> str: """Determines what type of database the current Conreq instance should be using. Ex) MYSQL, SQLITE, etc.""" - db_engine = get_str_from_env("DB_ENGINE") - if db_engine.upper() == "MYSQL": - return "MYSQL" - return "SQLITE3" + # pylint: disable=global-statement + global _DB_ENGINE + + if _DB_ENGINE is None: + _DB_ENGINE = get_env("DB_ENGINE", "").upper() + + return _DB_ENGINE if _DB_ENGINE in DB_ENGINES else "SQLITE3" -def set_env(name: str, value: str, sys_env=False, dot_env=True) -> Optional[str]: +def set_env(name: str, value: Any, sys_env=False, dot_env=True) -> Tuple[str, Any]: """Sets a value in either the system environment, and/or the .env file.""" + if value is None: + value = "" if sys_env: - os.environ[ENV_PREFIX + str(name).upper()] = str(value) + os.environ[ENV_PREFIX + name.upper()] = str(value) if dot_env: - dotenv.set_key(_dotenv_path(), str(name).upper(), str(value)) + dotenv.set_key( + dotenv_path(), + name.upper(), + json.dumps(value) if isinstance(value, (dict, list)) else str(value), + ) return (name, value) -def remove_env(name: str, sys_env=False, dot_env=True) -> None: +def delete_env(name: str, sys_env=False, dot_env=True) -> None: """Removes a value in either the system environment, and/or the .env file.""" - if sys_env and os.environ.get(ENV_PREFIX + str(name).upper()) is not None: - del os.environ[ENV_PREFIX + str(name).upper()] + if sys_env and os.environ.get(ENV_PREFIX + name.upper()) is not None: + del os.environ[ENV_PREFIX + name.upper()] if dot_env: - dotenv.unset_key(_dotenv_path(), str(name).upper()) + dotenv.unset_key(dotenv_path(), name.upper()) + + +def _str_to_bool(val: str): + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = val.lower() + if val in {"y", "yes", "t", "true", "on", "1"}: + return True + if val in {"n", "no", "f", "false", "off", "0"}: + return False + raise ValueError(f"invalid truth value {val}") diff --git a/conreq/utils/forms.py b/conreq/utils/forms.py new file mode 100644 index 00000000..53ed0126 --- /dev/null +++ b/conreq/utils/forms.py @@ -0,0 +1,20 @@ +from typing import Type + +from conreq.utils.environment import get_env + + +class EnvFieldMixin: + """Generic field to read/write dot env values within a HTML form.""" + + # pylint: disable= too-few-public-methods + + env_type: Type = str + + def __init__(self, env_name, *, required=False, **kwargs) -> None: + super().__init__(required=required, **kwargs) # type: ignore + self.env_name = env_name + + def prepare_value(self, _): + return get_env( + self.env_name, default_value=self.initial, return_type=self.env_type # type: ignore + ) diff --git a/conreq/utils/generic.py b/conreq/utils/generic.py index 6d09c7db..1f31b009 100644 --- a/conreq/utils/generic.py +++ b/conreq/utils/generic.py @@ -1,61 +1,47 @@ """Generic functions to be used anywhere. All functions only have stdlib dependencies.""" -import os -import pkgutil from re import sub -def is_key_value_in_list( - key: any, value: any, search_list: list, return_item: bool = False -) -> bool: - """Iterate through a list of dicts to check if a specific key/value pair exists.""" - if isinstance(search_list, list): - for item in search_list: - if item.__contains__(key) and item[key] == value: - if return_item: - return item - return True - return False - - -def remove_duplicates_from_list(duplicate_list: list) -> list: - """Returns a list that contains no duplicate values""" - return list(dict.fromkeys(duplicate_list)) - - -def clean_string(string: str) -> str: - """Removes non-alphanumerics from a string""" - return sub(r"\W+", "", string).lower() - - -def str_to_bool(string: str, default_value: bool = True) -> bool: - """Converts a string into a boolean.""" - if isinstance(string, str): - if string.lower() == "true" or string == "1": - return True - if string.lower() == "false" or string == "0": - return False - return default_value - - -def str_to_int(value: str, default_value: int = 0) -> int: - """Converts a string into a integer.""" - if isinstance(value, str) and value.isdigit(): - return int(value) - return default_value - - -def list_modules(path: str, prefix: str = "") -> list[str]: - """Returns all modules in a path""" - return [name for _, name, _ in pkgutil.iter_modules([path], prefix=prefix)] - - -def list_modules_with(path: str, submodule_name: str, prefix: str = "") -> list[str]: - """Returns a tuple of all modules containing module name and an importable path to 'example.module.urls'""" - modules = list_modules(path) - module_files = [] - for module in modules: - module_path = os.path.join(path, module) - if submodule_name in list_modules(module_path): - urls_path = prefix + module + "." + submodule_name - module_files.append((module, urls_path)) - return module_files +def clean_string( + string: str, + allow_ascii: bool = True, + rm_spaces: bool = True, + rm_repeated_spaces: bool = True, + rm_special_chars: bool = True, + lowercase: bool = True, + spaces: str = "-", +) -> str: + """Removes non-alphanumerics from a string.""" + new_string = string + if allow_ascii: + new_string = string.encode("ascii", "ignore").decode() + if rm_spaces: + new_string = new_string.replace(" ", spaces) + if rm_special_chars: + new_string = sub(r"[^a-zA-Z0-9 ]+", "", new_string) + if lowercase: + new_string = new_string.lower() + if rm_repeated_spaces: + new_string = sub(r" +", " ", new_string) + return new_string + + +class DoNothingDecorator: + """Decorator that does nothing.""" + + # pylint: disable=too-few-public-methods + def __init__(self, *args, **kwargs) -> None: + pass + + def __call__(self, target, *args, **kwargs): + return target + + +class DoNothingWith: + """Class usable in a python `with` statement that does nothing.""" + + def __enter__(self): + pass + + def __exit__(self, *_): + pass diff --git a/conreq/utils/log.py b/conreq/utils/log.py deleted file mode 100644 index 4df500c4..00000000 --- a/conreq/utils/log.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Conreq Logging: Simplified logging module.""" -import logging -from logging import Logger -from traceback import format_exc - -# Globals -DEBUG = logging.DEBUG -INFO = logging.INFO -WARNING = logging.WARNING -ERROR = logging.ERROR -CRITICAL = logging.CRITICAL - -# Function reference to Py Logging getLogger -get_logger = logging.getLogger - - -def handler(msg: str, level: int, logger: Logger) -> None: - """Submits a message to the log handler. - - Args: - message: A string containing a verbose log message. - logger: A logger objected obtained from get_logger(). - level: Logging module log level (ex. logging.WARNING) - """ - # Remove trailing and proceeding whitespace from the message - message = str(msg).rstrip("\n").rstrip().lstrip("\n").lstrip() - - # Log within a different stream depending on severity - if level == DEBUG: - logger.debug(message) - elif level == INFO: - logger.info(message) - elif level == WARNING: - logger.warning(message) - elif level == ERROR: - logger.error(message + "\n" + format_exc()) - elif level == CRITICAL: - logger.critical(message + "\n" + format_exc()) diff --git a/conreq/utils/logging.py b/conreq/utils/logging.py new file mode 100644 index 00000000..ad93ffc3 --- /dev/null +++ b/conreq/utils/logging.py @@ -0,0 +1,15 @@ +import logging +import re + + +class SensitiveFormatter(logging.Formatter): + """Formatter that removes sensitive information in URLs.""" + + @staticmethod + def _filter(s): + # Removes query parameters from the URL + return re.sub(r"( /)(\S+)([?])(\S+?[=]\S+)", r"\1\2", s) + + def format(self, record): + original = logging.Formatter.format(self, record) + return self._filter(original) diff --git a/conreq/utils/models.py b/conreq/utils/models.py new file mode 100644 index 00000000..4767fdb2 --- /dev/null +++ b/conreq/utils/models.py @@ -0,0 +1,17 @@ +import os +import uuid + +from django.utils.deconstruct import deconstructible + + +@deconstructible +class UUIDFilePath: + """Use this within an `upload_to = ...` parameter within a `FieldField` or + `ImageField` in order to automatically change the filename to a UUID.""" + + def __init__(self, path: str = ""): + self.path = os.path.join(path, "%s%s") + + def __call__(self, _, filename: str): + extension = os.path.splitext(filename)[1] + return str(self.path % (uuid.uuid4(), extension)).lstrip("/") diff --git a/conreq/utils/modules.py b/conreq/utils/modules.py new file mode 100644 index 00000000..b1c6a657 --- /dev/null +++ b/conreq/utils/modules.py @@ -0,0 +1,121 @@ +import importlib +import inspect +import os +import pkgutil +from importlib import import_module as _import_module +from logging import getLogger +from pathlib import Path +from types import ModuleType + +_logger = getLogger(__name__) + + +def import_module( + dotted_path: str, *args, fail_silently: bool = False, **kwargs +) -> ModuleType | None: + """ + Light wrapper for `importlib.import_module` that can fail silently. + """ + try: + return _import_module(dotted_path, *args, **kwargs) + except ModuleNotFoundError as err: + if not fail_silently: + raise ImportError(f"{dotted_path} doesn't exist!") from err + + return None + + +def load(module: str, fail_silently: bool = False) -> ModuleType | None: + """ + Imports a module relative to the caller's parent module and returns + the module reference. Raise ImportError if the import failed. + """ + # pylint: disable=unused-variable + try: + stack = inspect.stack()[1] + full_module_path = getattr(inspect.getmodule(stack[0]), "__name__") + parent_module, current_module = full_module_path.rsplit(".", 1) + return import_module(".".join([parent_module, module]), fail_silently) + except Exception as err: + if not fail_silently: + raise ImportError(f"{module} doesn't exist!") from err + + return None + + +def find_modules(folder_path: str | Path, prefix: str = "") -> list[str]: + """Returns all modules in a path""" + return [ + name for _, name, _ in pkgutil.iter_modules([str(folder_path)], prefix=prefix) + ] + + +def find_modules_with( + folder_path: str, submodule_name: str, prefix: str = "" +) -> list[str]: + """Returns a list of modules containing a submodule with the given name.""" + modules = find_modules(folder_path) + modules_with = [] + + for module in modules: + submodules = os.path.join(folder_path, module) + if submodule_name in find_modules(submodules): + modules_with.append(prefix + module) + + return modules_with + + +def find_wildcards(dotted_path: str) -> set[str]: + """Returns all dotted paths of all modules within a given wildcard directory. + This is currently limited to trailing wildcards.""" + # TODO: Support non-trailing wildcards + + if not dotted_path.endswith(".*"): + raise ValueError(f"App '{dotted_path}' does not end with '.*'.") + + dotted_path = dotted_path[:-2] + apps_container = import_module(dotted_path) + if not apps_container: + _logger.warning( + "\033[93mApp '%s' could not be imported.\033[0m", + dotted_path, + ) + return set() + + module_names = find_modules(apps_container.__path__[0]) + return {f"{dotted_path}.{name}" for name in module_names} + + +def validate_conreq_modules(module_names: list[str]) -> list[str]: + """Check if modules are properly configured for Conreq. + Returns a new list of valid modules.""" + + valid_packages = [] + + for package in module_names: + try: + module = importlib.import_module(package) + except ModuleNotFoundError: + _logger.warning( + "\033[93mPackage '%s' could not be imported.\033[0m", + package, + ) + continue + except Exception: + _logger.exception( + "\033[93mAn unknown error has occurred while importing '%s'.\033[0m", + package, + ) + continue + + if not hasattr(module, "conreq_apps"): + _logger.warning( + "\033[93mApp package '%s' is not properly configured. " + "`conreq_apps` is undefined.\033[0m", + package, + ) + continue + + valid_packages.append(package) + + return valid_packages diff --git a/conreq/utils/packages.py b/conreq/utils/packages.py new file mode 100644 index 00000000..7a6a75a2 --- /dev/null +++ b/conreq/utils/packages.py @@ -0,0 +1,69 @@ +import contextlib +from logging import getLogger +from pathlib import Path + +import pkg_resources + +from conreq.utils.environment import get_env + +_logger = getLogger(__name__) + + +def find_packages(show_disabled: bool = False) -> list[str]: + """Returns all available Conreq packages, typically installed from the app store.""" + installed_packages = get_env("INSTALLED_PACKAGES", [], return_type=list) + if show_disabled: + return installed_packages + disabled_packages = get_env("DISABLED_PACKAGES", [], return_type=list) + return [pkg for pkg in installed_packages if pkg not in disabled_packages] + + +def packages_to_modules(*packages: str) -> list[str]: + """Returns all importable modules within the given packages.""" + + modules = [] + + for pkg in packages: + # Parse eggs + with contextlib.suppress(pkg_resources.DistributionNotFound, FileNotFoundError): + import_names = _parse_top_level_txt(pkg) + if import_names: + modules.extend(import_names) + continue + + # Parse wheel install records + with contextlib.suppress(pkg_resources.DistributionNotFound, FileNotFoundError): + import_names = _parse_records(pkg) + if import_names: + modules.extend(import_names) + continue + + _logger.warning( + "\033[93mCould not determine package info for '%s'. " + "Package may misconfigured or not installed.\033[0m", + pkg, + ) + + return modules + + +def _parse_top_level_txt(package: str) -> list[str]: + """Returns all importable modules within the given package.""" + distribution = pkg_resources.get_distribution(package) + return distribution.get_metadata("top_level.txt").splitlines() + + +def _parse_records(package: str) -> list[str]: + distribution = pkg_resources.get_distribution(package) + install_paths = distribution.get_metadata("RECORD").splitlines() + names = set() + for path in install_paths: + path = path.split(",")[0] + testable_path = Path(path) + if len(testable_path.parts) <= 1: + continue + folder = testable_path.parts[0] + if "." in folder: + continue + names.add(folder) + return list(names) diff --git a/conreq/utils/profiling.py b/conreq/utils/profiling.py new file mode 100644 index 00000000..fa6bb4d2 --- /dev/null +++ b/conreq/utils/profiling.py @@ -0,0 +1,34 @@ +"""Performing profiling capabilities.""" + +from inspect import iscoroutinefunction +from typing import Any, Callable + +from conreq.utils.environment import get_debug_mode +from conreq.utils.generic import DoNothingDecorator + + +def profiled_view(view: Any, name=None) -> Callable: + """Helper utility to add performance profiling to a view class or function, if possible.""" + # Set view profiling capabilities depending on whether DEBUG=True + if get_debug_mode(): + from silk.profiling.profiler import silk_profile as metrics + else: + metrics = DoNothingDecorator + + # Something that isn't a view function, such as a list of urlpatterns + if not callable(view): + return view + + # Async class or function views + # FIXME: Currently not supported by django-silk + if iscoroutinefunction(view) or getattr(view, "view_is_async", False): + return view + + # Sync class view + dotted_path = f"{view.__module__}.{view.__name__}" + if hasattr(view, "as_view"): + view.dispatch = metrics(name=name or dotted_path)(view.dispatch) + return view.as_view() + + # Sync function view + return metrics(name=name or dotted_path)(view) diff --git a/conreq/utils/threads.py b/conreq/utils/threads.py index 6b635d2e..c9c3f25f 100644 --- a/conreq/utils/threads.py +++ b/conreq/utils/threads.py @@ -1,5 +1,14 @@ """Any function that assists in multithreading or multiprocessing""" +from dataclasses import dataclass, field from threading import Thread +from typing import Any, Callable + + +@dataclass +class ThreadTask: + func: Callable + args: list = field(default_factory=list) + kwargs: dict = field(default_factory=dict) class ReturnThread(Thread): @@ -7,7 +16,7 @@ class ReturnThread(Thread): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._return = None # child class's variable, not available in parent. + self._return = None def run(self): """ @@ -15,10 +24,11 @@ def run(self): This child class added a return value. :return: """ - if self._target is not None: - self._return = self._target(*self._args, **self._kwargs) - def join(self, timeout: int = None): + if self._target is not None: # type: ignore + self._return = self._target(*self._args, **self._kwargs) # type: ignore + + def join(self, timeout: float | None = None) -> Any: """ Join normally like the parent class, but added a return value which the parent class join method does not have. @@ -27,51 +37,13 @@ def join(self, timeout: int = None): return self._return -def threaded_execution(function_list: list, args: list, **kwargs: dict) -> list[any]: - """Threaded execution of function calls where all functions utilize the same args/kwargs.""" - thread_list = [] - results = [] - - for function in function_list: - thread = ReturnThread(target=function, args=args, kwargs=kwargs) +def executor(thread_tasks: list[ThreadTask]) -> list[Any]: + """Threaded execution of a list of functions. Returns the results in the same + order that the functions were provided in.""" + started_threads = [] + for task in thread_tasks: + thread = ReturnThread(target=task.func, args=task.args, kwargs=task.kwargs) thread.start() - thread_list.append(thread) - - for thread in thread_list: - results.append(thread.join()) - - return results - - -def threaded_execution_unique_args(functions: list[dict]) -> list[any]: - """Executes functions with unique arguements. It will return all returned values as a list. - Functions must follow this format: - - [{ - "function": foobar, - "args": [], - "kwargs": {}, - }, ... - ] - """ - thread_list = [] - for executable in functions: - thread = ReturnThread( - target=executable["function"], - args=executable.get("args", None), - kwargs=executable.get("kwargs", None), - ) - thread.start() - thread_list.append(thread) - - # Combine the results into one list - results = [] - for index, thread in enumerate(thread_list): - result = None - try: - result = thread.join() - except Exception: - pass - results.insert(index, result) + started_threads.append(thread) - return results + return [thread.join() for thread in started_threads] diff --git a/conreq/utils/user_apps.py b/conreq/utils/user_apps.py deleted file mode 100644 index 75c97dc5..00000000 --- a/conreq/utils/user_apps.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -from importlib import import_module - -from django.conf import settings - -from .generic import list_modules - -APPS_DIR = getattr(settings, "APPS_DIR") - - -def list_user_apps() -> list[str]: - apps_list = [] - user_apps = list_modules(APPS_DIR) - for user_app in user_apps: - package_dict = {} - package_dict["name"] = user_app - package_dict["modules"] = {} - app_dir = os.path.join(APPS_DIR, user_app) - for package in list_modules(app_dir): - sub_app_dir = os.path.join(app_dir, package) - if package == "settings": - module = import_module(user_app + "." + package) - package_dict["settings"] = [ - item for item in dir(module) if not item.startswith("_") - ] - else: - package_dict["modules"][package] = [] - for module in list_modules(sub_app_dir): - package_dict["modules"][package].append( - (module, user_app + "." + package + "." + module) - ) - apps_list.append(package_dict) - - return apps_list - - -def list_user_apps_with(submodule_name: str) -> list[str]: - apps_list = [] - user_apps = list_modules(APPS_DIR) - for user_app in user_apps: - app_dir = os.path.join(APPS_DIR, user_app) - for package in list_modules(app_dir): - sub_app_dir = os.path.join(app_dir, package) - modules = list_modules(sub_app_dir) - if submodule_name in modules: - apps_list.append(user_app + "." + package + "." + submodule_name) - return apps_list diff --git a/conreq/utils/views.py b/conreq/utils/views.py new file mode 100644 index 00000000..9eb1d5a2 --- /dev/null +++ b/conreq/utils/views.py @@ -0,0 +1,145 @@ +"""Any function that assists in views""" +from inspect import isclass + +from django.contrib.auth.decorators import user_passes_test +from django.http import HttpResponse +from django.utils.decorators import method_decorator +from django.views.generic.edit import FormView + +from conreq.types import AuthLevel + + +class CurrentUserOrAdminMixin: + """Mixin for any class based view to block access if the user is not the current + user or an admin. + + To validate the user is modifying a page related to his user ID, you must set + `self.user_id`, or you can set the user ID as a URL parameter. + + By default, the URL parameter is `id`, but can be configured by setting the + `user_id_param` attribute.""" + + user_id = None + user_id_param = "id" + + def dispatch(self, request, *args, **kwargs): + if self.user_id is None: + user_id_string = getattr(request, request.method).get(self.user_id_param) + self.user_id = ( + int(user_id_string) + if isinstance(user_id_string, str) and user_id_string.isnumeric() + else "" + ) + + if request.user.is_superuser or request.user.id == self.user_id: + return super().dispatch(request, *args, **kwargs) # type: ignore + + return HttpResponse(status=403) + + +class SuccessCurrentUrlMixin: + """Mixin for `UpdateView` to return success at the current URL, if + a success_url is not set.""" + + # pylint: disable=too-few-public-methods + + def get_success_url(self): + params = self.request.GET.copy() # type: ignore + params["success"] = True + self.success_url = f"{self.request.path}?{params.urlencode()}" # type: ignore + return super().get_success_url() # type: ignore + + +class UserInstanceMixin: + """Mixin for `FormView`, `UpdateView`, and `DeleteView` to utilize the current + user as the object. Forms utilized in these views must be a `ModelForm`.""" + + # pylint: disable=too-few-public-methods + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() # type: ignore + if isinstance(self, FormView): + kwargs["instance"] = self.request.user + return kwargs + + def get_object(self, queryset=None): + # pylint: disable=unused-argument + return self.request.user # type: ignore + + +class ObjectInParamsMixin: + """Mixin for any Django class based view to get an object by ID in the + URL params.""" + + # pylint: disable=too-few-public-methods + + def get_object(self, queryset=None): + # pylint: disable=unused-argument + return self.model.objects.get(id=self.request.GET["id"]) # type: ignore + + +class SaveFormViewMixin: + """Adds a `save()` action to a `FormView`'s post behavior.""" + + # pylint: disable=too-few-public-methods + + def post(self, request, *args, **kwargs): + form = self.get_form() # type: ignore + if not form.is_valid(): + return self.form_invalid(form) # type: ignore + form.full_clean() + form.save() + return self.form_valid(form) # type: ignore + + +def login_required(view, login_url=None, redirect_field_name=None): + # Class view + if isclass(view): + return method_decorator( + user_passes_test( + lambda user: user.is_authenticated, + login_url=login_url, + redirect_field_name=redirect_field_name, + ), + name="dispatch", + )(view) + + # Function view + return user_passes_test( + lambda user: user.is_authenticated, + login_url=login_url, + redirect_field_name=redirect_field_name, + )(view) + + +def staff_required(view, login_url=None, redirect_field_name=None): + # Class view + if isclass(view): + return method_decorator( + user_passes_test( + lambda user: user.is_staff, # type: ignore + login_url=login_url, + redirect_field_name=redirect_field_name, + ), + name="dispatch", + )(view) + + # Function view + return user_passes_test( + lambda user: user.is_staff, # type: ignore + login_url=login_url, + redirect_field_name=redirect_field_name, + )(view) + + +def authenticated(view, auth_level: str = AuthLevel.user): + if auth_level == AuthLevel.user: + return login_required(view) + return staff_required(view) if auth_level == AuthLevel.admin else view + + +def stub(request, *args, **kwargs): + """Placeholder view function intended for debugging or development.""" + return HttpResponse( + f"{__name__}: This is a stub for a view that has not yet been defined." + ) diff --git a/docs/includes/requirements.md b/docs/includes/requirements.md new file mode 100644 index 00000000..7330a8aa --- /dev/null +++ b/docs/includes/requirements.md @@ -0,0 +1,9 @@ + + +- Install [Python 3.9+](https://www.python.org/downloads/) + - Make sure to select "Add Python 3.x to PATH" during installation. + - Easiest if this is the only version of Python on your computer +- Install [Visual Studio C++](https://visualstudio.microsoft.com/visual-cpp-build-tools/) and make sure to select navigate to _C++ Build Tools -> MSVC_ and _C++ Build Tools -> Windows 10 SDK_) +- Install a code editor. We recommend [Visual Studio Code](https://code.visualstudio.com/). + + diff --git a/docs/src/changelog/index.md b/docs/src/changelog/index.md new file mode 100644 index 00000000..17174200 --- /dev/null +++ b/docs/src/changelog/index.md @@ -0,0 +1,5 @@ +???+ note "Attribution" + + {% include-markdown "../../../CHANGELOG.md" start="" end="" trailing-newlines=false %} + +{% include-markdown "../../../CHANGELOG.md" start="" end="" %} diff --git a/docs/src/developers/apps/file_structure.md b/docs/src/developers/apps/file_structure.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/apps/getting_started.md b/docs/src/developers/apps/getting_started.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/apps/hello_world.md b/docs/src/developers/apps/hello_world.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/contribute/apps.md b/docs/src/developers/contribute/apps.md new file mode 100644 index 00000000..456c9b0a --- /dev/null +++ b/docs/src/developers/contribute/apps.md @@ -0,0 +1,13 @@ +Work in Progress. + +--- + +## Prerequisites + +Nothing here but chickens. + +--- + +## Listing on the Conreq App Store + +Nothing here but chickens. diff --git a/docs/src/developers/contribute/code_tldr.md b/docs/src/developers/contribute/code_tldr.md new file mode 100644 index 00000000..648ed781 --- /dev/null +++ b/docs/src/developers/contribute/code_tldr.md @@ -0,0 +1,64 @@ +This guide is intended to help individuals gain an understanding of how Conreq was developed. + +--- + +## Major Dependencies + +XYZ + +## Repository File Structure + +| Path | Description | +| --- | --- | +| `manage.py` | Django development tool _(runs the development web server, initialize the databases, [and more.](https://docs.djangoproject.com/en/3.1/ref/django-admin/)_ | +| `misc/` | Branding, legal documents, and other miscellaneous files | +| `conreq/` | Main Django application | +| `conreq/core/` | All back-end functionality | +| `conreq/static/` | CSS, JavaScript, and Image files | +| `conreq/utils/` | Generic functions that may be helpful to use | +| `conreq/settings.py` | Boot-time configuration and settings | +| `conreq/urls.py` | HTTP URLs | +| `conreq/asgi.py` | Websocket URLs | +| `conreq/core/websockets/consumers.py` | Back-end Websockets | +| `conreq/static/js/client_websockets.js` | Front-end websockets | + +--- + +## Viewport Rendering + +Viewport rendering is currently being reassessed. These docs will be updated at a later time. + +--- + +## Modal Rendering + +Modal rendering is currently being reassessed. These docs will be updated at a later time. + +--- + +## HTTP URL Routing + +All of the HTTP routing logic will trace back to a `views.py` file. Within this file we write code render a specific URL address, which is effectively a string containing HTML. + +Conreq relies on the [Django Framework](https://www.djangoproject.com/) for HTTP URL routing. Here's a high level example of what occurs when the browser visits a URL. + +1. The browser visits a Conreq web address +2. Django determines how to handle this URL by comparing the path (let's use the example of `/server_settings/`) with what is contained in `conreq/urls.py` +3. Django looks at `conreq/urls.py` at notices it points to `include("conreq.core.server_settings.urls")`. So, this tells Django there is another file that defines this path, and that file is `conreq/core/server_settings/urls.py`. +4. Based on the `urlpatterns` in `conreq/core/server_settings/urls.py`, Django determines this URL is rendered by a function called `views.server_settings`. +5. Django runs this function to renders the HTML (known as a `Django View`). +6. The webserver determines how to send this view to the browser based on what was returned by the view (ex. a `HttpResponse` or `JsonResponse`) + +--- + +## Websockets + +Websockets can be thought of as the server and browser communicating via _chat messages_. When the page first loads, a connection to a _chat room_ is formed, and _chat bubbles_ can be communicated back and forth between the server and browser. + +Chat rooms must exist at a specific URL. The URL they exist at is determined within `conreq/asgi.py`. In this file, a specific URL is directly linked to a [_websocket consumer_](https://channels.readthedocs.io/en/latest/topics/consumers.html). + +A websocket consumer is a Python class with a send/receive function, which typically process `json` data. + +The data format that gets processed is determined based on your consumer's base class. For example `AsyncJsonWebsocketConsumer` has `send_json()` and `recieve_json()` functions for processing JSON messages. Overriding these functions will be where most of your code will be written when working with websockets. + +In the situation where the server sends a JSON message via `send_json()`, it will be processed by the browser's JavaScript websocket client _(ex. `conreq/static/js/client_websockets.js`)_. diff --git a/docs/src/developers/contribute/docs.md b/docs/src/developers/contribute/docs.md new file mode 100644 index 00000000..45f73621 --- /dev/null +++ b/docs/src/developers/contribute/docs.md @@ -0,0 +1,39 @@ +We use [MkDocs](https://www.mkdocs.org/#overview) to create our documentation. + +For more information beyond what is in this guide, check out the [MkDocs](https://www.mkdocs.org/#getting-started) and [MkDocs Material](https://squidfunk.github.io/mkdocs-material/) documentation. + +--- + +## Setting Up the Environment + +1. Install `Python 3.x` +2. Fork `Conreq:develop` from GitHub. +3. Open a terminal (ex. Command Prompt or PowerShell) at the root of the repository. +4. Type `pip install -r requirements.txt` to install MkDocs. + +--- + +## Starting the Docs Preview Webserver + +1. Open a terminal (ex. Command Prompt or PowerShell) at the root of the repository. +2. Type `python manage.py serve_docs` to start the preview webserver. +3. Navigate to [http://127.0.0.1:8000](http://127.0.0.1:8000) to see the documentation and changes live! + +--- + +## Adding/Editing a Docs Page + +1. Create a new markdown file within `Conreq/docs/source/`, or edit an existing markdown file within this folder. +2. Fill in this file with any markdown text you want! +3. _If you made a new file:_ add this docs page to the navigation by editing `Conreq/docs/source/mkdocs.yml`. +4. Commit your changes to your GitHub branch. +5. Submit a GitHub pull request to `Archmonger/Conreq:develop`. + +--- + +## Building the Docs + +This section is intended for Conreq repository leaders. + +1. Open a terminal (ex. Command Prompt or PowerShell) at the root of the repository. +2. Type `python manage.py build_docs` to turn the preview into something we can use. diff --git a/docs/src/developers/contribute/source.md b/docs/src/developers/contribute/source.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/deploy_tips.md b/docs/src/developers/deploy_tips.md new file mode 100644 index 00000000..e2832754 --- /dev/null +++ b/docs/src/developers/deploy_tips.md @@ -0,0 +1,14 @@ +- Don't hardcode urls +- Always subfolder static files to avoid clashes + +AppConfig + +- Settings specific to your app that other apps may want to access + +Django Settings + +- Only use for legacy configuration values + +Settings.env + +- Any setting that needs to be configured before Django boot diff --git a/docs/src/developers/interface/cli.md b/docs/src/developers/interface/cli.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/components.md b/docs/src/developers/interface/python/components.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/fields.md b/docs/src/developers/interface/python/fields.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/forms.md b/docs/src/developers/interface/python/forms.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/models.md b/docs/src/developers/interface/python/models.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/processing/tasks.md b/docs/src/developers/interface/python/processing/tasks.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/backup.md b/docs/src/developers/interface/python/register/backup.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/components.md b/docs/src/developers/interface/python/register/components.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/homepage.md b/docs/src/developers/interface/python/register/homepage.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/http.md b/docs/src/developers/interface/python/register/http.md new file mode 100644 index 00000000..db889edc --- /dev/null +++ b/docs/src/developers/interface/python/register/http.md @@ -0,0 +1,5 @@ +By default, API endpoints require a user token (typically fetched from the `api/v1/api/user-token` endpoint) and additionally an API key. + +User tokens must be provided via `Authorization` header like such: `Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b` + +The API key must be provided via the `Authorization` header like such: `Authorization: Api-Key 10Q5p9Lr.0Qp9twA07Ve5U7mZJvDgfOuUItdoPV7O`. They can optionally be URL encoded like this: `api/v1/demo-api?apikey=10Q5p9Lr.0Qp9twA07Ve5U7mZJvDgfOuUItdoPV7O` diff --git a/docs/src/developers/interface/python/register/notifications.md b/docs/src/developers/interface/python/register/notifications.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/startup.md b/docs/src/developers/interface/python/register/startup.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/tabs.md b/docs/src/developers/interface/python/register/tabs.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/templates.md b/docs/src/developers/interface/python/register/templates.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/views.md b/docs/src/developers/interface/python/register/views.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/register/websockets.md b/docs/src/developers/interface/python/register/websockets.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/services/email.md b/docs/src/developers/interface/python/services/email.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/validators.md b/docs/src/developers/interface/python/validators.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/views.md b/docs/src/developers/interface/python/views.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/interface/python/widgets.md b/docs/src/developers/interface/python/widgets.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/developers/setup/requirements.md b/docs/src/developers/setup/requirements.md new file mode 100644 index 00000000..63b71265 --- /dev/null +++ b/docs/src/developers/setup/requirements.md @@ -0,0 +1 @@ +{% include-markdown "../../../includes/requirements.md" start="" end="" trailing-newlines=false %} diff --git a/docs/src/developers/setup/run.md b/docs/src/developers/setup/run.md new file mode 100644 index 00000000..98e6b68e --- /dev/null +++ b/docs/src/developers/setup/run.md @@ -0,0 +1,28 @@ +???+ summary + + There are two environments Conreq can exist in: [Development](#creating-a-development-environment) and [Production](#creating-a-production-environment). + + If you intend to edit Conreq's code, then proceed with the Development instructions. + +??? info "Special instruction for Windows users" + + Windows users will need to type `set-executionpolicy remotesigned` in terminal and select Yes to All to allow external Python scripts to run on your computer. + +You will need to follow the steps below in order to create and run Conreq from source code. + +1. Pull the repository from GitHub. +2. Open a terminal (ex. Command Prompt) as administrator at the root of the repository. +3. Type `python -m venv .venv` to create a Python virtual environment called ".venv". +4. Type `./.venv/Scripts/activate` to enter the virtual environment. + - The method of doing this may vary based on operating system. +5. Type `pip install -r requirements.txt` to install all Python dependencies within the virtual environment. +6. Set your `DEBUG` environment variable to `true`. + - This can either be done within system variables, or within Conreq's `settings.env` file. + - Doing this disables _a lot_ of **security features**. +7. Type `python manage.py run_conreq` to run the development webserver. + +??? question "How do I convert this to a Production environment?" + + Follow all instructions laid out within [Creating a Development Environment](#creating-a-development-environment), however, set your `DEBUG` environment variable to `false`. + + Then, Conreq will boot in production mode the next time you use `python manage.py run_conreq`. diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 00000000..c9cd2838 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,17 @@ +--- +hide: + - navigation + - toc +--- + +## Welcome to the Conreq Documentation + +Conreq is an extensible web app platform built around [Django](https://www.djangoproject.com/). Read through the docs to learn how to set up Conreq, or how to contribute to the Conreq repository! + +Want to join the community or have a question? Chat with us on [Discord](https://discord.gg/gQhGZzEjmX) or create a post on [GitHub Discussions](https://github.com/Archmonger/Conreq/discussions)! + +--- + +## Communities + +[:fontawesome-brands-discord: Discord](https://discord.gg/gQhGZzEjmX){ .md-button .md-button--primary } [:fontawesome-brands-reddit: Reddit](https://www.reddit.com/r/conreq/){ .md-button .md-button--primary } [:fontawesome-brands-github: GitHub Discussions](https://github.com/Archmonger/Conreq/discussions){ .md-button .md-button--primary } diff --git a/docs/src/install/freebsd.md b/docs/src/install/freebsd.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/install/linux.md b/docs/src/install/linux.md new file mode 100644 index 00000000..8e036705 --- /dev/null +++ b/docs/src/install/linux.md @@ -0,0 +1 @@ +Under construction. diff --git a/docs/src/install/macos.md b/docs/src/install/macos.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/install/unraid.md b/docs/src/install/unraid.md new file mode 100644 index 00000000..b4e39e9b --- /dev/null +++ b/docs/src/install/unraid.md @@ -0,0 +1,13 @@ +???+ Summary + + Conreq can be installed via Unraid Community Applications on Unraid. + +--- + +1. Install the [Unraid Community Applications](https://forums.unraid.net/topic/38582-plug-in-community-applications/) plugin +2. Within Unraid's GUI, navigate to the `Apps` tab +3. Search for `Conreq` +4. Click install on the docker image from either `selfhosters` or `hotio`. + - Both dockers are maintained by trusted community members. An officially supported docker may come in the future. + +!!! tip "Unraid is Conreq Team's suggested operating system for deployment." diff --git a/docs/src/install/windows.md b/docs/src/install/windows.md new file mode 100644 index 00000000..24e1eea0 --- /dev/null +++ b/docs/src/install/windows.md @@ -0,0 +1,32 @@ +???+ Summary + + These instructions configure Non-Sucking Service Manager (NSSM) to automatically start Conreq as a Windows service. + + A traditional Windows installer is targeted for development within our roadmap, but is currently not available. + +--- + +## Software Required + +??? warning "Warning for Windows users" + + Steps below will not work with NSSM if using the "Windows App Store" version of Python. + +{% include-markdown "../../includes/requirements.md" start="" end="" trailing-newlines=false %} + +## Installation + +1. Create the folder `C:\Program Files\Conreq` +2. Use this folder to follow steps [setting up a Conreq environment](/Conreq/develop/run_conreq/#creating-a-production-environment), excluding steps involving `python manage.py run_conreq`. +3. Unzip NSSM in a separate directory where you can permanently keep it (ex. `C:\Program Files\NSSM`). +4. Open a terminal (ex. Command Prompt or PowerShell) within your NSSM directory **as administrator**. +5. Open NSSM by typing `.\win64\nssm.exe install Conreq` +6. Under the Application tab, browse to the path of your **Conreq venv**. + - ex) `C:\Program Files\Conreq\.venv\Scripts\python.exe` +7. Under the Application tab, browse to the path of your **Conreq repository**. + - ex) `C:\Program Files\Conreq\` +8. Under the Application tab, set "Arguments" to `manage.py run_conreq` +9. Click "Install Service". +10. In your terminal, type `.\win64\nssm.exe start Conreq`. + - You can check to make sure its running as a service by running `nssm status Conreq` +11. Open any internet browser and navigate to [http://127.0.0.1:8000/](http://127.0.0.1:8000/) diff --git a/docs/src/stylesheets/extra.css b/docs/src/stylesheets/extra.css new file mode 100644 index 00000000..431add96 --- /dev/null +++ b/docs/src/stylesheets/extra.css @@ -0,0 +1,27 @@ +.md-footer__inner { + display: none !important; +} + +.md-typeset :is(.admonition, details) { + margin: 0.55em 0; +} + +@media only screen and (min-width: 1220px) { + .md-content { + background: rgb(0 0 0 / 07%); + border: solid 1px #ffffff17; + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), + 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12); + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); + } + + [data-md-color-scheme="default"] .md-content { + background: rgb(0 0 0 / 04%); + border: solid 1px rgb(0 0 0 / 14%); + } + + .md-tabs { + border-radius: 0 0 10px 10px; + } +} diff --git a/docs/src/users/configure/env_vars.md b/docs/src/users/configure/env_vars.md new file mode 100644 index 00000000..53d38e79 --- /dev/null +++ b/docs/src/users/configure/env_vars.md @@ -0,0 +1,46 @@ +???+ summary + + Environment variables can be used to customize core Conreq features at boot. + + The most common way of setting them is via the `settings.env` file, but they can alternatively be set via system variables. + +--- + +## Using the `settings.env` File + +!!! tip "Many settings from the interface use this config file!" + +Editing Conreq's `settings.env` file is the recommended way of adding or modifying environment variables. + +Here are some common locations of this file. + +| Operating System | Location | +| ------------------- | ------------------------------------------ | +| Windows/Linux/MacOS | `/data/settings.env` | +| Unraid | `/conreq/settings.env` | +| Docker | `/config/settings.env` | + +## Using System Variables + +!!! tip "These variables take priority over those stored in `settings.env`" + +!!! tip "System variables must be prefixed by `CONREQ_ENV_PREFIX` (default: `CONREQ`)" + +Variables can alternatively be set through the system's evironment variables. + +| Operating System | Location | +| --- | --- | +| Windows/Linux/MacOS | [Varies depending on operating system.](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html) | +| Unraid | Through a docker's `Edit` menu, click `Add another Path, Port, Variable, Label, or Device`, and then under `Config Type` select `Variable`. | +| Docker | Various methods. [See Docker documentation.](https://docs.docker.com/compose/environment-variables/#set-environment-variables-in-containers) | + +## Common Variables + +These are the common variables that aren't modifiable within Conreq interface. + +| Variable | Default | Example(s) | Description | +| --- | --- | --- | --- | +| `DATA_DIR` | `/data` | `/config`, `/mnt/data` | The location where Conreq will store its data files. Automatically set within dockers. | +| `DB_ENCRYPTION_KEY` | Auto Generated | `None` | Automatically generated during first run. For security, this can be self migrated to an environment variable. **Make sure not to lose this key.** | +| `WEB_ENCRYPTION_KEY` | Auto Generated | `None` | Automatically generated during first run. For security, this can be self migrated to an environment variable. | +| `CONREQ_ENV_PREFIX` | `CONREQ` | `COOL_VALUE` | All **system variables** will need to be prefixed by this value. This setting does not apply to the environment variables file. | diff --git a/docs/src/users/configure/server_settings.md b/docs/src/users/configure/server_settings.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/users/configure/static_files.md b/docs/src/users/configure/static_files.md new file mode 100644 index 00000000..9198237f --- /dev/null +++ b/docs/src/users/configure/static_files.md @@ -0,0 +1,8 @@ +Conreq can store and serve any custom files located within your data directory's "static" folder. + +In order to use this to serve custom CSS or JavaScript... + +1. Put a CSS/JS file into `DATA_DIR/static/` +2. Restart Conreq +3. Set your Conreq "Custom CSS/JS" to link to the new content (ex. `/static/my_style.css`) +4. Done! diff --git a/docs/src/users/getting_started.md b/docs/src/users/getting_started.md new file mode 100644 index 00000000..95047f0e --- /dev/null +++ b/docs/src/users/getting_started.md @@ -0,0 +1,7 @@ +Start Conreq + +Navigate to http://xxxx:7575 + +Follow the setup procedures + +Feel free to expose Conreq to the internet diff --git a/docs/src/users/install_apps.md b/docs/src/users/install_apps.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/src/users/optimizations.md b/docs/src/users/optimizations.md new file mode 100644 index 00000000..523e33c3 --- /dev/null +++ b/docs/src/users/optimizations.md @@ -0,0 +1,20 @@ +Include security and performance changes that can be made + +## Security + +- Configure Conreq to use SSL +- Use system variables for secret keys +- Limit allowed hosts to only include URLs Conreq will be served at (local URLs can also be safe) +- Limit CSRF trusted origins +- Ensure Debug Mode is turned off whenever exposing Conreq to the internet +- Reduce max session age +- Enable Rotate Secret Key +- Configure email settings to receive security alerts + +## Performance + +- Use Nginx with `X-Accel` (View reverse proxy docs) +- Increase worker count +- Reduce logging +- Use a production database, such as MySQL +- Use a high performance cache, such as Redis diff --git a/docs/src/users/reverse_proxy.md b/docs/src/users/reverse_proxy.md new file mode 100644 index 00000000..defa9774 --- /dev/null +++ b/docs/src/users/reverse_proxy.md @@ -0,0 +1,7 @@ +???+ Summary + + You can reverse proxy Conreq, but make sure to allow websockets and set your proxy headers. + +There are situations that you may want to reverse proxy Conreq, such as with distributed computing or for traffic optimization. + +1. Set Allowed Forwarding IPs diff --git a/manage.py b/manage.py index 477f2229..38ae359b 100644 --- a/manage.py +++ b/manage.py @@ -1,10 +1,18 @@ -#!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os +import subprocess import sys +import traceback +# pylint: disable=import-outside-toplevel def main(): + # TODO: If venv dependencies cause exceptions, try to reinstall Conreq dependencies via pip + # Make sure we are in a venv + if sys.prefix == sys.base_prefix: + raise RuntimeError("Conreq requires a virtual environment.") + + # Check if Django is installed os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conreq.settings") try: from django.core.management import execute_from_command_line @@ -14,7 +22,33 @@ def main(): "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc - execute_from_command_line(sys.argv) + + # Run Conreq + try: + if int(os.environ.get("SAFE_MODE_DEPTH", 0)) <= 1: + execute_from_command_line(sys.argv) + + # If Conreq crashes, try to restart in safe mode + except Exception: + if int(os.environ.get("SAFE_MODE_DEPTH", 0)) >= 1: + return + os.environ["SAFE_MODE"] = "true" + os.environ["SAFE_MODE_DEPTH"] = str( + int(os.environ.get("SAFE_MODE_DEPTH", 0)) + 1 + ) + traceback.print_exc() + print( + "\x1b[91m" + + "Conreq has crashed, attempting to restart in safe mode..." + + "\x1b[0m" + ) + run_in_safe_mode() + print("\x1b[91m" + "Conreq has crashed again. Giving up." + "\x1b[0m") + + +def run_in_safe_mode(): + start_command = f'{sys.executable} {" ".join(sys.argv)}' + subprocess.run(start_command.split(" "), check=True) if __name__ == "__main__": diff --git a/misc/branding/circle.ai b/misc/branding/circle.ai deleted file mode 100644 index bbe5bbfd..00000000 --- a/misc/branding/circle.ai +++ /dev/null @@ -1,1768 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_circle - - - 2021-03-19T17:58:03-07:00 - 2021-03-19T17:58:03-07:00 - 2021-03-19T17:58:03-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUo8x+cPK3lm1Fzr+q22mREEp9YlVGenURoTyc+yg4oJeO+aP8AnML8vtOLxaFZXeuzLXjJ T6pbt/s5Q0v/ACSxYmYeV6//AM5hfmTfFk0m0sNIhP2GWNriYfN5W9M/8i8UcZYHqv55/m7qhJuv NV+nLqLWQWg616WwixY8RYveeZfMd63K91W8umPUzXEsh6U/aY9sUWluKuxVMrPzL5jsm5WWq3lq w6GG4ljPSn7LDtitso0r88/zd0sg2vmq/fj0F1ILsda9LkS4p4izzQP+cwvzJsSqataWGrwj7bNG 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 7FXYq//Z - - - - uuid:f932e1c6-5245-fc45-8a06-af9d16379f90 - xmp.did:08255e2d-8e06-4013-b203-daed99fdfeeb - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:08255e2d-8e06-4013-b203-daed99fdfeeb - 2021-03-18T19:48:20-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HUInA +vbd]r8?bh, a&!rzM]e&Y$#[z͒? yiY$V˻*dUN_;rL;+mN"sx~!E53gg?#~ɍ+A%ULR\Iky*5\ۧ4XJ@F ~˽Ria\ pڀ"DbB8"f pJ*cC4t+fo9"w$8>stream -8;Wk$c&IB1%#'+]#1CIIOITPaS>K`K=oUS/A6,a*A-mp7ridJiSpr:N!8t>>';k^s -@pM0](OX/a_^$3\,')?7L?:t_(WAun#k\+-6#.TD0Hm*5h\N)dA>)B@X[]5u1s3_! -W&EL7M(guV5Z_\Sh,'s7(K[2BhP,*(e!X0),lIb=lE4]^S;EbG?pCW&;GBR.gcCNp -&#cHtF`L__YB=SL!^8mV;Mkc-',3[!;DMsI(H]$mknRQ,rPV$!PLI(BonZb)U5qc9[$drnD-U!dgEe7hK[6d+54."`WU-3/ -f?3A]=->^_E\;J7/kTE`m`=;)4#9!?E+V.Y4pU_Zd^78Ei;IYlQs.`a?:oDpX1IP6 --e(?!ofg]uk@Xc"]W>]~> endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_circle.ai) %%CreationDate: 3/19/21 5:58 PM %%Canvassize: 16383 %%BoundingBox: 11 -289 286 -14 %%HiResBoundingBox: 11.3463075049212 -288.779944054208 285.457306209986 -14.6689453491535 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -405 104 1.04844008935887 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/XĴv -m* mm[QΜ&" -NRj0A  %1Kݗ6KE)V^Xq>,"aJnyQ QXhB5RB,`RݝgHH"ɳd0T(C IHpA-Eb$XcEJV-E? 0ef*cJ8϶ r[0QE(gE bW rf%,YdIF;2uȠ־|Wy“95C%#Dt溊j+olweIug{2ꩽ]<2e]jFT42LͻT*? *I{M$Y(@+@? -Rh%%Q eDx"bYYIa@WQʰA{ijREi%QR#atu -$I:QK`,l$Fq$6, LGd"SS#2,IH/b+3&ɔvDXDeSիz=lk;_FgkUvHt<2U{Ԓem -M+J2lM;Eó3]XqS+@I͢6L R1*bH!FC-WR`"D*H( r rB JrFIYD"ʺp^a4'Q W6FRgH`c1z(L21cy)4clGJy"*w5{NCxHk塲ۮPKzȦH!BL.0 lpZ*ա -6_f/C暕VIf{DUe"TLCxxrjHuUwRqxuv^+K!U.WMK5)!W)i+\CTM*8 d/.ʑ8Qeuz0-Hb% @'NL2'Eb$G$JŸnB0J$ &ԁ"Z )VHL\0T(0Œ%qHJ0 - -A/DM2)<1$IJP &2' #I 8FH DD"idOKJg4EECBcCθ|t!fKH#$+aBA)"HqM0") -T*VX)gq%8Bc!b@D0R:+-/1357<)/I9\a"$L0ĜP@A@,H"RɁ&%DCH   L`c *T蕞 vT门˽*CH \` 8D!AU4`@!A2{|;d~Xj[_"A 9ʜ -bUN4j($k[]^V2p1R J(AvFׅ F0pR$E4J!0̕#L2$CM4^o-nnkX_~7~yĩpQW`[(EaG eqiƍ0@HtÎ;C=~qr$G H!XXY28 -)$D%f++eeffgjk{+0CKX竫+%AǓLI'G~x<>=E6YdjmyiEPC 5z]M +lmM F:ז֕*ać > !dPAKJHHGEBA)@1bBGr$qaQ?~챇zwaGu(tБ010 0 -jgaDHqFaEb - -+…/ - cL!D`&ph ^`$hЀ! 6x !" "`  L A 0 DP@D0x$"4h0A h! GDQd 8X `20a@4DD0쨩GtKoZDE"9Bww.n[I:$[~(3;M{^}֥Ÿ;»Z$xtֿ=-e6ggzW**E4j},+]§ݦxKFu6A*ĵ:hK;>2JW^tBy`W*s.!ĺ.L54|iA+s.Mǻ[E?Dk[wCUvCMg24h?#eݏԺ*u*l箌4 v[;jseӖ UD<*;WhNϲDKGLdG6INYcyhXgyImBcgO<6\y$sor>vfųks\UB:xh6D:4?=jPc&.Wo3/sjţF׵_Zѵ4-ͽ,\P( 92Ψ*] PP6XXHxx0`P&0 `px Q `A8,((@fAd`&! T, `̄܂B`A4@ahAX礳j&τ[z;=kW  0DL`Cw{r-toyYJ)\$ғÊa7MYaF,],Fm%,.$Fa*]$@CD HLTԔW9KˢK;"%=]<*)Vl%$uxlIږB:Vt3ci`=c)TVҵmZ}ooxʋb.Hʓ: ajqb I,Ł$8t9$aTQ-"z@:YЪ$E5 -$h믩j%%V9_X󋵼0bĸFR|qa((J]H1=>Z$%IET/&ʖC5c_4ܥ|wwh^.n3&"ra#/b +zR R8$r VT_ EQ(.4J Y()EU&%a8EkU<ǖ+ 4$퇤{W[:?#;NKϩJL=;DAY4Oզ3U?f_#|ٺS9槏O5ӦDV4yL]˓w6j JԵ;Zޟj"4N2}+Hw1k=ձ]FǻΊH.gU{z}F[3Ijz1ZLUD:7{~ ^v=SQܲ}\SLJݗOӆ{4\}\d=ݓiL?~Ԉ\3J6ZצxlYsgEGWhǿK,7Юg .!蔄2*!d{yx*skתG͒҈YgDU{H1zAaѩEJs+Mu*1o>sDEL:q15q].YO١īĵL:OD#5O%==QՖ[m1r}JN$!1Nq %}\D22<[se.R2Z7tNhKҽK:eTtLXzh>$j"(!^y Ȍ֕r>L.lIdxQǃG\ZS[K[=^)/Ӹh룻/Ż$ܬ#Z"ib)*Te,ҡ3g2]3cEֵ;kx>k&>ƇN1QԥA)4\ųy --xte94z۽hsMiI?ƬmX٪=9S~Hvo+ՌB[*d4[m:U5EVdsHudS7Ejnh\XuXwn$*m,5}xvToT[RsJO6>Ti4J7*ӓ۳iVK<=L4ěc|ge۵q^yOOj]Vkd5s[jZvn4zgʸXkM;4҃gf&=i蔚v]?iNkb"ӛכdiLNѼm]Xkpu=Nl˫Ǚ<׬c7.4wZnoL&;iY4ء=k4VV[zQ=L;y_Q&'ҍ+ -8 -eH`FL0^hWP,@ 0 -#P>"a0 0xx 001_L1Du`W鬯ȵKkLJ`ML]s`,(]22Ҫsg!cف)\ ':_5S)DwοvnK_ަ婚׳n?yukDC|w]U!ݝ~xZP(c^/L;Ϣ+=*חYWguk7VtEuSB -<[P(ϡOvJΎjձ}ţunɨl޹L\Bͧtw~&^ZSZO3LB*3JE_7s^Lc.Kߪ^=rtBIk}V**V鐜wNe32z?U~XUΥ滕M*;JZL[f~7^Ϳ%SY/TuީtjZSMvw.(쐌񝅪VM!unYN7tO<𵮽ïψWuUyаtө+v^CUT5NµOCDǨ*]wh^EwʘYwYmU_QvR[U_jSXyiwԎs:IDvj2ZE`Z^7ju6*=NebZ_);zx6%#CD*"nEý!*.n"N-p)O.ڢmEkw!jݣV+|"evow4hj4]{ sftycC++OKOon_Kr̩y*+%KzzM,UR[5כN=ItѯlJ[d⥪Yg-|BWcp3j_LX,ܩT13 yP(*!JE pUDЮoshfQtTO2(j28o~\ESNO7E̠/h7/eSD${7QG8İ+ v\' xFX5)v]QR2K(g7b#) wڨ=bSy@3 W - -W8sƢ-]&* -bRoxO|!පbkr(:1-fenpdތB{IIx1=$%fh20=p҉1SICu%6[T$]YÇL+cfF~E$rz-VPļL&MZIS4evͽM\3(nqC^, -c|"rxИx$+KDxc{[Nw:8y Ѱ`U؈v{tQ@oިc)P/8#^n|= /yĤ m]tc˜U -Y4Rt{izNge7S+%/ JaIHRX[ 3 5$(4PI0E - D=qtqF%]D7 .}Pꩤ$}ݕ4kug5M?<=|ѿel*Z餩‚kv}F4Lm0{zBH5ݎ5ݔOL5+n!y#+v]L],u\MߟXQ,ݒgT2yE*Qb61$@~j#R0Z',]6ʈT, ۖ} `׫T&)l[X*߮hEbӊApj4TtX~lRE߄]D?0}}PPD wҧQup;/'C,_%h,׼OҤ<Q !]9v[ҘmΚ3l IQ_^gl(r8_~kH~}~ RND>E8* 18ܩL"y+$He>Xz=0ʲ=CKfm[X8m.aɲ8Tz%L M9!wռcgf6Pּ% tI⃁ӡ܏cY-DMflwMB]bbu߂ܼg(SVhMs4 ~P,]槭={0?ҏ -!Qf4odf5WIޗe6)iQ3G<ӠVKmt 7vx*{0j4/f}kz -- [DAݺ2Hۉ^`1dN'Q0a;7:[M34Wפ#!j/U`! y cMt*xd>xڵTNvkLwhhgkWeA?т<BS&uANVpI6Hj:bRJnIkz%:&*N3q?g ]L@걭-(K(sk؁ʿ‹r@$o>4巢_R>;61]Nlzs1=5k< TOI7y:ZDD@ |ۖ]ra3roA?hҋ-ӷ:_6j%NۯoÅ^/s] O%"/e5+V2p]v__wRl#d.|`7pzk[P`Rj m 8 -1r \c ő pWF_, ~;Qfag~۩o.2&؀r !zXXLp؄+振 @osgy;v|3j2LyF{7}n醆g uC:@Uuzcle%jfUb #ئl(YwCNur2h3fe7na<V9ĻZL'a u氭Cy!X(Ak2\ /a15yJR̡l&s/@t+Yc08=1VV|GO|CVw9ݣfg%xQ*lh#j|0B{YBYYlq^̮ic혹C53[rWURdȲLMg.a49O6}2]~d>1x*aMB7>ML'C]XOW<VN0I.4,-B!;u@\"QLNI$/K2NP1>.ڀ&sF>| -X dg X[:<0B`<'א&Q S{!4(X.zϘ 7^ԂPWڂ]sD\` yr#՛}J(1]* fHrb&cѥlf !tɥ  Al /+dr CZ{(gވl?&=®iUk3[Q`946-L8-Q]X{r&?1ZVއ 5n|d8^jHwCFWy{'\請[:|wsC -TYXwd)/0sY3u&Xfn"_X/[ER?MEF -it:(gbu5)szŃdPJ6Œ*ZJ*ʼPDݭ'h4Y zTø#^9gGLP#qy_mHu5 -ܑ}/2*m:XY$Dw$<\*Fat>ך"Bb@(pW.S(!./ZGo&DUA9!EC'O#P*@=rY^ղ)QXKzoף(_W ;z>g%?O=ՐͪvhH;$s~[4 -Ũ~x`&%GRSEїƬLXV0e۠ ISNwu -$"OxZ@߈| ~6~-ɂ5[Ln"M 'K;O663d6pm:iwi@I.sq2ƭCRdGRkׄW3+`;רR<_ qv]+akNy1w:6|QDB4r?SԇuoFu¦lpȌuyxVSKAneLFBϨ΢{ne, J-]P ,;3VĮj(5I[GgΜ{IJ%jKNE j8bvQ3\%!;01|iEĚ'A*YJ\X R{{0ϝ@ڇC˂8HKTBL9'9f`A&U:C8~( -%ݢ1ԏ5?ao)@T/'t4`ٓȷ@#xo-eN1f=BTj/Ұp;U珏ꯒ@xC߷2`7jrKinNUcxrW\(MUY_˺)8 d&`Dc>nKq[JmA:*ݢ[\Nu3?=p jFw\s'n)8قiO<^1aec0O~-{ vjТ= -G ;P:$QCa*ED&,^T^b{4S-!DWx\O m2Qm7u90fv -oթHJ`.x -^݋.8]~ԋ_ޏVY&8]>Wd* /&"jWlTa?`_jX8l,ktt]!bfUP7u2'¼ hjxRm~-~{Y(M n7d3I#(}Ut2 ”IbIsT!.GWkFEZ'C"]ӊ_좛|@AtίuWfcSO-w\Nn hhέ TL3qÕCdE0341i!j7\c7nir$qh=XJ?@ tXq(Zf2L>t(a Lcg:h ZaL ,rQgQ nzU 1 $a)YAv -uJ9 h@ D7󡫤|vOibc[E\#f45_qSn2f-9( -(EExmawC椚QG-2)F4 pq3ہ  f0 - \TU'{ZS8$0'H`)NNluZ\4rWsIq{ [³[%߹{0:ԅ4*:_R:@[x1g&anR:&U"n(eZqTj yIho,,V|P#rW&ze<mI3mȰY]4Ji=ܛGb!T ^+L$Y`WlmyۼMPA]hw @QoV6JDk\e=WJ׋rB -vXW,QP׎Yts)+ҷp"x -%3pi+Py]]r'?d 4 s ԶHedžmB.Цenޝ25^\rTBu,uoM^g{ xdU[;8~dzVLƵ?/z~O w8i -64Up %!IĈa9L ]FuT~=ʸU25.%"lN@H@D&e}M޷:D_R÷!updYjbW~NIuJt)t桟*n >F٨@KOgRUf/!_i:h-gD.E5>;|`yy|=fkng=+-"[*\f0dR?feq=8ʽ2FVʱ1 s<"<]=+[ B7lL뛖dl! rҞk\I^K#'a JŰ|d2'1"ָ_J%LU|˯)B@@HW-$hub1ed,HT"#jc n1\T.[4-qx ?Wӷ(zdl3B<4l6F8ZB0%e$.^ {,_w]l{RXV<9 f]|%pnt[ -"0t|$;R ګğ6 [d0r9尪{>F3G9 nw\vԢh%JZSQ=+i_ -2$({+mꨗpg|x[%e-P,LuoTRXu}Fjoc]tLHZ>adHTǗJPJ@^m>\ 5o(QmAd!C Nt}k{) {>=mO* /[bH8s1R --u}#VIq%xoIv1f1/()Y8SAܴXhXEj|#ȝU)>[G$gg@y9Z(vοo# auORf'2Q_4T=&tNZ@M -NNz2d -ژ -BI*ª3.!d:`7U!+3}(p@مN-p-@9Ʀϱ ]/ɣT-hiblT*SvPl9l*@ߗy22;knع<W"%2?{Vɔhcq4\ go/%9}ͼ1.jj{< v|'f-욉]-7޿,Vr,+qfXPpOuC:o\r B[? 5B @@y -CvU'/fl%ڌɂ:LxˌԸBb}!̮{W}frr&cPiv&-cGS{>0Ҵ1L{Ӗy+.p2.@ Ed1Lŵ&\Zd[nzoz-yꕥҺ$ ) NeCc+{Ʉ?+heV-{:cdR7 0G]KreD: -q,Y[.z4&=5ȣPrЀ=&zwT]-L\5S>`xرor,V4*.saplU1[nNRpz;ߐ7#A -f=%HDZxnF823h\aUNknc|XA߂п(6G\rx"qK[ŽЕ8$%Z o/6f0"U% -*B7{8h4phE?1pJaB4`9W,ôG3a!)zP@([hpKmA_j=WL;5 ?mށ5(M #1 )>\tY$~܃肺m<`aۃzLoaNE4:i""ZeIe'E|9ޝM[j?f.v/rUAD -tAAG&880`X-tG~5Y ;}]L^sdr+u<9E=o7d -SW0̳[Ve*fţ*7Bb_%RԎ -I.i`J++kMʸ5eJ9jB3$Ց$xP$ rQ3n$ƋBؾԸ+m"c@"E^4.t[gN@~QEz=sF*Q @.aHdF#[9+׳n偾҉ct.T{zX:lahz_P+ņp UG{}+@B8e$!Lb`<6 6V -jds$~eqz^X̛-"Wһe9! -mF/g?]_B6l+eCk6޳ n4M -T;'4Vz͜Ϣo-^7&jT c -_[rەv -u#^dYeͣ]/6s)1mG_r=V'ei쒻{{Oi8 s.V-BwlS7XTeLI/=X}Ұn5>1^g+)!SCg^mbBDƨ9`62 E)(ڊ9ovwS@2C5G0a: ՗!P3ZRJ-168?:4i=gxњ*qEHmA/vKAEHlۨc.n9\ODVGJ}IMº(fOa)䇊]98h4^4(6%2vn7՛6JB<&Ut>m/L}(:_o^NZfKXv fϭ64x !pKKrdDcvIOL?8;G[ 빓LIWg@[R170I2LFk*ݼՒ̻-\[))mX׷_X:EOw)QJzg!`LH2AU0M"'Wˋ(tPuڱBu)-JjƘ!`ǘDb7ybGL7aiPxCPXfG+ͫɝ?"" Q>xcї{oov78^BD&ZF|*G#KO0tY-r -y A \@GĨPYAN`}N6yK|r&d!,+K=^&@wn! -o<7~mb8>x\ֹHGJ0Q4:l,O*u'䤻g#7ч0%A#<CۍN0,MHI5كħdcr,1uL#!_^?HKŖm[ZVTF$0jȩ%ɐ~25ߋʭ!Byr*Z8 ! S8ςG¤?k]%b`Can*$G) -ŻޛprוiI! -MN/5'B([\5Z9|wد<ͧ˄zO{ N͂S;h$ClhOǜ%NP& -۞ʳ{p y>w粰*iǚzN}n1]]Ɏ k@SpAZ 81qĜ!a%}m{uJm JW3Kܥ9pah-3~O'߷4YYGD￱oLX"ˌH]+*u(7IJgE-#,`':OVD1 eT줄mV8ʠ5&ˋgIctoswJw%V{+*E;H4{gmN=TS MkFvPz8}j [SGNϲ9b,2B^# Eȫ|'6/̕={-(4]L u4zGw\^ +?n -a%6JfѓGhL_jj،Ӝ~=֍ʷ0q2D K- ?Tghʤ+[&a~$]7`S1f^om!k,%Is%N oU =h1t"[}3XŰȘnM:It/듞`^p6ÿaڧ8TzReR) v&q"JۓEY?9Ɠ 36$MR憧;E[_ )vV rZyo#]?1o0 \T{elR1$U("z\L%W+|*!A(IS輗^ >[!,RФyJ<9@ -ihXr bѯ@nmȓ lJ؅UT֣ܕO؀];B&c{9Ѝ3 1 z٭aW[D9`J]J$udlO.5-),}q<*oKbx8d1]~0Y9Br#A LΧ3:;Ww^%6؆DUO^0DZHvȆCf6Qu/s瑏c%xs||LjtNR-Z-`z-g&Mlf;,$n("lĸۡwb̩ht$ KmhkrAwTˀ [9L!_¨Cʲ0Uwl/N f% !ae4"G}HRrfJ|l elr"u$1O-j*icbQK45>gqL J yevBC|W*|:.IbiԭB64E`CR<[ w T90aԢ -Yׁh4n?uXf]}s,nӨHLzb$#zfT27m_/JNeNisr*ֶ%ƍ 5q$MI4mb}ŋ=ZDhG Ne}ŷg< UE!G}|n-+R`}*w`A~$n{`ZZƞ8Y"˘g!N ^[ N:b+J,K]F6_l)ᙠV`˸ wUާBү58Sex*?/I bLJxXNLeb_ꝔR+[CXm,\C2 OBTCR (>!ɜ{2>F?8WW yxIxM[j.P[uّ݈#32>yw狮ng>ݪ|!YEqx":ҍg#+ؚ0/6c%2fThn ;7g֯h~4NHE$й¹l9i96g$*Ohhb)U{Sw+x4džg4w↧7~gDߡ au_fXVӒLKrJ8qLV%JO1e_:m})S~ǚ9?x'w#uxLfU7xReT<KIJsQ>ޗNqDцH!&EZ!֫ -b4H>/ ^ڌT$e[OfԞdz"P3=`ȺtE%8dKq!Ƒak pƀG7>H2x{sH,D'kb\ &\ A8Mcap"sq㎴gp[x/$-kn!e-ÖQ0i3!ݫsa7F`=YwITTI!i_ C*@0Ͱ>Su9V"R틪oƁ``7|ûɉB^ROs>~b|0‰YYL)N|)ܚcuBqVC$KMCBTOp.V -Lမ/aFL"d+\(L)|k@2G(iZ`[2G6АFΪ,bάh1"X g70F4 -pyzB!dV tj9(% \Niza} dTQ,APh>|UqK`CYg:82&'C\ul g-8H ˞pw^,0tmST4ߏ%^x$xgMQ1՛EYAHKp@k{k_ ]@QLKU<ٛ^dZ!9jM Kޕ/xew≁4Wfg%3|TcU\m۶7Y hUQM(8D -@Ea@_Cd@PR09bCcL#*^s:<6-s -"?"r[('jӴv;0R9_h{h*\K7U}s_wmG V I>a R%C>9ʼnnAXu@꿾 -0 uoPK4ٹ@yjq>. -X:Yvg㶹 4H(si;PƗPoz!pypBҭ*I0uQ)V'Q)M6"9v"Q[mv8"16H?i~A:~'W[c#G@L"zѽl$ -vRzr,::\DBj8LUBFyޓ~dC9H8 -@GL ^&94@G+ā4˜..fѴB)>)7#1Ǡb+IT^ګjFy~-ӯeISBBwmTz复 nB@:ڑ`0%K ͳ ϕ|)S0z5d2Fb>B;pg&6ذUm\F*(/Y&Pr1t'~K/CC6øֳ8AzAJ |aVzt!ܟlҬb͋:׌h'¨E"շ!,N -:0cVؙFWTMY| 5 *V=]L׾',5 Lg -fUJ67#w'$Vq6:/ps0D؞3 SD@?f#^J9'BK@Q.9.0h;` -0$p,$7+*To2;˶Fz:m'~=0 wR^Dj!wAFkmT ԥ)IRJ$"*M(UQwKP&_ -My%QGLPu ˨\grrM-b">""1#Q[?#Ud$(~\X5T]Uy|A*36U02-7>%᪚yPS6"!A8SQy\!13D.&SQSLH`!s06*E}l>APƼ%PM*%&{x6UQͅ. m*[9(kK>FAQahA_ !$}f{O7G* -?U%⳧VO՞j|吘D|炁M/m ->wcЁT -)$WpDJ m`B$3" "7T#QFS+r!eMI BC7Yg0毤E9MH 5:mEr+!)$EH+ P#$R`- FϑLPY WǝY;"/59E*5uy&4"aY+ajPBtSc -2X5Gz{Aԅx' gSiqʝ1NEQlrːDuϽE#t>WT0Q❩I(Q 0SC!imFaTCcG8NS|u%CaU50ӺKР FP~RH`co"k MFIɄGqTh8^UDرkЄ|ۄv5rʽ -=m)Uˆ2Ļk>tObrT Y|nd:XMZQyfs 9CAtMe^8 T3_E[a3P8w CC挚 )Μupb3YςFG)XHc2/CCPb*yc\N_e%+r~1:e -"bSjƾT2U|i"e`BA#ɥ0\N(4~PG9iˬa(uφMN!|]\LtVyi ^, ->ܜ q$r!'F_}RX+Č3s֓ DFߡKFL|2wQ9brΉkf2 -9h (v=d D׼i5 Aw*1La\&ƄV8՟~AH(Df^ -Sq -wd=& SkewL}˝05^P2 -Ɉ,dƱQ 0ۜdnS/(l 4Hp0pd "@l`S QU+U[ǁrVHpk!,uZ x%|BQI5. -wlhѭTvhk{$-XQ*vm -eQ a4l(>X7?DuWAjsLN#m$4$8CwY#x)^iOHd5߳ҔQ%Ҧ!<.ԵĠ(: -ִ̟hQDY؎SbsF0.׻aUQiJ} SEyeR.i3.Q%<;(}.)m*j`7$Vd،A0%N{bhHf1l]xTZqD*/Xq{dC¬, qQ/%+&Ԥ1fiK5NӷybM#!<ŖlM&zYR@-%Gj%ZijOU H$~lX#Ef|Krn>UXodܘΫ Qm;%\.pce%4BtL2w33lɽN::bH4Wv# 陗)ƦHaih+;Ba,P^ۥJ73Zk.K@ Zϔ'/NpiU><5Ѓ= -<>ΧOy~![G^[)4=RbvY)ʻU_rZt*^^ -I9#ŋR"?G#29dژ߰p2L.MϥV᠖>nS9EI]"䠦fT/$27(է/svno(((݈tF;,q{=$Ei\*+Ae4JDv!9ToYGIQHBcEv򡗄QO%3QZtJ21Z}ܤP eHWcD=U^E6w -* hu -|3;r7?A,lқ-}}Sbķ WB!J̓&JR4AREF }\\ꋞZ\hLAe}ZD լFF4i!ZB Ɛ吩(]QJPp* ^[oJKZ$q|FKN(XZHMʣjIŅ,鲴sD+ Mx(8"[dB.9qM=]1߭!ag׵s)9ⵗt^;4<46{B*-%-8)qc(ԑ0%]UTZ/$dK==%[#;djTz>٫2kʖ:"'n˯3]P9Vsh8,JucyƺOOUH*#ڝAۍ/@YšL8Fk|h W6 !f"#(I,"3"U)l#nWСNOn  ?(X.єG:?>޿t#BVyt-99$C^>T:81ׄ8u C?:A0Ձ  :%|{"n=G |JriOt@QSbFH AX h`̡Gt0y;by@샊)h˜u18Bᴨ5FDp 2B^Ebɝ|8!*M'A g.+rQ4 3d1DV&LDVfvP.A._w ٯ6MSJ"{ՏhpچڄP)RvGHdU_I*!FRMP2zhSc&_#yw|$ܚDLԃL<' - -q}hp^ͧN'A({cjr %\*Őh*0mD{BL#FՈ …BJ4>P;(rEMiC6 C#%|P%xG8[&x6q\.6"#sv0ڹ7x@ŎMu9QhbARbv5(Bcxx$Φ z3QmGPM*>|&Z8SD03E]S),$`:HLa!z@׫CAb O`u9bːqBjB^#TTdM vlgE#vF*הNYw H⌖,XU;2$BK u+d]C3B%3IF+mộщĕihRnELVz#TuT. -WDR}uϙJRH -, A#+VbTЧa͐޻уC/&C+jl}(2iRT -hHH?)lDH*I weQcb|Tِ{URą cCўD ѷ;.+1lҔtߥ!9z|HŜm!rlu&u(!zr@~h! Bp X 2 0X 44؀!p!Р 0@0A@7X  ȠsN 2`` $ e 0hP8( `d *   6LI̙GsH˄Pp`̖:(YMP1Z z+aDu E*8Y13!1[-;OS“+~0NzAjCDD:Y5f<LjUQ"~u -f'9 -Ahe -ѱUVk!ԝ3vA{(ͧOU{$żKc q(L2 )-R,]HA;t -E9c*DG"EB=!E#T1Bd3~tB<D.| $\(ESۓ:u82ܙ~IG#̘ERU5u ;jDuKE38eaXESE-UjVUөi LHVoh䮟57 "rP T?પDF֢:.M Qwg"3EZ$J1GfiVHPЅ6(+|7yɄ2-tj2$*-C/%b"o["fHb9VrPiMeҏYDY_Ք*{H1JY}$B"BB~HžRrjLY(,9GUԕyNe\b/m -ocƒf֎?Dvr" )V(*Xq,Fb%I% qxh۟Zhʇ|`*KK$L[,9S/Tdk"Sz8%fѤ&Qbאj%ZOMxj+( eFQ+\RUo #r+SȊf*SM UL9\J΍NSBeK%ar.՘4sWqT)?e}~LAD3U&J9dgC.CQbfy) i>F4qMB uH492ԏbR&mɯж(J*CYxSJ#Xu.[;WiK~۸n:jΠj Ȍ2SH.STHFֺ:hF@@@D`L:>0@prZ'TnK;6N(hj`@;K~d*6SmM+ vP]J -sZw 䬞 r8UQ=KʿF+>6mrCe%1,g ;0o䎰W":tDffrGʂ`LI@{.|'3;<.[]Ⱥ\&8-h+.@iST "<ښR,1<9wںkxH T[{itCԎ ,6>6Io$fi2Gp(bb>"ҽwtg i.cjX;C{~̢Š1C2BѴo03ÄbN{r-*B&4SxCCH0ٱㅐub8M `w|:ڧ$zݼ5$NEա+-fGVz^^i2+ѓRFe8CsaA~ MdJ̭tA4QN͔oE[y3/_ת,okh<š`D!P Rubd@9XtP$NylI~Ff^&Wmhg`Zg,eoSX)1g~͉ \8y#-xg7|x#~ -HJed>$Nqm;'qj?tϭ #؇w4hUuw İu -Y*8Mwt"ڢxZҰnE$N߾R;f##TLҝ*x`lZfUrI^`NX尨Sq|=9z(SaL/:lvȜ[3b32m-*ƈ߹mI_}Njk,yzןyRwZU#BE7W2k{_kM_@ -S׸ }1es'B}KAyhb,#_` -٪韚&Y! ,iӸZ<PX LwQjg aRꄬNHhc`N)^ oxFW8kiHy9yEAnIy-:&WxӰd/jeg6g[4 Jtym7Q'Ly u-QO̖e3ThG+u_]WrʮQB2rDK^M+>D+M QſGDIΆ !"S -&xp.?1#", tMXWJ NۜMR+MIA3 vU'Th-5^Mr`OVWfB.g7BRӯB|JrRl!ʅF}cr%hS5XVଷ (EucCN:*[T>BOIWr:W-U8=4#͡+Gz=daLO#[r/c3<59ʄ0?m)㰉ō Nk>XJ6žQ"Hr+(u"M*\\/jj\QC(KPs](-.\q.;ȇE7,f vMvOE37t!&40{Vi<B# -f-оZ8H_9V 1b*!NMJrġ\ı#{i#Ҁp6@HopZ-obr,mM!c(Xh=S$wlčː ύJﷻ1 37`,}VPjy̫+L% *Xβ|`r -ج? -np 8XhC1{G+c+K -BY*"Y7VJF -R $/BVިLԉ,n7QNHY?rN&$ _{E3(QE[Vf3z'a9Pq$}6lҍ{YemYA6$(J5AJ1 -i 9*$y ހ$WAp@2۽Aըgw*2(SIVhQKZu AXiݦTD!0ՔUF?`]{M苡XCߚ Zg֑R -$+ HF?J9ݸt!zSMZR1NrlkXռ:i.ٯue̊)@@U5Ben!a8j&c 4f)e8YBl`iY Z((F)/:Bӕ5&bb!"Ɔgjv ?e,]>NpT -Po7S>u`GЋY{Ͽ Mn0κ A#I 2fb.@aXM Oۨor#j1xs64Uh,ކSJ0^?AC+Cה50AU/^NK#dͦ:tA{t\b0 }wqfz+(ʣ,1e>(rZ\s5Kf&|+E]@;S%`բD3*WH'Tx84Zf$ŨA4yHLb~<")rK(MИ#o'UDvAHz25702ի !*av2ciE ؅3jyn -M> |acOT3|>X!5&wVL2_ѹaܑRt{jD*h>  Zl95fJW<#7ېm!y(A7LF .E.)֛. >Pݪd˳^ߜ$64TFQtSp";sYR~^)X y>4(IU -W(IIzJU)b܇-]GQ\ӡ.Ί~q5߄g Z1S.+;ڻx_0kYlwu%Xú*5]IB٫:j w*rc:(aSuָO7(⥕n|Sez1/ވNtHu,f7$di;>`iCG%lטM֭pPUD -ŠE8XE5ُm,xAxX0e5y*:ֆdz$mu E9d~N (ZQ `⤘1E;OF9x w2[MP~WI62] -bfQgwUdT&}oKؼcQ6u@_P|Dñs[޶|ONP­'b,Y@>2 :ٖH&w0fQihg,JῬ\LuT='Ke6<Ȩݽ+ --kt97'ET`\QMk+000?z A]8Xttgz,$3*o҆8s9N%tdG6wKӐޑ\R^*16[ʍa& ~>` -LW8rJ,"Hɺx'PmCPZZf:LGVpR:VԖ -8 H^~ ך|\.=kl!RAXn'V#p~d" kl=مa- -Ї#YO-ʹę1bPug3YAҵ.]p֊eS-(X8׉Se29dV@dd BaFG.<I,S]^6 =@Y 1%ej-5ne;JRn]w 0mònD?֤ť>IdJWO"$%y"ae _A9Oa*2mb?*:豶G\ \Ӂj8r=y*FN>֡OB@5nP 2D5f* }Y1KZo=lz3}iM ~Q#@6QCR?ٻO@$6OIe \%` a?Z(FUY"e[F'pp&{^ƽ` ?,,-i\tT# z~l^Hv]xVs}~?ZW*_"a^@L69i22E dvcγs찺f^2 -3`7xPܑ_K.LW#7YKN-dȓ;#W&3LٺY=`{c##3Q ⺈46MG#9_,f>ͷڼ'[E3>ArkNx sK MU +%Ӝf)6af}j1`B:?Tr ( -lTm~ɦ/RQp33ʴ,PDZ|+E0_DY>fQ6:j)=cňZ.x (6GI_3FesBB;=,ʧDM$ǦoָGJC#E \&yVRgDX҃$n>)-t54[P5UK+&+w䧾p}jgQyX ՐM۲s4z$@*7$TDe¬iچϼr8|$[@LIڵ[B5F-}TeTXSXdMd]fi5ؔ(ϐìޘߠk%gYMugE0hsFR[P<zR?ӻ=Pk& -֟:ODVia}-\H_ϐxX6o@"2B@ʵR!S\яX{я6s X_2Amn>O'4M~5Hȕ0 ( li`2(mZ4U -N+zAm,99~Lˏߊ7"$ -K?¿,3KFe^A,6AdPɧϣ%#MVd Bw|?3[kZ1-풍 ]P 0L!&[{u-&_ՙHcck2g_@)86bFRm̲~Yb35%r۔Kj&>KSywlJƟd 15XӬw NJFЕrnWF2%Tr$(NHy|FVhiO@㼤v:ʁB9*;T -=[Pv5͸Lt1߬ -dD*Pq۽aXbraP>+fA%wP:sOXlJCiRrQY%͂H=iI))n$1>hpY q89r ŕ 8`M^pUjchM.9n3n`,X3FZ+l26E-B[CaNO08n%dr AF&c 1X79! Jn 'g3^"WyqW4j2&NY KpqALT*Vk - @; @P}Je|B2M@yksgvdV 9?<-M):g:'hј`z.09& ĪNc\"#&@]Mr 4;0K@_4aSg~ &?LL!+;<ȽWY-XblgrInjʻ'd:2w7,SpP~Ę'StMUO("wU]XeT4̸QzDEuLrELp#|=BD'^0 4؃+*A>"z)b\/IryCrn~3Q#l/P!|Ϗ 7'`gIjssvRrBl7GM#Б# &ː(D,c!Hn,BuI}%2}EၧluF /ŬmKmFNIGk&vdD~r _zƞeh ry! ]IHr+%rH{}^~u[!; -34 %E>$^`|\X&mW ?07fnZmL\5Vv\"K%`1'u -@D3GnTxSEXGmZda*."~۔84ЩpvX2fYAu4w\b! X=~˝יE =n.)|k:̏SyMDGQ'I)q/s{ޠ0š 0fG8*hԖB\~r єDs!SR8㜝CAlj(H!/sgIPTK}\."}c -/Lq^=n|=nu B J)>_pxAl pܙdCʙ`H$R !kAP{c>J8$;/jgq(((,$fD/3eB;d -X$ *t@i|Nf$Þ'k94vf'?4 7 m(>Ad8L8W8 - . SHT+L}4c?Z:KzNt#>B-ίqf@|Z -^Wƫt> ᫚ 4Zf3YRRU{4Qrk٣'aiR{efݕ)%{^s-ĭ#XN8.Dn;_:㼫[2Ehq6GSmap\i໗8kY1.7 -63Ɔ×+ge6 ?Al kSq1s^2 Z jyϰX-BKp8hQO(|ieL b(99:j<:Ƥi09 -2\P?ޅ .h7 \@gbVZҚY - }e5(dJn*2#"e8"_*}@fSޫz(/ZiDž1=7*m0Λb&8xIo;80,D -~e=fY FH)N0"F Kb$B(WB/TKO@|#l-s{ Uw zAcp^}FF?ʕG(.;H8*]EUCnr.<) -..@D|6 P9-~_axG}F^EdD ]P]݈y;븺uߘ* }پ>.X<+ozܻDxJmuc9SHuf2C5\Pqk pp+0Z mº,oے\SR["aucBF2~J85 Gێ>uلR$!!v@~J|"?ha\==xj-;M"3UA).,貴I@h݈3mlnZvh& .9ά%LR=F&Ad'+@wM/" ,ia@X(;w.bkbc;]il"_ =+6?:ElyضhwS? - ¦DR|*XF4t?~𶇾qΡc4bZHIBA聵 -0/*,/F6}ZIbmIdmb;~Cqk?FFEľvp,JHi -~Q1cmT)5 SEE=*ޢ5CwB[F45p?**K@d&t6hmȹg f2k8_&!7=B*"k̚o^;e -HV V[ -d+\'k2sl[㻵9h[KwK VXGU==Բԏ%J)+踐 -BKB|)^Dz=) p kmM'9=UtfY2| V8ʸ򹩗xՄ-8zSZw &MJN5_$i-W2%w$Rn#.QYG{tHGʬWf؊'^+Evl#UkFu[Ta'"AB 7k@ElD;пfvf=;K^Xng\e%nEW{qgIa1.x5?,Bwb)Ep=N~)UlqDi?0 t"6vÒ<4#D׮T:3"<|qLn?ybLZ+T"uT5tf%̭5-fSbki Y < -Nn8D-[^|EfkW}ngM|?mԈSz 8r# `9&~s ?'+*tbqi0ٜ -j2 ``&ʒywVBkpWpo$J|F?ɠf%>VG. @d,%ʌKv@y܇!Q(.{v.;4w Shl RY4jD$sV+R;L$G^>CR͎H?BAy)`dC޹+I1oh`>Eic} { o%g 1Ϭ62>PǞp{>X)mP0KBo(5Υ i=T갡 !j繕C O"jĴND,)l@L:Ӽ-4 Ƅ4W2u8?|vUqj'[ -X.$qOk!xfe[ -.ngMM ךwN8+;<\ 0aDN({ixꨔNi 1d4 -hKec-pB$:Tl[n MIsԎ:GFcx*m1;l3O|iUvt?dx"_(17%c`q *TuoADpT -OA^4G V6FKj wbMޜ '>LNkPC)S뵌В"^j=0b1I< mL$gZ -`ge^z$wd8foG8U0g - ,SH/VJ/ضn)¢YO@oIv9gCtrM gt);RU4hOqvO A2ė2; 3E!OK$l9D"lM`تq1Ž#Q>j²љ~R^8y0G#MUM18Lr+Ӡy3Î\SFU|0Z*lڷ c\o[SP֪wk'M ў .KJAeHhK%_2_bE $Jp}4P ⢻]chhWmiU=sTI؇xO$2}`ݩZ./~{uE|E[~Ø_VSzwud^Ho8';¸Z/;( t.dNr`cdO¿' q-QK[D]iOEy $|bLLנDA _޴/%XNϧ`=pm:^7kOc 8Wco69}a61yi=jBKDLӡu1'?WXFU:%S:Cqgݯ:]m g,Pl*& -/Dܹ]L`T:qA:z X8JbIv>=w;;,wS+?h?|R7dE/2hNmRиxH!Ľ2A Gg2*=@-W\߀:}U;]c>*p层C]. [;b XJuvƤh>m{|jH"=[%|/ޱɚk*7 OL\wqp -mߠA^}< Uӡ*܃`g d- ˅:-M_x r4k7L&z38 /P#$-T/!Ʃ.i*@P*9&tBpb]AlNĻzMv#AWFi]k]E3g4{z)))tD7kwv%i&ٴ*Épo# Գ5CE,$wv'PT>$/ !`tũqH{]%HcCPG?w Y4-"8U'^)S.OFB:pO?K0{ 4Ob9SW1TXt4ϖR;9o/a\-Bd>z f=>F(-pNdm2_D{D/E^ 9O1 %xn9tHuez+`9:3&E2'W -Cs2[*x4e#:RS&FP{#}GPÖ'*$*J5h qE;p(d@'wXĠ5ou@b[b{:vvpCs3F]qҁIk ˷BIZѢڣ)V$nU>vwC7SX9p01-)?U1k H!|ІD -T\x.. -\ H5$PbBt#D$P8єgd!ᒫ$n3- 1΃;kAa?3.1MP.Ѹe~ѭ3~z4_t? /LCCZl>JbmCU, wd-nU,)`LiUЃ9h$0;$]͐f#~,(, ayA$\Q\yY۱X2f -rE a*#/P6oSX\^1szR$,"&+,|V -Gu>_/SѬ%[y%'q G+ NqtA`Vg^П$+?c6#S\;-ސ< 6]fE)`YhwB <59:k1ͥ0a<|/2;xй.F uύH%ʍ#'V^ 11/ֶ>ISʥf -Vt{Ճ<,NIfZlQZRpqB1bgu2M.HaZ9{73Ղ1{UY砶 GQmYT\ Ic|d>V%~x{z[/ΒJ&e,Q+OidMo6 @BfAA +)4n!MW-_>{ZZRWت" BJcP~Ly:ńV^N`5+iPc>l ĩZo7?'Vf / f]; ͎!]F.a VZo cY@~v˦400oԺ[WX[N qǥg\*d.4D3,6s#rt8ֆ6Iz)bP [=BL>wà `?XU;-;aÔ -9r&8&M bf@òriy>XH2l`cVA` V6Г3+|+Sڟ.PKCBPFYq45jg - (ޞr336"s9!`e]L]Njb,'{7E]h饮c ó;&ЂSXbn}TcseG+E$Okk)sYM>đG^'4b55Xdb+MJһw#!ދs!wp^)< g:;xD$\'[KVKeUA JY7\ThteȊ=)={ )[۲P26NeA^,}S-u!ӛ+y5 -tT.> W4rnQɽ_2̇)*Oʕޓyi2 E&N'%~PpKʰlmL ~gf߼K0~b< y('S /ˎ?iGBlQXxӟe}bboUBy! J&I]d!7~;Rp3SΏSĬ+DžCUTݍxVZOH״BtVaJ_K]M Ov9޺>Gg'9v}rwpinAO?HZƊ6*F}i kv/x Rq hf'~21GWY cv!y:c -vea҂aL{ض zE) HJbbߑ.jݙtݩPnHtsnlXcɸh-Et"L+Mo:;dXP/1.(.1ku&K{xa) < -I)='l(4{Na sKc#04Zåp;ɛjRx(N:IzR3-R7*l%WYu!l~bsJĈPO1ݜ*aa KO}`:lB* )EoY%,P9dDAͼFphIBտ" O%/+E"zU ^;<~\П0ސ^D]nT˻."J"΋Ȍ8%lꨉN!Rk -~eX |_ -iq\гW꣰>d@B3nœ5„yOh…f]/Lp7HcÊ gz{nBUȉAt&`Oظpw[Q=v=.b j >kOvw4FQ|,npw/62!OWN4j8$a c=m ? A&Ji 162%u&;q 3{p׎a>*vmZ;P`:6p7^xbzKaћsߏivC/\:[dI]I_v8cfҼ7Vn7>>mw"÷7-.MAݜ7X^ `wQnS[yGf7/uCFkk]׆_?DJf juK:B%7dӿ]֠,\k.@Dd,{ - -X] ;W-\r%r> \O7(?ScԠB:'lh\Er=D$S\-.8(g4 SH/NsF Z! 75?V7VUQN x|i`a)|mxtЧb&FxGuYl7}h`%9MD 8ăpɍ< -dA2.ks=݄Ae<ǞY~#+%hلc;뿼-ZI$wLjvTv`s8ĭiE֙59j@QbFh `c,3J;v]ZABA"Ts=U@H5o8T; eTAH0?7#d2bB(`}L8! yV(ക~wZHP5ZH wi M+.!(7$Oߛ&Ϻ!}ܐ$Rz/]HD!( C;cMA$hB$`3j.A$" D+sZ"r -&|tɚdŮ$ U&9D҂DFU?rM$KN$k(BD]0H|z"o+B|A\|+a5_a淀sGIUdaV-|hB PX~FGo8@1éem`OpX%SOzxOk1Pd$:oP-#cY>;b~%\w&l@Mg,}+MY/x3j@g~NlW~bChK2Od7M?y~<*M;ǀ^~VąRΓ'D -A6j.!4b 0@,|PL'"8l/o;IX]QAlG0KBÃGz1(ӝ2W6UF YbuA/%mefJo﮶,SV5$Eo.g X":K?o_!߫$S/BĚTkͼmcWB'ޠ>)J+>탤&AFˈdl+llV!}4jҦf;On>;0 e&Rq̂Wץ}o}>/X,j.D.ɔ,i1čHuH|ThIRZRovTz%IgR -]==0c(50!+wN7VI*? -eԥTfiT`h,{n> -lU笿k8C }J8LGM]#?>sõ\>bYP0Ǖ_Za>͹ gy Lw0T8ݛGZDj&^HtAeGl>׬ޡ ws(w'N;|.je0z=Я|nm9n/}VkJijh's)%*!lX3[*jCJ>7@k [)@ ܰ㻐g=W{bn7z}] {[M[PYs~F݊ĒFϩ-s ->8&}4tFngQ'.'ES/i#\(he>x,y{.[SC[{{[D)8 -ԝ^nfBVwԫד멄H:"ç=ۈ4t67=\s46sUo9bZk@S.8@yU i R˞1jd=腘>@?.nϫچA>NIbF08"[z>=Oj{j71K* {u_LVՅFU|o !g_+~h'`SW,mqȉgۖ22V&/ -׉r2Hs\ǿ'#s\EA!?#t1C=0Gr;xWJ5\pUeޫ%6=w XJ؏OTh?f` jK#}_'{d{Dg^*5}0Q~j[O̯7A\K'ZG -+H=#֓qR D - IpV T#3ءQ>$䐱'<+,vkr?0 2ʜz+(t ϾwR${i=i%vM#GfSfZG3_c4]`jw#؊bB m5i( ZGl yRkU`lG:RzA7Fs -rhHb *O8S(q Cu dJ3c6(G@%Cd{{ϷLrUl6(.(3FP[3|cq1c)Ne6LP`Kwxc*BqS]" pk'P)/~Jpk-0ؕ幖]uJVG'^כ\]%p|]ʻatt[Tm.ҀU|A;rYJ-S[j,Lܰ-6LD ZjyRiyr䌴Tx,6VgK an ڲLf{ SeHTL|ҧX]EɆd\x핤"خ5 wQ9g[9&RۉW% iwJxpN}tgup{n`%!w/ RDXrOI}H M+ĥQESʄh::! 6kBJ7~uL!p )^.pJ%ҠR|Bj$UKkPmX:PtÓ`rjDMc Q7Ixw>&}.}9ތY$ǖ$D.ő5֛<+bR=M|vawq,y'~I5'ULbkn%)YIzF;DFېd@lH#'\\/ -%4@GgHb#d–6g阊 RЅd0$aR84 xgf@eN<:x,XHd -.rŵ1[m&u -QqOOh(y -.U3Dqݟ8'4v|DWO냠κ^Q(~3jCj-{vVmL5!@gO/Q8 OR'lL+I{B{^B+f!z3s.IE?T.JDuZ{z.Ca'wg -7CͷsHvcF -z5DG ̩)h endstream endobj 19 0 obj <>stream -~Svƕӯ'wGwawӯYZPB^ER+4A _Q\[sMK|E!a`Ww-Ĝ[eP;/%bG?}43|]q a --:Iе}h*J!w/(YvDW}rKaK6<QkI Ad_᥍𴎦jXዮzCύ~Z*_0Z1z"}IP 00N̜ϊjj{o 8@q@$)L)g/ZwvR~gG]"[Ob]ʌ(Ӑ[Y|諬 GvIzI$'CkJxF+dXHz S3QbGL+DZȪGQ?P!W ^+3%]ubPF=Ms"r3*|⒘%KRvJC\OD8wPYKBST8Qɏ"Nah纯IQ5gj$[)%kɑ0F.!"Nxh>.SZ==(}%bDt۴n4CT%Z>;C.q')㥚~JDS[?UWg板h+SҌO*ۓ7S/"VK;(#? jϡ{P>>_1ylrbPTJtRn%_JH -~gx1_.Wbm,\F)a7oh"ڼB%?FPk;d۝m-fg۝5ڇZMm_>^77LX֔gxJ_H-jDLM,jbZ8B59ܵB%b'_'2)D>~U"IfB>2*ȠciyCʼneYvϏe|L"{ؾA^=<͙Ü>C&`P -.|W+#U5]㭙Qm@^2xpW٫nhTE!˗`A"ĻdFu@ՎLy [yġtZC1{(2L^c+} -FIƔ0Иr PF6ĕ"b1Ђf%T㋋F+$t?L).D :$' 1! -\5Q\hCz(MzVUyQSjΤ@JJNK$]Q -TC rCNC_&**UY?0 cMEw@saMT!Ցh"A5S[ <|DD,FbfetT:RJQ) }p($A*"g&ӈ`M0q35 h3,hN~Œ&S~F !b)$YLHyT F1C4R!>f, mhB!s -=.s;GF^+ely_PQ\cETDT1%NL2,r -Z]('i-N|7Ǣ":D,^m* U5>E`+ȕ ]S29d)ꮷm>A35"BK=>өi1+*^$Fe1>%LɎkx33SՠzUiSRv)}iEZ%ELS^FܯLig/' uX2DwszgP^)W67. 9$}'FddP&fk%aJWKTBOhdnëI.j~4{L3{BtqZSpH̵(O;]l<+cr(9uLe3ӈ Ψ*DQ ńd8roDY6Ԅ,*.)O,/O(6=C٦.kƮ I&5*!4 o9SSڽ2E% PLJX7FjhAR#1HGd,S#@dƨ*\ `j4"!A$껸N%*{..jg.)GMRe\UlE? -G4aWnƢ+K15]'Z GH+f⟎ ) sN2(aGːȳn߆3]zYvNkm!y)c$ZwZn،^ݍyŕʨ_Ǻr -E]Z,&}@ЈS;έH#=X`9kOUEjF{rGkie1عJ&ϭBr*3)gR|xMV "yU=[a8EҞE݉ͅ_f]+B$竚XHs&b(G)o.12Wb'aqQGc.S袩o&pTnUL?!gxᩰ|Fi}'"Ǟ2[܊F՜z1?Dbijh{9HvH]Xo?بDc#JyFgtGk%^lIfHGqKxct2Mg:BBRy5p>H9T.3OhWQN>>~W3dmOIdyUDw_ A*~̠'R܋_EWpU%Uf"jjKL:vp1sX<[:+y  pe_zKDūLunqjW%8fHaίL֘hd/`y:/liGj<O&T&ma}ŋ:B'˫LQE2+%8VL?+%R2 -BZfJL2O%.EUV23ni*N;QΆ.!fCE9gGJ.Kc%Fq_QuhkUi15vpe/-ݝTѸ+N>$ȵٶxBetI!bNrQcC6yJ|QHI}:-H'ok$LIT$>a􂟙qiQEZQ5S%+_bmV # -"R#o"(h9#/MGA/װD5~P7?bw9F?ԏpBe$J}4!mh+g(LBHې$"&lG 2$I \lb_y:U={)D.%s9 iDlxIKst;\(9UgBV2s?ºil6Ҹ/a'!ҾkXx"NQ/Ed}!, +4 M?p^EB^" bJ!+Lh,%7dȪ -QejR[9gYZs`yR*h*eGSKrtSK#J(Lޫ;nO-NZTUӢu&t)ќS/Ŀ:`,wU1u -*Umqx_%ETknUِP\%bUf>^B*wq'H7]ܺ[CMbJAB3A#?)MiT+ *qr7,͔<a/@YD=K?4/GFs?5cCԳ8;E?đNoQE'Frb<1Ȩ:OĠϓWy։x)q[KEeb^Xn{ -Szp# -N1}vT *D+t15T8 cLs =GO-"%J$ݨQR20&HKKWz\:%'-6yX34MI: -9yHs:]Q13P!'ZmNi0]1Oq^~FJ#-W!/ej$/B4DgO3D?AFqˡACsץQ~+ N,IɉDZ$ KY(T>-W>X RWF""b"_+wcdIkFZ}")hT`%4ERaSi>cB -!%/ 4Nb\ PDvqnχYwFg`+}223!Zݣi3vr1!#]bA= 0!i * -5 52ڄ2'ZQRD؜EC'xf,Bö I\y;R]:FMdWDl Ff+GkPJ,ʗJaX …o P7!X(ְ*aXa2 0 Åa( - j y H!Q@@7a(d1*LJjR!ũ"V4C:_<qfq/~YJ+$(F L!+E2 -HR\R͋=u#޵~ՄJ&h"C5o=qKV"?d}J[!Q~oGujZ}=_. ɑ&r5žW,P* AY3I\ "lgaEԊVtR~A~ŸQQӾRYT*F)҉7>(i,Qt&>)Ƀ '.q*JƖֺ#HsFZZI#iޞѤL[-9Gqŗ8j3LRAȮjuiqMX2D?Z7G+r #ɴ\tvuy&ӆ=gWӔ+m$tOJ)e9w2a)XĈuJk-!+[q&zcq?4Amc#YPΨp('*53D˥r bThƭ&+M{(c"N%rfYCR4=.7hʗ2ĉ1iGIz,FQyQ6ө5,R"~ ^n1V}׭4߬/gkkaܸݸiUJ /9j8’uI+}'3;iۙVI$r|~e׈D\{GNh–h4ai?Rb+l稚,rE/3ˈUlho@t -8j,VBEd͐.7#-j_Һ?Cɐֺ " 'DOޙ OjL:՜ 61S쩛< -BD>S?Dt6/! -!넘 PW>oTq,h3:QmDlBIVթc!YmjDlLu'e]ٜm\UVjd% S6%3 TbJ."̍[{}1mFkiD[uG0D!~ S`D2 w\V"bhBLzFس+i2i?o;WiɁ.=f?DG?^~7Pp "2D&1;[\\XYc탬$o3aA|5կ)&5#w_}@sh%|A5r*?!&֏xꤤM~D@(͇mTH~"[_Cmq/@Ё~<$5.&'vB>WbtPh qbyf|bFpRLkdZD0?XLw2!?=|̪fb!s0r4@Ɇmtʓ3;Zf͂uN21*YQKg+]q`OZ[|Uo`LdÇID?~h[V%46> wH?_Z yl 0/~ڭ7ÿXbT K\ ܗ 39eZ*BFن7EB,K+ uH-W+t~ͮAlb 5y?㷠 5&摨sVGV91Y[ 111\ihUܸXY"Ӹt Rtx6B4ï2 [*0A=@aG]Qˆ߰3y8?R,KQTU ?N`"b -7=/;ġ: Wc=A<*W"K zEBlaMi^b#~W!}/ٸt@fS͚5<Ϯ -!A 4F -HMZ -ǽ400l=Sf׾ -W`~BG=3; -3M.~LCa%iCٟ/&yH6ftBz-eC}"n - dN߰ī025=ؑI,,ի:`ŋFw&jh#뫺&=%YԖIuΞno}{,bY(!.o5@* k70Z:rlꫪzގzؐx.3U?V=oDG]JXt9~ST ny>+@^W=l_#fG7yo%/'tHPpFhXtV9(t/ƏVɽo"&/p:$ =(8NFPuM_, =ͯ CG "e&3 BtB(2اT4-SOWqj'/bՂD v>{^DDyt~„}kX 9_]tq/ccL7"$= |FXigB7g;/C$X51\O܎ |ѩ(ry3V&P_>"8~#T >6/fkoc< UeDDnUr!D/Db9p%RDR>}10PR\(4/N0"gS~/Gʍ.iI9. &pDA{4K a)%-o=Lb@+3ZqϨ;T= =OMCnTQ>isIuq=dǻr|7ٶdw #0NVk4~dpQDrseBJ -Əh#,FmOcqw=xƱ֤v(lD%}/6km02 O|/q<.)oY?`j\YΉO'Q5M'>7FZe?lf.v"f  -M-WćmɜVV! vyH ER>rl}&Kk;b)Ps`n9} [%Ba5v̂4$UF}6I4! W@ZYa4ᗡ\OKCD!A L )R$yX@`4&9lhjV)l}x:l -|,_~{WJy\&XbN챑-BtTD'D;Uy1^PXXfmO|00a? Bt㯐Hv} - -3S |A[/ =pj8ᄜ+>MB/U@R2Vw ф϶5;AG ~yBB1YMg;h  g0ðYEuR'~/iaG7o3+ON8U#G6]S%/{XE>c]fF2; {U~ -}}oVDⲫa5! ՛Cͩ*Q{1.ly1}n>E|^ 6hgj.{$5g(0%!i[{hb+\ҢLp]|8` -ߟhf3EQX+V@o}C{eZ>)@}4(3qxD S+f(.8H\8m,OacxGP2+U^=c#$TgN\+{eK"lFu&+ĺ{[nrV1`_|iS(@]`:@9|oCR"1WK|CQ?Hm8h|_6 -"pݹљp{{Lj=S ̐\5!U^K{wYz_oǼA!ED=l^)K-޷xދ*{?Ѩ:I9,yjYYz{ $}b !ƴw޳d9)Un{_3%&'?+$ίr^GNḴy#È DK~32=6ŻヤHb\} Ea)7_N24ҌQVH\Ec%=ɩLo tv_7ordﻅ&{_u}KeTT3=W~3B<1s}:}ꔨI^_Y -F& Oj=Ӓ!#[):t=U R4/KII6+#!Dz?ԭTuu4S+ -jsw*фdFCtG5=YM5,dj38$!E.]?P#@YQIz-m(AWAt~T0#\{C}ځ=66܁hR{EUؐ`V* ۖ.w w{aJ=0_'yE޷VY x;[Ma.BާD,}WbPm1X -OCI>-IoH[C1g]V:fAI~jY^"rqKSg{/Ph]ϡl~hb] Lޛ IZ1pKCq$S{SDIHhӟTܽ9.kx+),ϥ vHl{KCg&F]0f7e:@=Op1_]zPSh[OĤtX,ic^vʘ.(E)mMj-29BƌLFv'[Run騂sYMǃ<}&On?*/ܞ՞{AS*!#@LC,j^t}^Cr#YS*$#NԂ"߹_yCbt6A, -&N {*ILP ٣D1"2q6KA }A̞Ogx{)]I u5XOR -c@0 :vDHvYf_f@U vj!fNҔyΈc[,Eʾ9#P1"gSc K䝈 -ǬUNJCh"'ν {JU~ ƫ)ā`O]dnUVZ$~;[_lf,K09QGnǺ>;~nsp @ -i1De芓#[ORQ`xk~-Q+"X,4WF!+WͫZvLs%^$DEpGh^§:t<-~bZ(YQ:D}c.ʱP50ҽb _FATO*`{L4FQD#^Xӟ>R:fS8K_nU\Mo΄8׏*=\\.fCس8c˗^ cG_J!vJv^e^t^b8Jev >T`sd{uE,W 6$sfe; NRd=*2-cB LPwl.X?0"8qBj\9) 3cȃt'􈟷 n1K2qGzDA}" -/6-F>y SBƵ{.cfRJ'|偙\2>.ƿ +FܹΫ -*a=:PJ&e;% ɔU̼@C ( - &Lc~mu0[ٴ2J߱E`dPN@&Q:B'I/RZ#A&y^yV_R(7 q>SJѵ@**lyv L?4BJPCe{iʙo쳵^5}eVib {FhޫGSѬtF\1KQ~㽂< F^kylc2&YqY\Bv qhJjBs:P`xySo d/U f3ڋ Fy񙙼Cu;8-I$9FX Rܰ4;85Rs @ORY#,s%kФGS@sr?20 -5C>Gl78'9tY6~ܱoo'5^Jh0B 4ڿV28Lxo3c\[3a6axنJ)_|j2$'^TLZ<+ ,><$Ld}𸊏dĔنH"y`,heݍQNrgs xI rbduOGdC ]P ȿSS`#TL`񀫷on&k+kb 1 X$^idjb )9|ΩmxFRV=F -7y4(a?cul5pQQum?)H )h m :/\MFUv˩8ƴ-xozȶLd6f'G: ]C^N} WO2طű9 ļ7kih8Q9j45fb#"59_9"p`~kYJ++\_nWsӗs?CJa̐-ι<qy6hL] -rC':bGtml&Qo,ӥ7hlTx%TQ8@?'h `K&ꬄ||EԎwU04 4M^{޲ұG#iu>:9T|H_hɤ\a ~d힅 -dζӾHRQ@ʘHh;kֳ8ёtwnw+rr ]_3A/M"D-a7cYѓd-z/z@kb=R nBMHR?R>g[cFDRe<IZ$*{^NAI:HKSSMhuʫ; rt%K/> }^-'-`Rz}raʤ'sr? 2Or75fV;Jk}u}V}%TJIvwDȕ0iˮ&z/1E -an@Yü6P>Vo*Ų{IbnX@a,t 儽x7T$#q쬦=ЬcM[5+P/IRH.K١WMMs}5ZV qh5RҖflA%STN0_G>H'ZҩiRn GQ, f $>1עKsOc; G߳uI-IVcL+;[ƥc%g'i:)Q1Ч Ӈ槌s `6~5ĕ@PgVVH>WIℋ~#NfU<*?k#Z~M~u*h G捅9UǹOIXM -zs}&!3Nt}l8q#}&dkI_K XGUMs;C}lsOҁrwcr%3#&*ggOT_(%%kP}"qrX-^XbwJcIzNUR.E.Xf$e1zi8i/VP{GecB%:Z0|+b/m]wO+2' S s Qxrǵwʋύk9sWr"a[|?GwFt+Z9?Je 9Hтn|QA$ei/b|tclꂐv_?n@ƺ?؉zA?%j/5~k9U ؤG]gϿ/Hjsq@gBTVufn6AW^w}` "l݇\HMzS耚j.-~>Yl]?Os?v&]NvCM9ў'lBMZ#R#REFNawjr sӺ}. -6dpk)]:_5O#|%Nj 93s\DZ'>. v$SDDN$G36 u83&ӭƏAgj×JTÙY|I60ml v#̈́6sRp5C܌6LR#?ǾG(N=33`ԗ9;~l6zGA7'DKyiU7ݑarK1.!ݐNTYB~xRiiv )$`P&IhҒYjZ$0aGRR4?V,XnNz$OrD٠~.~O#/OKA=?Ւ?/qY8yV%5d2IM~"NbUJ$ YVQPQxYԨ#?.CSPRXY 쭠H*((G*#q?Z' k=GPJX"?I?'G̋ Rb͹'&#=+ YG>*~%ܓgOeVxe4y!arNI R5_&y!Aܓ&$:Ӕ,O8l@=vI1IGn<>ԁc^zzOCP[BV 2Bjs'?Ɲ4c9=\d{-d@#9$g+44 ?3CT̏.jbf< 5YC$+j ^*G@In:$bۧ@ w<#F'yt6@iˈcCC,qbCjXVGyAi0 "?];,x ?ru' tz/䇟s^WO_fpNRŒ uځD -<9wƣMY!u'japDC, Ni -a~P$M#E}wRU5!໓(/,4@ItbykI}-QSI)gu_1** uR8";m夔:N$YIRnNRߧ*Nv˝.X"\\VZВ׿ᇲ㶽`^դLf4PU;89[Wj;7$uۧN?ӫNB#NHIkG<\os470yҜlijǐF# 'A+EpNLR\γ_{[(kѩ-Q:IPLg +a: ~E/RmCSXZla{GNG7C1~)}K˿`k1NOa.o5ghBqU -Y|(=PGIxc|qt4 g%dvO4ZHTCדp?gzjMӖ91/9&n71BUϓ[rГT<" #㓪 g(?g!FO"jZ)zy(zU&Azd㱧?DCc{u~ ӏh%Yq~ ])K[ -˟1M+\GTY'8z!ϮuM$yR[yDE0d^ J|kVװǘB+y@cp lY HF>7pHQ,* DcR_,$Koò -'`Kd'Jlэv%ɕ>P? 'aqA͍6xG-T:SRn>bDAK\ -p=8?]9y@=obH6yn I䉀yR6y" q|W'š]8q75Q@ƃ2+uٜ0ykNѠל,gbלi>& ap(X!4&Z@x9 YMݴ?\A`@QCex9;M@Ʌ $Bs@TD"Hӈ\fڲRH8L -$Q @\"2Lks]P@N YfPBRJf1NK2t2*iڅ% B#]H6"/!t xt>XsUQ~!-OAiZuŠh<ɌR,c^AtWQ"P'~ALUѥd۟JK"8f3*uJP&$^zrV:!. i["ԄY~xJ'VAlw 꺄 -n@['jT#9xHHh9ɶWƷoi|*-1YHH4|$HH5eJJݭ|< +%K'2F@S]BX J\ iQ*w?32PYMXA[N/EiRMSeTܰAi̊c oTnBȐ*͕ ϒPWϰa\CӢgxӅD>tg/{]?A`9E Aw g:Kt7W^we -dECNd8Ӗ0=H[Hk!Q~^]'䬤+XӢZ$]_6'+T`dN5#nӾH1nOU,DYIB]KQIРnLW}&Ɉ?\ՓH;N򯓾:;'AJEʵͱPd})1 )>?0dJ7}NCTAMCS(~+y+14椒7O_IXURgaD,o{W d.R3v!ѸjU:}Bj *WRy+mI(HjVW"b, t-ѝRlokW ;WUoUq:쓯&n`GrM[TUi^/CYVeiG#B=2n4x 7JRJgVc -?B8l!p^*? 86/iLK5𤁬J!\&Tf veT\B+av[8^glRBnHσ,64F햡0շF&j`>J[1/Y*E ecH#32ћq yG&>QqݽF/Qpޭ[{OP2)iLT^ 2ZQq"FP*ctw9$j/:h(p3,"ur2҉oxe6DŽJ<,2Q/1X<bL ]5S^-LcX8d`j9.XT2 qW@ט\ic*0,}b_ZC|R6O"dSQ] tP11 JzTuL4D*Ã/K7 rLKI{|JWa(P۹/C[j'}K SFs|z _Ya8n(ScL!0[11ޢ)Wad*bTq`P H/gtJNcqѽXJ dwDŠRg (.mF2j}B2zC& ?J`&<ʠ*U[5drc!2m/ % mfs:y*{`LC}N6"~:^-U -'|dFS_L=LLm2VO3 Lq>XL4́Dвf(!xQЩg s-dl{^& ix].#PĴ;L'M'iR+[j"h CS-L t텤(('C,$fV):bT I]%{|"TU>Oy*c*=q`U+UHQ}XާrYCJ8T۟Rh)ZB(#) >' ќ*aFΥWpPZK[I*~ޞD[J3R -ePɡPV'C{0?g'F9Qߢ>ΌjaQ pf -/g -o#fR>*)yB0T*g OJN̝t) xtMڸ)f4d и) )ՊSW4h+XJ F%- -RuqiSyvW@zj&b\b])B(3qwRjwu*!b*e?5 -EމѲgkʔS;&]V2՗ҾwNZiy*>䘖S | jhqVP /ۀиoEP*_?cfX\T+wLrE'V{q xNXFUC %(0GզTUO? - t0*P%Uhj28. aJ$-MМm0YllbTNsp"Љ`T MPTb$fA:"/4gE(1͊w@r]%@0*M;_<\/~`Tɇ'lj)0 T^\')0%v #ky.7!$-ͨ#?jwV#(`Q^U tw$olHUfT_PDA;MU.6w7ڠ3*h -skT`X,Aw6*AJXZay@Տ4- -tϷ+g2ƸM:zbx TzPGBYeU!VETOu }Iz~ڵ QhWٿHU=*BS^4 zTLAeg[{. YXyTփED6'PH yT["Nt'FnJY'^H)0|,qLh*d|iu>{TSxa ) |.8v9xQYJMZmwiCJ{T~:)Geס=%G>_Gu'4Tѣ*䗛iQ maf_@zT~B{xYz ,XGDQY`o=tQ4u%$УPk`}5U-I=*?:ͭG$&Fp6*TsB|N#Jxl Gb -$Cx/w2I4f!zG]|ϣh9>\q z}'|A(J2BTegG}U Q+dtt(  *"bתdsTi˼  -c}8 br FqTS354"GT  XtNQ Y3N"F!qrdQmǦ,9>~>QqQఆ'!;bLv5qT bݐmz -7rT -nnꍗcsT*c"Gk5riLAk l 57*JHTvF6~sNv= Y(꟏EQUNGrOʇ2-ܨ,1ŃN CoTW.ōM(Qk)%-T UZ֭QTQlN!=+F6*x`Їolb&QaQ$?\0*g,[{%yzI .`Tt{KbR uniHR,OZξdףt9sèPm]YE=4eq_TElkr%n7_Ea=cLNj*UE*e aTЉ&0*ڹtW?V*O7$@R}+Um1DOlǧ&4\cx(6*GP0-U[k+za3֭;h?Fs^hT?Gj/id 6>d40_FDK+5^Dj(UKW!o)~܂?8TSl5L^Wb56H>@iTr|qhT8*b2 J@^H,`Cy?E -OQn&=wʓu<[H@1dWY/"mTMn.z<]6*V^F5mҢwԨ,w^=܁pQpYS03YBrmT͚ҋy.FUR9"QY MZ@:t pɷpU>5T6+yZ&W3jG,WZuOT/ٮQ*5Ge -&{l:0={졆TT+C*qIR]-L -ᾭ[b@ʲ*kE~DKz#D[]YU=, -kG."duTΥ(S` ) Nl&Rޔ~J,K{EFNWrzHՑM -9iϕH^ErtoJ h/J `]"댩;RjI`Gs٩H*U#mjtX#8RqlCH_H+ ӡF>K\Kj%ڧ ]F#vtx ReG^xr9qĆIIE)K+kB?TSM|jpqПT tz8IեESITɪbe%oSnEGT.P5kz'-6mKIIK'O*3ܢ)7*T=d{O yJWJĕ4XO*T`]ϲM|R]YITzܕOeD纏Y@ȓ!7uv'5}~Rݨ|j =-5'&={m&yӓj}Γ7'oo/5P*;.#t:KK^}R1,0Y -711bT#׭jB: WyG޲QUe,* oj -3;))Rt4}wB.Z%;[uT1n'tRqx=Q*GcI(efOrT9!BypQ*\NƊ{FLFʼ%:32|T)U@ ʳ*r5)U*rϙgRS>j c-bv5dnA?|RCxt\P"f-@R*%g8%JUÿBi2U ѓRm?mFH.6v_Z?ZSʦt*IXG|R*gcnJNRBRpEH`_w2J)Ǯ`T Idk|R[?򚯀(BTCyO C.EIThT-zR[' W12#@a'L`!8ȆsGN*^u2 9|j4GIU/?O*9Z[7D%O*rE*}Tn7ӟTU.N>KyR9+nÌ19ѤX[:a@JuēԋS3TTU45J[]z/\?JE2%/nN2)N07@ -}3sQJ{5ѧOkG2k%W*.ᾖk#v=MLEE1r:`8u:s5L3`ZSMMK jun&]LU@0IJL]!){pQ+;k0%Z\T力=.|TdV-Ap' -nr9a`)VB1HLQ(e4sm0U5P1*uƷ&L.=4Lv `KU}]0kTٍ4z^&K>F NGιt{&iUY9.:\.2U A$S ްboy ;4 -d*.4іDjpL@dmVZG"Sqᑅ+JRb2UAF8Tfw$jT6ut܊ED2v7H)23΁,}ܧvv24']B2Ud*Pp-M8VLuGYĂ -(xd*2?7@MI}^:{2 -lTe*z1rUK`-S%mBT ϖH]S߅L50B -blq'S#_886T;ObLAd*>S.>+ܒF;T>Q₀HTahN݇$b*}}TPS.@|H"S=|هT:F0)d*"qcshd*⮂Rd*:cT4SAR:b3,S2Vm1f^j=7FꌞA)&f*yękL%(@P\3S>;mf*iJM8:>+3##@f*E+)ԙJ:cT tVeMLkJeL;NLff*Y1S]Gj)KFTpF˸ ʢ.zχ2zS;Le' -3I[Ud*j]T$TPJ#"Yb۵fLկ=38_Y J8jN;H 'SqꀌO ,ByT15t~KY&t[*SV -^3.Su{m1?> -2mٽz*weTr(Zx$jej:QTT#W|7(Be*JTM~[Tɳ2$a*DmzTdHaA*| -iM5/I`Id z.=gJ2TT-{/ Ԡ|5-1kȥB5zQl?2KyT㒏}X5Q9)zh,k*Rث@HpҚ -rIii\SQ-]\3yC,:G1H6,4 czAaISQy +bЩL2AT(@r?k?NUT|􍚈* ;7SY°,X3\9r;uCf!T -?.RăNx봓)6^:Uc[г:(n{!6"ޔNl`9X?Ul SNW}*pgߧpSt+>W(&O%~{)Ԓ"OuSGǖ̧6?˵s r*E.4lFQvR}*> -Rs}*F2r>IH[%/s(*SQ{?ZkFyqO,lewR5_wj( zTQ ~*̞ygOG%(+pS2)`  {}*dqn#Kan*Nv7OeNЪ:T-}@oֲ07V;ኑ*|5u#)jDS$TU0ZI<&pJhEPgt6d HѲ/hBfWqb> #(R+WZ1F?ܰ,.=+َ,^߃9JKZ z2p}!I*4 v 56#mo2U ՠjSHI S[hWTqɯS.9tfUKGA$*C΋r.vuy&vUeԽ-< c{\yC >onZ2.v'r:ԂQNQ"<(PW1j%ieExY'U2N,ǠnATcFTa[Ƭd"gH#U]*"1ćǹ|5Qv=Q -iv{e{Ҍ8Ț2ew*^ -:kV|DOn; yRACQ#. ]mA0Q+ %ueCDUc=& Bk[ӦAxMh5X0J+Ha>9S!= Q5~Ue+r8sx+D;QMT <@.og?UzάFJK\5QZ3*ZqFwM*BCXS$UH6q*WތDTDIU%$Uy7ЎTeZRmxvqHDj;-pf uvL2kTqUamI*Bf(呪Fp :iS l: |rAne>6 H?<@uQָ/ðXjz U=.c{*2y _U`؅بn`?Q?f "9D##}XQer`ݒSUlsXdl"7lOvwR5B7d@ĨRXXɳwc2$!޴X{iFݤ\Dݤ`_J5ţfhcỈMou~Wa'=\nY%_Vc `㍪>D^#ܛ{ި*W B}ꋚlT*gF`Vۋ ب7<ZJYr*lAhDx'3Lϼ uʃ$co ʐ.`QpMH[ -#F">ˬU/b 4ި"YzǘFo;rTQ,ZntTK=} ߗlZ=^g:AJ1^Qn [gHo FA&34F74$h90MؗݥFy~G. :r&x9QY -Dy UW7T"4G bX|O~ܰеQuøA2d) -rC -P}DQ i 1AJ@@-UU k*㴈ChTIoT1jaQ?FUígQUf _?F6ڑVUԨ -lV&Ԧ5m]I?(1g_ߨ–S}U`ŦK4WE -/M -RӥHY]AC^ Q FPQ%Kw82fQ%h΢E[ GқۓeKE!} !;Z(dB*ub*sJC)Ds-In_  6f%@bʧr"T --K\:쩘q ;,U/RiT\rVT%à*S+1Ѓlh7L$TQ, j/m29U -4*-{ U?6U+,Bda=#dPEb! Ưc> ؟1e0B'F|C4*iKv8tnjP%'DHzv,L~x`u]0n\@io]rC]Ug&TByI"<d0ӚB՚J4$y%TIҠVP !TufV/:|=N.2IJFh%Xףe\u5<FZM֍Npj^&Z5mT껸uQ8/gW++mBQ̕K/صd|SǴYB.OQE[sa+E0]7;Q0Ob_qI*qF (<wU>l|<,3nOUSؙ27EnfnC!ʡ. €h^ZJNc8y\sҊE O*  $v,G\U%UI|\G~Sk+5`0U7[N1}3.t![ 8=3ŽxOGάIL~p]VejC{aDk<,fz$S8{|wLTgqtbݱ$mGԜӡ15Da"@49Sl?]䳐Gɬ1rL4rT R5=A2lD2 y jȁl2s`ܡ> /ל6K< >[b>CV$׼#aF17%8C?S,L-M!v%: -Eb -em%yzqMlzh˙(.ήc3>S]Zq86zXXH,땒I-X8::O;9y~qԞWTv<Ƭ, N#Pu#,Z{xTaMăO1bBrWGgӛ{ed8 1*J߬{ⷩ'sW" Bo&H3[` -=T3GKXNEgW{EgA˥s1I<mHQO_JptnPZqqjmak ¤ k ?5E{F8Jce>~n hWL[WZc=ˑ+H1)eH>d+}ˬ{cV2Ssf=.MNu6H2yũ!v&82YBDLpFe%y ^{ gtPj];~X!뜝 a#4mQ~Q!g&@[PJWGdX%!}N3ia6S#<&*¥6<Z "8<ӫ%1[; Lii[&V]#ٝt5$׆g5Q&L4`)P[5UT2z܋wZY~!,&F7zP; N1"iZcQTB/(ƼKj.[l>r [;]%~+9b/B{%֮\pڤ޺)X qVv#!k",$qG^>RZ3-sX]Zpeʄ?cz GP&H2brW~R$̣ ^hfua5sOD55şx\Y -&. - op0j , A?%3vnYP)?6rjO =ruu_眄UKӟܤ -́5Yҷ@a[?lk{sS&mzɺo'S/fĺMZu>6Xs#v:V-~|k͑ !T={øqp,E닗Șd(Mx*֜Eqh܎\ _oY4McvEԔᦹ Dv3>]5IE/ vcF,[Ø]"FX/Թ<[tUu4-x[{pBacij|!c[] a+h ~uU._bvޒ.k*pQp8N(>W/^i$:G~uL˼kle?k]$ZvZ 7)@kRl;/JtX&de -FI (Ί]MkH?m:C!Nf#nc -PFnf#>'ϓC,,B;'wBD`fٻXt\JAvJC]Hl}/y+b޸yX1yFW) cSu{6gPА,ܔDz(Gl|Ukp񒵙.oxfsJ7aU5•:p?Ld9ў`n\Xdqӛa9MR)41Ѓv JI6n2V1 ;.TiA$֝]ŷѿrN9!yU@"z<L|?I??ꡊ Lwom!t8jrPpT6`Г0, -]C":,urvw4vƚgR"ֿ#:>'t$뢊;s]Nv6@%#3uMd|5Z#}Ċx`Mc4k@ A2W +w\}niTi9vae"(h6d?JiL=<38rz%_d m5G3j172(o][?5ܻ;LBvj5OmUCPsoNWm3F~TVO;*8>;R VNZHϱa|[3/{oAWݶ{8 `JD*њ $Idb#4 ]ͯ[@z890]SQaQ4:QV1[n}mW63¬ -ũ!cRߒ8mGoeϙŠiAI(bVOlk^)O@f -%]AQǍC ϦmM-v*ט"deFs >SGF/{+1 -Sxn%(F<[\yX_ tj ̒p>4bP%("%ar3'ęם/CxMX(|Jؔ +ęEDb@qtsc͙ߩ'4sFxVb}C -Mef|ZOYH+!*z2 "!4&^wV^d8IL\#kEƺeq?Ϳnb7]U6AⴞՄ N*fѫ(m,x ]y6~z^fcBHm -oEʁk_Y!) ˇ@NicdVUo*:L ӅBZoӑcOGq"E84"'q;:0ƏN3f{A3Y,,аXaC=܌+pOĂu)p382>??2ֿ'|2wh&ql~ExWǴe4F#>1ߘ5U! 3 ;z%( w5N[f~y;3| 1,?/Rs A?4ןb8̱Qm# fyҙ` 9%x҅Cƒ<ᖧ rC?2[&pJO7Dpb9Zv.Ze ]zQ(H#hZp9WB#PE>&IL4*p$ £N&pE -c,a*ѫz4͔f ֆWP(6 S0CdaPRѦjᔧ#+:6OxZ2u;BfXAol:H'ݸe~Y(_b澥Q[nDsOg&ܰL.&lF V.ƚeWLv)&kAg,D$!K&Jx;`M7Ėo!$!x8V!I "x24DE*JhϧV+y(Frq,FPn0g 赏aQFoB£Xc҆^ȈEDbA=ܧ .-3c74űh͹ P"t7{43ҜX?c,A B wV|%JBۧ?3k8pQ,ht.^T{Qsp``0| ^&f  -BZ#Y B .`ahJ/ btuH\x+!.f"(.Ҭ5f}}::\'*r[HP:0,33_? -. o}1 rYTBt413Upq_mC)=Op満 ob5\Xt4HI S \Wrᗃ;Χ+ -xdt - ;p0nkN(b6 +!(-\4j-fE`b&@Oc9uw.w PDy)8AY̤^' CxUh?$6}U(țScJpqF$`k|NJ#'>4i6E Nr -꧶A&Dڄ(I1M#TrÚ6D.c9X8\t$ {,/3j]~$?jBLjq9_?'m5!IWo2)Hp" re%P 8.`UCe<,nQ5*O|t kGM9|:pylMP[dX|M^Xu_ɖ#3:vłBgSy*H ^|a{c?{?E%ž[^FM@8؜un/LCdqNjC-u`rFo arg:\VgEM ƞ&e 2diy_5M咷. Z r(p xGe| \̋Ɋ? 5x8"c[z5~tI>4ϓ;o0+1+eԆp adOz~QQ`/-8=_-pA$v=µk=yQz5Ayݦ65A)1!&6[5Z\b6C tز^DlGx$Ѥ.WPZRH@EfK# G1qXno=fj w o2]/EE+;Fľ)"'p$6+bJ_7[ Пw\CM h.`R{tҺ -F\:tXexMv5id_.~L7JB3M~r RH.n,,@KP~W \Dmo*%ANB.^#Nh SK.Mg -~r.FW^KU5'J@s =D8Yb*1ײZۄ.KbxI J.2 \m\Ǽז-ߍzq{_]8p27Ț+.ؓY\(s tzi\4ρṄ!0] T \XFy.K>${rP$0x.aɠ!?w7W \҃'[B; J:$6Iw^$~ƋeKS6oAJ\0S1((ɛWuۀzZb)[K(.`4:y3ik ~n% 39U 32>KWJݷ)ۤ؃}Qtd (.r6NscnΫ>N_33!b*O^i">mcj一RtPEOYN~%b\!ىHBy ̠xC~Lb ۅ/x,08pa[1PU;{Eu6j-z Ȑ5%n.!t42I9c 6OSWx =|H`/\p 'ڏn p!M.L \DrR,AKX2%ZB[)MB0ڋ1Dƣ_ٳb]{QWQD0JD.-xEmj xs-z9 -./CnsSBd-/'I 6@q…$Z#O[E6~*QCt]uSvE=Nh3pFou$ø ͢_x$[EK_ch -\_g7ZGU5{X"xzD%i\N<w /lR\eP'HggC 6E.̣Oc4n(1[i(]~M?X'_b9wOCz lq G7Q#ᡌ.j<# ̮D3ZBv`S;6zGRo@.Ree: pR:``rh l_ՕEJh I(1 2ZVLSoZ݈IRFK0c̮ -,T#1QN%pʷ2-:E-aF#02#}>FK< - ބ2.*I.xTaPT|@PlbqZpR/.QWIMu]S(e] VP׎lP vh)!zglo8/s+$%F~߹)c%xܗDs%ZN"'[I&!Q:<' &鱿EpWrsiX uK+u6;g2e}3V?nwVFJȟ "?s%'PuRN3vsJȣI#KKOoFc>sJ`@` dVm}#)A^L shiCd#DܮI5iD[iG -UB\8ʫ%x]ŅNl5iipQo JuU9%D,M-+|QN ^ϗr`Ig" 챞Čp滁RyP -|i)dB噿+V !&+L\Ė:.9Mp_߬ ӂfX)NEo\R:@Ϳ?E5.{3)[-A)"Z؇29H~ d, ~!PIXCeNwOŔ`oQTabUzkb-o:6_nB@:!MUfYP-@+J"<9JHv[QwM1H L:ÿJ*DBA oTf?;&>[­$:!ouÿٶA $շj) H- -GtW3B5>htp1q)<[)ӈ }9N4"NҞYZӌSŌ;) :O*@B2=F -uuczx-1fSY[˂\nE4Q֯v -upQG~{\SOXrv=L#Ë́[dpĥGfid3YBs1o?|"dv񘆧TkAĴ\ԕ -ހ;K>bKe4\h[HgE-7| oxMM6\Xa7a6/Ro.F^jTlrq)@[i{1WEsr';-g "Z~վ’2m} bdݷxA7:bI]ڳ**}4WI$|o!JQݷhQ8L@$NXDAϙו-RӐ4^JZG[nbO )} [sWIL@F7x覵ԯ)A/2] G ?}VQC( z4j[}X߂=xmRdI}*u[e28[~5o'Y-5b>dKcTCmXDF-#į` \Rԩ!<1m~|+t -O -! c -^k !2âX[2djY{ -?WE*KW .Pǁ0ep d ,xSaF[0ѷu'.< ; WCŷ}(*{ Ĵ&{֪&YB[IJo{e.(&M-7̾ƀ (B k|Bܳn\f*kD88V(V̒nrWsB ,JMqg 4GTCRpTv/d`| y@8E[Vljτ,WW˼r E}4,νʀ,[8rx%N"DƮU< Ʀa6sVu[u;h+y}ڒ]CJP-?mh0"1D䛤 Wp@EnBõ)txZ[1oxQ-1E%KdAAn:4E~97A&R7濅3˃gi~ew$<àHJW Lߋe(@@^ʩeǗ`88?o1}[1);`‚ [ujgY^xYV -?οE$`{drX`bBhalR1-Z4S-r$%=Db&4lMl%XDMj]˿c5hFc pIxavuo7olƞ=e8m:cgyL/x^`7֖3 -9^C6=r!lG/ɲ#szfJ} d5< ʖ{V2 Ƥ{G]*{%XL쥦0:ldY\#})̊-QKn/S@S_o88SL+L|&pEv06 cxdSdJR͌7bgfm_kul֡f+0|_,Ef@RIPgI$CD - !?m= -s!; -HqH+mh2 -93Dht[W$׊E>%QbYDw(8 v(աPP9?-hyY(y"4,(RY0Z*,\̟Au8hlnOZO>~>!}½-'p-' DJ{ $>NUB̝z"0<3D;l~@ډa'MDҎĮV8N`5srΐgq"'LDfHқP_71"(qx&MpxqK}&fDFC\䢏&X ՄMQZ #MdYhMkhXgRMm3e&22%^!Zc"c i `0,/aH8@]h%4rИ/C9h_" .wƪ7-AK_b+} 4 -_{ņIKh]DDR]1Vu r 6h%Ls %fK`{'rsϢg-ge 3F߬ K }%t%L3mDicx1:Vm*1/AhڔU"^ (@[M[%8Pbd)ܙt@*A_U"AUlVkhрh/خZhScfm- 4YФ _.K@K%Ra*1,u J~oGx*dslЩĻVr&S 'hV @#qAH8JݦP%`JX3*zhlgA=%jAWJPXvqi9wh<čDhDVf_-'vG3IAZ}nHQX I'HSiēW.Ô9I˹[$L)I5HM$ DYOj%@]$z 5?*.:Dvz!!A^jS'$R z T $\HZ?3V##5*GTYmT2`Z~xPV+tG[;j01Vt_31"غ[0q"X,4P.d{"$."[CE wW"Ί5٨*7TDplSD(bcCt:X'6&Vي -/%%"8uDF8[_,<ۄst!'`$S$ݴ 6!"F-Cm?AI!\Ѷֶa!€2ÙfIpۂC"p[ɞWjoc7W7ۃKcԽͽT6uCmΫl(hI]߂+n>FvnK!nUsS\zpx a

-DkEҠؘe4Fg. .} y!p!D,D3d"BBX - ĄH k$!B0 -B8Ax><xAywxbGt>po:i:derĵg7 ]މ`G'N;AOq)P.b; -ʢ -D;cYPε9N + b~L]/tg -^A@G1q=9jG?gJHBϥH 7݆0t͟~S5M`Ǫ RÐ?`C@D݅>}P><|u{,և$$_>R-A6!5> #a0%|:1mA΅p{% dNQ=\n2I+ qM΃q<ܾpRpM,"EJbpKxC;5Eg$e No* m34u6x*{"gw{T/ofH6 -'<\؄tf@F;ʀdHQx7r1< ÛgBL#؃EG`I<]4$wE!p5 +^~vAfxy2x4+}<%<1*/-fu,F$]4#L\[Q<&+̯]>|QɄ3c޾Go)4ӳːsfڒTzN {Xar \/=12u\7;LE~={wSCܫttbg;޽`Σ } BC^GWW|:|:yn]P|KQG"q|W>n`^]rrdნ}Az>uA_m g1 pO|ߜQ ?n> Sl)(Z+7W[eHJ22 w2&AF2}})ӨFco$% -) !~ zcPV,F8@Tc ^ Ό_mj^n*@h_(wi}!D[0@na8Å}:aC>Jj*piCx0~6P / a{I>^HaJy!e .u< Ay D0}طz}rl=.XC@du~\ȁo!nn Ooq[n7m!۷/xA1BBvjၫ|N MଭX¨y]-HY0rWf!dT,gY џpʷгXXaA: !Xv`!W(pk{g|+V}H`Mxc( - -ۜ&+$$ =ۗU%VWUiSDZgyS|W܈®d4ែLkSwD>y4c -.OyxL/#E}\kda/ #OT s bԲ`4Iۗ -q [*j{m/lCvKo']>,R'X*lNs3k2G(n0ݗ -%}<}oV;"!L{jtRGDQ!}Y[Ef+ PAj_(THLBE]` -37wB۴*P}yP>/  -'T8E`^ -sP.azАO -W?2( -˥%8B*9̸5{(Txx:Uf?*fP--ƒ]1tiS@O+=A5RSB{MLC1 #RJJ!IHB;1 [P T> -qF[9G!UQ((8(WPk0@Xz(\+D(b A[t@'OOAOi'H}'ID`_lߋg'NpZd9Mq aOPoY M&h&x&$4Ai1Mp]R+nR_B h*&&``B/gjK(4ZxKj "a -t%hb%K Bj)QŸP'`9 4 WNV>HQ$ qOQ2D径!aRE}[8޷R~|PE+B$apJT@e0E@" DDpP>A9O"|ЇAC >byt8w!28H 80 LH #}C(xq)8~Bnrm}y_ 9XwH=Ze ػSp'}wrR4:%Ek#+Rkd\ {[Cx hK[CH7x ]NYCxx0` E3_B .,&4bB8|C>$Al}s*50\Ƃ}OI|: *{ $@[ F!ـ A;Buji ֲ@}y|JzE} >w`|}%( 8>{ u{S(JTz`CW_A˃ӒǃԉN&DH;(j);`xlP>T ?𫣃Fe:0➃7A]7ǟ~9\+H?29`Ax;80p,; Áo/pp|hf7 5 /mEk\hH6E5M6@1,{l6kk)@;O1q2_'> O/b?Ilic;a ~PFCP{qϢ5S`[O<3) 0~kPg]<O$~~Ѿ9?4෍4d9I D_$<&4;rjnM3@̀"\'N=d@`d ddy \1B g'|~ Ǡ@ )X2^% M `'dc= YK,  -ks+~ MrAcƠ][0y1S8GS9W1 87)zc/{O?ㇻV1 W/1(52hD}B0o=~٨`!0"h)z8yS4y Āa* -+4 -T 8%\ >)@:sNIAO/IRQA* Cң4b. E (`'_O?fesQ 7OwϚ$(r8Mtc@ML H`-+M5`N/AF\j5([1?I“O `A 4e%AD$"} GЫGdGp `T"#$"ފ`q+s23W*hD[$CXAt:,cz -|a' Z(BpXJ@?*JBXc {B  c?ضxH'X{{ 0< s(Nw~ށ HNCBz:fTw<(s`8K8`@ipZ,?Y܀o kVt˓,Fji[@.[E e9ed{1aM0.=1PJ/@x -^Hؒ`E ӱxL) xZ~ l uB_XYX@W`\BFatx/?<X -5/f)-Y/0c~>RI - -%@1[j$I -=`% - ]~s:'T - (=ߧxo~Փ?WI?R/?ފgZ4?YXd:~)Q{ -L7X \7?'0O4؟S0~ d+2baċO ?oO`Yp/~ZcN$L9&~dqG@f1 SO]msf^J ) DIEt[ Զ-gխ?oDWwu-Z7c>Tp®7LNBA'wD/-!}Em. Чs@`a(hO*@}C ."+.jV 1ƀeeJqT-߼L  ]](淁E,]=/^_Z]*~„ HBLj []DU4h;q:8+OGO*LGa[T@f/vj)t#A}ٰ)'Xd6Hш{DG{k4+j83RaZ^L1Z%VMWy]I*lSF@ ^_L.c Zcc% :YNoEBzCr7Af;Ӡ_)ԍx --pP欩@C?@ PtHb,@͖;q {"[&U <w2jtɔ1Tt 57sAQ +9--M,?HyP$mțUu@g ؃%3RP~m#Rd@1cmWmГH=4jNJ"x}u4pKX 4L($TוGN:hjG"Ij3Zh|9mvA? |.ǫTۯ h3wflH'mr&n`/*&f"֎~yDd` {%I:o\)Z\>qDؕ@fȤK;uȉ3xߗ[v ?.MCNH+_e)`n3v#\n+9#\cUy֭A~F7U>`2I '>_G=d#9j}2@"|DrH(?cB,ꍲ8 #!_1c%N)F"HّT0ސ,K/WCLlY} ҡOXh0|B`WCQ.ӮcZڈb& H.}@KÛq&e3Bi`eh!Tp6#&xb.揕Pj7fۖ%F&_S4״ء #_4T!:87L9_v6ɑKR= 2tHCO{9GI8h9IE0PS𱺉i9"2"G@a-OzGM_< I 5zGGuM23dZME7 )9ZP|]kBlK  -#P)TR3h>HxF,'5LHH\7ފRêvYi!Ɩzxp%xI3Njj6@`:=4VA1ug@u(ұ׎8 !$ -If.]$<9cε(D?dQ{GAw  aH?Łga3Ku1RBQҴHXh>*}uC_3l"iP2UͦgLEh|I -H`4LAjl 0d|C4IV鄱,b\ ]VY4I[qȂoUvP,L. B&n`[NW5"|4Aq=k@5NL9J.!tƓ+$MRZb KӟE 8־[6Oկ.? Jp>j g?YWcđs&wֵSu儾2D`~Qhq &9P–[E/S~< _i앿NIvq^¡+B}d]i^`^w5S Fد}XL@zT 6!>_ ›2% M۳J16?zƜd'=BSP 7T2}b@Q3V[Ҹן)$~8!WU!UYR6WoF5'&9gnL [&+~1׽u. @ HhF/[\S@U -j#p$ $O;'b(hc:vXT޽ZȚoRkĀʦuHH8Wc$(*mX$ N@qC‡}^$]\Gp -#C'h)Ii< -Cgn !O_ASϿsoz5\"4_ -=K4z٪OurRWY3*JՙO6V"n=iH-<'X [K_[kd}SqToCg~gXMirL?KS,"Ճ%qS'j,?sIϨiҌLOFz//%W(:Vn); EЌ ?,J4FFr1EQYWp1.$׫5H!}z􊦕~ad8Z:۶ӯ4lzeqHE#B u7 T&9)9=ddX,=7-J`81=OaQfa.[E:Űsݗ0KU]RI|rVLﰘ!k;귉R(F:u'.[eԭ n;c΄yɕEޚl%+/,M;{ɭ1 tsN}nPdZBKܫ:d͈MmV)QlEsiSдDZpX. 2xF~7ׯ}T V'1,aH\G$gf\Wٌ͒ns5q:TĈ&/UXsb !!'ZGmu -~QBbf-B&T5d*y B1D"àkhI"PKLNCMzMuc`YR(,2OS Szw`A5ǡ EC`A!F@ 5M`p3x@B`3`@S!B"ܦ@CʠT5~RYq^鬣zDKQXb?##f[!ҜI'c]Ѻ23܉1;#y~7UŚZDw1s*)Ĭ,],LDM~ -+ B +*7Bj,(*bjBQ/A:Ed"&U!& 4 -V/ ⁞֎D#6ZWB2X``3%Qq r(fV=- -QŚr(^&"X)NS%3/"Q$Haa=0na,\#u0-V^ԂLWY$q@PH@az[,r:hY  bF&.UBRXs`eMAP ܷMbRMGR  :VD0B㱿Β<]&( ua(XDB -_>G&لSilJ{{}w6AA + ; ȶ]PeDL/߫29PmE:dN26@'/>hyhp%6nK\)MaOn3\FN&Ր9OZʼn2H!B5"! }Wb''PNgA{ͰDF~]Il}.|-pv}jO_0f94o4EǮ7&Km[50]*D TH䎹iUH! E*<7p-2a{LJ8/VvcXRWx6jIiiըc_+&Oe153k-7T"¾B[RxQm9 m-8l _BsH8peB8iΒD'by)MrALuMjT,o9` jM>e4d JK8G&_7aj?ܛ̑=4䄻ԣNt 5!U١=GTU>a -|RK hVptS'n_n{l1"ic@kMJ۝e;ҵII wdvM3,=);R_%+3AMRYeHS 'BSff!XB /b)#* -` RVB&:۫q )S V"=jR`/L 2^j ꚴdu1Y>/]TnD@i<Hj~ J:)v&h%_3A&>c@RU44QYƤj9ɋo;힢64䆚*;UG>stream -SXACZJw2FG!ve Ld}!0MqއVhar9oJpB]4[_ Na`Є.M٤#b)מU}%g/:i?Ζ]c~dvOmR:IBf#voRᏗ#輔B%34]01|R~.yNyS6؆cAG:;p*1 f5-4.N>ؽR471ϣAzcsE p4{ix ,ntLBl[,-а{ۑܶ[ƕ[ 4_re&RʧW"r*qpv.^6@U\9 -iSwR D}L)wh_9!6fw] A[y$P|쨧rwT\8yJV祀@)^TgL= plMlF.*h5c%y/][oJT'JpV^m8RƄc8Q>@40sA Z -f8~L~i,f.['|k%=: -sF= fMB岿Ԙ{,NǾ~|_`as\L;9׹W!gr e+m5F"x=t^bĖtBٓpM0gpQ pړ O4\i⊖T7C -DcF gwe${f#ی(O.N~`J& -WF,(XDiQ=ƾn>Z"}#~3%/<+@Cs(}49]–$Y(1—CGW5}=4tasvzvYeDL"^~:u܆Z4:F!]L|cvu݊ y=d&CX&{z} o|jy4^[5,8o װXX+.Ze|Q+(Ct  ^àȎ k{PlpV+o5H^7 0uYk0+ `wrq-Cx -+i_XE腍aSAtZX;b^}w(1<5\ {k-ょ' 9Ա g\\۳ayq!R/n ڠa {v԰^o%Sa*UJӅqi?yajx͇Ey31,MS*u}" L^1Seogjl㱱tc01 pUZ؁1x:#12(p-ZX"hǪH6#{L& L?}2ICDže 2e Ye,$[sq!- ,v6>`-l]vO^]~ -[,q#8uNF"U315ۿ೙C"X=|O{fg/LnXnE% }`ZKH2vƌ?W 4.FA HE8Y : M@S ?qдBEfg\Z7˵Eh=xmwk0h&dָAи()N>9xK2hУ Vh< -;~!2cHi0 ھ`h@,/а6.'1 CGNVr -HXԸ⩐Ƣv$yeh?Ch햞hh}y0jFr 2 *x&qOe@f6.i4тW'NhaqQ9Ph6h7.MV+I\s6.85fy޻24%#޸`ޫG=,Cc mM܍CԸl\Cո#C{ƅ 5.L SU_bдPhS׸P{B;W05)@{6qQ:Bp)BCaRWh!ڇOv+ih7c[{hh/L_i~"Hc\dZn2.gEMˇ]642,'%B1$#nnwf\4<SvBʛ{t$J~9CmBI޾}c\h -GShYLoaovŸP;'5q7 8ѝc -⏂!DX/.*7ŅųW-p~~0.Qpe VNsupΗbÄK -'.fp -"wViLqQ\*[GSq10S ]O\͠w~O`q!đ(q늋uMqqF;0^BB\z(.&jՉטȻT{i(JMiM\qx[EVמ2OukYrNQWN{' }ЧzmFy )./!`zT %\çHqQ$.wBG?ŗ2'Y_p%}WŦO:qG}>ϏZ@\&.VV*8~G}F2BBH-Ҵ/:F3KRI-oiMgENF$ũAE0kG׿#}WӵoFؾH߷ ę4NY('߂ѿE]Cn|+][d.!uxP^.}!gCU .."$ CQB1L>". -‘;l(p(zc~zFo%}S.-}kjn)O-CjJ}iP} R5 B]ǚ3XYoҥ5L7C$c$%Da90nQS _ 6gm]g=01 pZ7p!Ok_' -g b!ppI-PVXZ]r7C ^PaV \\wͻ>6;0 amtp zj⬭W/ڷ[\l\־B pa\k!M}.RL7VHu>s=0koR8΀pA<u>u}JwKmӆOM`^h^sPC:H}+AG۔Yp}AQ!%X uJB\*_Ɩb9H>h_E_kkC@]U\gfX:co?}R\Hk 2SyG׾¾00@atk2p>dҺK7' ھ43۾hۗ.br,WwJakfn0DVUʟ.5输.oKcU_\` t_ 5BB y_._:mp7q*^\,b5Rծ;~,\A.A3R Ӷm5jԋy_bMr  }V .8\؝b}\ng .Lz#}B k Ys1Kp}}~9 6})eqࢆﳀ+>+a \Zc"pY'}wtC;ۇbJH \ !~[eejQ81pA Snˇ,d.V.~,D6pA.2R|> $1}\>C_sO?b_&@SM"V$\\fE/L' .r*xUcDX)e?-\ |U3q+ .$X< -.Op!?ޤCpcc :pl޶ _Z(`c3\^8e*1Œe-/ ~t; K`? A/\\=@NӾwے2O'O X -\,h~ %l \t#Z~w'-ZP\Rb0B5* `P(-#.5JC".\~~wW쁟XE`-s6ah$pfLOjvxHïf.ZovWm3A1`YqS>=_R4} 2".kԙP2 J%bPoE,pmB լ!%_Sɤ2$0:QV=6zODd p pA~' O~,}_I J~  pAg%\K5/n FfZLɏJ]6D ?C,ppP~sOR$Km+99G"_х?_v'dDp\֦ӷt} 4A}9W~v} /&ɖ8ַkbʖwpbɶԅ۾ce[$_0#Go!-Pş$-[-0PN[1[.߂ Q ߂̠woL тo1tsCEM%Zd[h0! :-))"h,IN 4>-.6]pY]~ҁ) Ećb-6d7}w&/&DV0E}Y""r wq}+)x  ٳn!,@jc aڰҍŗf*\2!չ pAp1NSo^pp w&Q -,%b乩hhk`p#̚)$V=` puiLڈ8T=lݒre@gR@P/@4P$K /GtrK+Lj@uQCRɎjm\Ab!\ 㾢υ&MEu{^#pB@F*pQ#mZyqfRm${.#u.~$pq#yHE 37k6cj`9sg%-4(wcmk:|,,R؏ Ăvąy%0pMzza}!fGuȅD =j!uh2L| ƫ Dpao0\[uH^gP\1>.d͸(|I#´w~-7<ԣb*ȶ(BIJ "X{:ޣ\.^2Oq.T)La҇`[SHe92N\%A* 0JGb`NdEp"syɌR 7 !=hm"ϼ kcɲ=~XOVk.L ĉUwi3v^WB:x.2NΝW%.Xe \=`̉ŬM, D E7zV 1qŋ%-!Vp[!ۉSo/b4,wE $ ˒@5J]~qeU嘺S -&\(Ǎ."QљAt(,}ם K 2B) B&,j߂0_d3z¨.Sƫ AxY4I(,h^J5 @,vHqzaqadIȞ)A0dҸrȂa) 8Q #-Q rz+j/]-.zpԇ!.]P?$bT>+B@҅B2,E~!Yp1#aBsڗ.y5V}ࢬ!0L尲K -R ,t?oeP7Կ4XpAB-]%z5^pb$7~+x7IOm#SA4m cXJ0|\5"X ?\AќQmY˔ J}("-bُ.Ȧ5$dAUwH:bLYP3ayv>.ӹ0c\ ,ʈ1)=a`ι@AeUMt.u^Vvz{$Cwhm Q$6XMv;? rD4'@LMЗqR!d .r ^\W'bѹP?V .*:SSM8Se[(~biKTM< Գ u\ :VcCG\ĪIwa9Gj ,e["ƻkhXWbfCq *dq&@16I!̹  -r΅b0(f21`˭K$7*1ӸPes.\I!2ͤpf΅~"Ƶvo9&#7po0ʭw3~IaXTأ(3E@ō&8nn2 .zJB0"\OX7vnxtZw'QR,<=]hl\,1r6vMUmDzŃew˹ G]&+9Ew2`Uc#UE .'@(6:r,ϤI .Q W6xBrH(J*,A{=7UQ0en[pOυD< .(-<뿢rh,g W ec:\hoeN\]Gy\!>yƤ}֬FDs˫E)] -4rl!?+'ma_>08QU_ϔ`gљ\(ke66í6 .q2W(")z .怅oJR|0Ye8:$V4X +t0Dz/ q;':4qO0)zVp4b VfhZ+ re . 0hSjap|dUB#*x)œUfSJ>r<ɪbڏşe؇?*ysP.r*$mRc(Vr \7G -{aH,!bp0^X. 3*\v6zYz9Cơ .2޷^lV-('RXpe%ywUICaϻ*]䧙X/@n &eU0^.>yG}or]peMLFL[Θ*7I6xTSXBv2V ] -tK" -ȣ -ofRAnop1dpEAQ)D\,q c3Nq#{."j6沩hpL[RT(a'B -{\1 a@ު9Hh, ,<dÄ\f -2=Ra#쾲*.@xn~%鰁#]*{3DN\t $;^(dWm\.^ -j)?pak~+yb9 }%u<% zٿ.ˆ/\gGe fS 5ٹZ8FC ᕵBH!fI '\`j}\O"V*` .HPE_zE -c^A*z5vA.p0OͬhG -[p1$"(bQ;B؂W}fjE[BC4~ - A`)ˊIkǍsIzTFI%Xj`Hʿ֣B1`rthP<8UK2{ h=}hhvX!ԛb1(af4C̐aJE$M?PB5ڑC(YPIEiEOS,W4lä5)L1~KaO!l0?U˛m)WUAm`N."Gg~ѯGCdHUz!yR쿫*UiP.V#O׭:.U3 JSz;ſ_LN<7TF^B}R  -k v8JΨB"l4&>&ϬB#md4I)R@| ؉dC hJH/ET䓧XbT!W>|-b~xyKRAhEe KI46^]. 2<z"xC ShႥK 3^-c͓ -NWB4*PgJ'e\)_"Q;+n[4ܢa=f"0.UY{'vN׽Z iכ zV4eGԧ@VBUrI𣚷Zϑ[>^z!4b,T r'_]Z䦭c.tnU'$s4M[oQ>;ʇ'픫%8jSJszܢdu"9YzNr5/BX&ZFnˆS@/(PAj_>fWr;RO~ QmjEG.zas䲼ڤheZA9fRq'-]7QR&AR_gh]?:NC7(QtsIM}RɐpOIc! eIMGiBSpqP<nםVEèM1'A>-{ &=cܢ]j7hOc]bǞRI,JOj9v#eMw2ɡ,I+:R͑jzJ8r;/[do/`b,I(jU{>WG%p7C܎TӴ(aE_;es,~q.Xݐeu3 郒ӻв5=N!_DV-QJ۩GnThBͿOm*ߵ8rՖw -;?멂Ր>H_>*Ms3λmqݟzY[~6ع[6 799|{c -O^il ^^vz]W{]^jn[i%8MǞ,Ss\q(Sr8pYfOcȃ`el3w\uh'Mc(zF4A;y9ղNiz9ޝփq$f=So47\-N|2EIq!AGjݴ| o1|䮤EYO:'޲w},lkYmo Z>R2Cs#628М)Eb>zJ666jP~)VK;kLoLRn5?iZӊhß5]eO*ROQj^{)'MZb-GO棯7IN`v&g^f%zꎣ8s9;{$=b/?I{e%7fp;.=r=17 -ͻmўǏFùp:Heɇ}z(Φ t0;_zs۹ٸ<B\enӿ4 # - -Ñ76p︽;7qN6tsB%(O3?1A@?k=.;ۦRm9n:{ǐCV4mkMJfbW& 7GҬr."ra$Cgɋu HAџU?zR.,堨; d!)e?&w[u vc( ]eV9\:i(RӐ^ٴ]%(=CrY `(~Pծϫ`$=&yu[Y\UASd!IMӻThk5OOIÁ7#}_Gwِ Un{9v6(4Ů|(iNÉUZMslQ9I3.GDyPt(@NjZ٬ZwN wv:TU漶(P l rn8fCwuqց;I9v7ܜH2}oYr:j#s~,G }f{q4ўf}y`Hv8  -V4,1(-uRCP:vN?PT޲1;4jV(seSO$?5)z_~iw\e1[vܯ'f>hIRߧ8د +>'b&|Ԍ#{qשs1?4a;xbN8A?M簓7]p=o| r.Ar8mYn6/ݧfZfce;"duA9(Hm.[,<;wDDi'r@3A@JOAafٿ3u5Aaoqhm:7u,9ոVޮk7dqTun@Љhwx:t8v8lu3Yr6ZVwqHqfYٌB:jYeY֔Ժ&CP޴nkNلV'Q}4=&z= q0'jwR=ղ1;=}17/}n+9 y ծ1\ǤiBn3ų8znAĮv}Hw]e%dvZI=rpnS5NqD&;S'4⮃mt81 h{uجv8jOq[$anK3mjZ2םMD2q0ǭgN3?X8ݦi:w\k7h-' O(A@P'_ǁN1atZ8xT,*2e0NCp4JSl։M-=폢햵&bAs0w:nh/~Pd4]>8u0md*s[)M}qnͲq5-: 'NgAP9($emk3 pm=@WM k卋 2Hk֙pl3l pNA'LN4Tx?)egCw]}85.dƹC7}ʱAfմHh:*I#g ookٜ᜝qq'ɋrǕNbfq!uG1Bh~}J:m1,9xrAC<:aOm[l:qcxBMj v:fsa_ØE6}Aaz~f] Re%ٌb-6UCQD+uܭq!{ v9)zN'n]p{D$E.k ~#UU.2^{^u(ʹf}oY܀8 He;ڻmtAp8yRp@8c0$7 J2s97s17 !u=t{-Ͳ9;ubϣ=t:(p,_'s]i3Gsi/ݺNFlVMAp)5qvmk9.8)в4sEi73Pm:ҊwԪ-ǕefČz.+hMiEP4:q(mnMqApղwIN"gm@DΦjN4Wϫ64 =HŢ" -[rϓ탊#+#aDdn~K%)o,&{m'8\մ'=,}$W=d8bSъ6dz]y4"#KfO](ڣfYglMPE}MK;r^մ; ,9qI3ոy7 =YƱݸd @ID e^G{] $gjYeݷA\MSմT,cWQ.@1n6ױ;.\~4k0 ~w1EEOfE/.&nN|;*^v3>6 e r8HMS\AJTj9)?( Ъe$춡\ 4ԓUYܠh -7ќA)břr8iSzaYS-o<]yqEEGϻ&OS7 ցLzvfTl2wZ-Ow_Ǔc}67w᠜Me՟jٹM:? ym:Ѡr䢘}isv: -B{/f -~I*JQ ̢V4?8Rˑ]m''jO9!eց;-f%M{v!$]aƛ_5}Qna~G-vؕM%|^YڛnteZ$MZt\g'?ի ǒ.,ewKQ_%U/K{zU/m=(m"fZin:NMukP)p:%*%oy𦽚v:k99uhkN߇w (F$gn4m;9?vΦ<ۮ6Agُ#}Ny$?<A@P AY\$?IBQ~in93Ugmm֑-5^1M9An@L܀eH#.*wݶl{?PjrUףT;8m?A\;=q-?B{sf]_M$="Xwq7'Yb}c.b*%Q'4rW;rG;U"[bǭi-}#.TIN{0(X-*vAɟitIM}?IZQ4Y?o_Ӑ 빣h5[{_DH{wEjiU?Y{O(n:r8jH -:ML͸)9wU@qm/Zr6,{elr8%gcn6m߫mku=eIN"UE$)=qГ=m9N6Y0rГ;.8/j??9^om(UEuzt?pҌnuz˻<koc3N?ɺDRO9ah_miνy ]P9ܦfc1ѵÙR8G/Gx2T 1. ^8UCgُ $Y_ҚT?KI9ގ*8MNS4,/,w7I$N@Fm! Uezǩ<ҠJK&]zFg?䲦}jvW>]V"14Q|(La>*<|UCٓ"/~IZvᯢIdf: qll\mGQ8\]+Bѿ,q;4I;I75 enYjZqYji2'>&c,?eY?R|lStIA@NqANm=9fYu\M-޴ñ?>?冷ie}=6THqt# =IgA^CPC5ܵ_.K:bMSLղX`nզ52]sC]CrUZ`jоD"xݒ[שV 5sTɯ (Dr*wEjmM2oJX^KR,E(,v_[ZDZSRZfժ6uŬKfKn tP2y?BZxOӇmJ=Md z!Vmq0>Q0eof >OT9 C< #.薭Bv@ d::Iž 9 q&USl)~ r $m&E`k\m=(r8+sr6%g3{HMw,e?&y_ulc_u~Jy,C9 QqkYe+gfwf[5-td9NCyCoYfv:&wz1LhHnv8hd*/X㨋~릅 Q?:p?M] -NE*Cdu\:9~jU4^OIls2ŘF9ৃ`my9MKĮ.mqz]wF/G &ۏ.N!"_hM钼1~S%%5U=1K~ EhZӗ˞S8௣A8IT+v岕=Bh7\o+[,c -:]E(-?))j\Ytz_$aN{/CUP/G>+2>%$ ~ױwZ?}HU܎6 ^:xE)e~JC4E帒G]K%NrΛmT-k-&yׁPD5QV1E7K,q1DAdvTC>i{uI`x-}_ǝ *r8i3RՓҝsRNʹA:Cp6u:tⶤ+Rær/zɞ ?r1I2wX!iUQ*%G؊Yvp.u؝ÿ0TrĖeծ~}Pk#De* 3'tR?$yRA44Рa>sﴚ&wLR?V=\դYu)n O.16?z> 樊[mK7˖݆uOYG6 !s/7?-{;mԢ0"E Ă2TFcGUn0L;ӑ?: W!쎓3u׵ܶjם># %09^M+7 v庤4/9ArPd㓊zD9~RCMclK]A"8"TzJqw Hᴚvn8(S(bu7s޻mbyFqxgR͐9AO`O~oxYpfϫy9m\ 𓽎AZV0b+{3b'(55]|ۅɣ)O'1%Qb?ǝ? zǵY]x#_6_' z4ա_ -_`7ü]J \ZrIc?wѰ^of JY.W EYncmyZŦw_hE[4b -] BQloI5?`qǝ`v˩vǰWLEj{u\krnt5_<^m9o6۲M7O<}|~78~㽍.t2r}.;2< muwyZke{c9>ue~圷e{sw=sc}m]]i^^wiwki{i{Zu\m{isokis>wIOm331;UL2'M'}Ҕdb)J .hDm0uw3;$q̈^ݓff4t%¢Ab<&|DӸ)+#q"8r۷P43mpVnK7͑˒4M%<0qƎ%؏,)[LTʌ<*P =' -74GQWMS@Ӻ'oAѡ8JM4fY^/"42)<*D?O$kcrדGe4*yT  -&&>HU?ۣ*u4VTZ5*Zqgu#ͳ'0n3ۦuTE;ZXR+ 4GU01Ĥ_Րo2H\:ݧ'5R| -'&"ޣu >f'7tñ;Ů#:mWr8`dhp>,&P -u`B XЂp`&cu -E˗$y,6auşGma1zݝ$Ӎu2ueWu],X6C~=b ,`vԦ#8"b`' d̄b?d{tSCRnklhQA1O\/ p1d$=Se`P?:<{瓻3E0\9.8msd#`isa1w Uu{2vTͳd-P8Ţq(zp+Z@z_\UA0\};ydy@`d7h/xP1Bry/NH\2$(bqEDx!?(]m0d7p>馩۶r\u 0Au%K~ŊăHEc,㨏}8)񹟢 -2JNޟM~ i``bi HN׉5 J1 _Dێ?)_w~&mqXP hHY5L籽F'ˑ_Sm;p܍{9( 9tM=d\nhwWIrӶ?&&c9Άlc1 LsN1n7I!(B [)hT1ߤm6(*}HypziY,]zCG|^ŕETƵ!2%eBy*)_J!s=(8"e$=p_ZwY෧Ͼr($Kܿ> Wp -AzAXLU?隇# 즱ZjوٌYf#mY̪id>MPƤT`UEO1Q^GMԍ3< ezW鯓pep 5cuJmIz0!mz "=V`FPibPEà I)vgT(/*NhjY^붞r0fNRqR;y 1CEBb">Y~Aê&ϧi%atܓc p!aXqIq* yZ墨[ZPe_M#]!>#=ݺ>i)}i)7(J):D)$*L!XVO=c` `-a@H4჎p3.*}<۲ yqBI^в8nw^ZO#dV|lJ+( |p<'-=m]؟8yG -)cb$.uj~Ԍ?N4EPe0$7 :4(֡(H"qɟN{Ep)Idv~_DICńFK -~5 ER۾|x$I8,h Co7Ǐzf+P -C "`%zHq -Ա>kyY$=co[3 z9GAP!ɀ?$ !,ST׎B9J\<~%ePl7 F%])=Κc5[u":bJHB"$FF - ,#-Jbߣ4'uϥ6UMMq+5]98[B]?i%~&9sFz)>i2/Ѝ>T, Pzvҡzr.薁J4rG)=Mb[ے(l'][Kr&9]jZUy)'W2͡r Z iA6NGd /ɲ,N"(6e8m8VA7 ;)@R :M^u)VVӛ⋨bF%-&GxmW_P0Ѵ[s;Qz^DUlb&|_.~SA4fLiʠgX|x|Co%Ej3TOZ[=w9=p V%E}s=(ZS[{sSղfPRjQ6 8`F iD& 2B\,` -HnZ?IN˴N&:g -ќD1&^flBkZl%ī'4Rɱe)!I̅+ߕbo!&&"8bJ2(-^#X/OozUt|q9:<1d8ǒ]DdxjTuq!+aMm2ů|]WS&K~$nheO58dhEEIJ^t1/KR,J-)J!ZH\2am͟g5NLLT `!Q!%VcDu-.(y#_m:& f@|`Xu0O  Xx1v:ƸN7\NrEOeDZ6 ~#֊Cab(}3X\ S;.&E"e% -e!3\yD.#zpCE;wS㟀<p"Ɗ$~z&ne$dHAhmǹ^7S#Y^T*R#=ۥȁ !#e)N?7uV}QLnZ]ʹmi6px8!k' e_&б2PX\[Y Lc;IA+ߒb̎vfq:G).N֢rmCۺۂ,z.*+~AYr8HrP[,yT>U=yx]nZ^wYwus8GiB[eϦ5ʖ[:g=Ux-H(䨓denǽWz(WmWM(x@C3+9NX5LV4iٮEg"d\XBu q,\Vf:шD4ehݦ2a$^ء'r"b=P\C`i1$Vb|8Mt\R̾ZFuRro!Tŭ"CJǣjM0ʧh>jhE --A4̄>`XhЬL((;>IIhT$$39VGUOtnDGeyY9cH(@K%${bMķc2O]GY#uc裡+Ywe8n8:ԣ5-iUIlv2rӴG-RCij{<}#_xܞ~o_VIG2$Imz$LE -[ kњz/V+fqmgK 3댜'E_De"}y릕]u[#$rOSTWOҋKd_Vkr F ?]$SrgIqC&[Dʦga%I 2e`G0QOɘ߃ l)$u\JSW<ƂKeN*F!XMYGS `4$( MmE*KH Q{|N)Kkږ7OIs,+סGOO]U=-{"QFQ˨B;8q'"tŪʆki)vO2?J hC/GލISM"B$IpiZwIJ8IY@Qq2%ÞWӓX-Z~H~YŲ8fr6"h:j]RcXu:zee%sZWݸ2خ{n?K `æiص?tm7jx]ʣ=p:ZP/Q{p٤YܣfwgTUM7!5O򃎣5Mt2z M|dU-kROӚؕ7˷tA0V1Y%Y%8R|"4  ؉rVeH`X?(Ul9Na 礷aD"c=!p!\xxMUt"MjOYOsyш&I뤘Mju ,7 (R#6be݉'B^/&!Nҡx_u"sn@t1?<8_,˞U.k}Ԉ`xu!!}bHm#nܚe.rQ2RfH~PbhU1AO2U5m?YsRn@ vu5; )OLAI 'B0a )~ oQ֤zݩedk CkJY'-ƉIid;7jIJyffCkI-+Z?EorD9.ŗӧ[5˒r'ÔV<>mkZ 9SY44/IFͫzx1 -LRIjWݛ4_K7.p>Nu"'6}' -ap' ep(D4BPP 8v@b+DfOQ`C/6ٳ-jC=C:Y [o6Q4_֥}bbJ,q c &^^@qyIeTZXH]X"FBAX&Pa -H`Є$t [P0$ a2xA hȠ h|ࡇ;mS/4G;,S6X$ď d Fp$E@3 -Vp1A W~P!( I lЀ4E-((=_o=HH -h Dh`+ M1! -WB3A c0$ )( -JP X %LU4gPt4U\ f.d b0&H a4 J` ^`(82:xĴĤ>gwUm:>p, \(8a a4 c %@, `4`XI{7->]{uy1A$`08 -Tx,\ -]Mh*,! -Qh fqc<|CKLL[dӦ~-f`<`5 -Z*L g0Cp* ?t# ,`haFdzy@)b(2xA `'@A e(| 50`$" "8`4d``M> A$ b#< RB@1d _xx \$"CG1h^+܊㐾O@@" gІ)P =,@! -MP T4c{~xmksȎӴR,PJ&@a -LH+T -Zp0a > < -J d@ -@`08tXiiY@\}(;b"%1,p -,AqЄ(0 [PA @'9 WnAeu Z %a ^1a W@&T -Px@&2@&:rĠIOqde"`[B`) e '$ L8p0 \*@0Q%nШ!}]=zXP|i}UqB Hh! Uxް/ -S̀'@AN,6HԠ1 -X iH^Y]||+$!t YH09ȁ c0 Kh*@=( -P p I2NJP)yYNJ"C!t04! @n@Xa -Mt@x1@zp@@!z 'g$w V7` Al.d! iX@'H Y(`440Hc*\LzWjZIl  -(#( JԂ"yt$Mr_9mrKD.֍0L$z`*P -CB2 t@6f``JBF\iyzvM4W3]g oKX@f0PM0 #!%:YX^*& yn=gٙV$$gQ\ @ "x`! V`B X3ja12"c 42+(*Rm(=w()yPh =A'H,&@"D0 H XFG ,h`\L\QהT,0rhQ0` 0@ &EP@DDD?h`!"S"҂X#ӯ0ܦe)"@K0- fB . A:0 @ $aG 2hfDR)]tSΈB1P$VZg6cdynugN-i$9dbߋVt8j -I`L"RgHT)DT+^6U|߹$ׯu ^TzZU75Qɗ]Q9[-ِk˴# tH4!}J55բzGMwd;̲ jʇ'ps3h1c_S M[x,~((i_9uvu!"o1U7r0TDhѢ"Co;+"%lOIrrC%Ń(ٯ'rcXW}1y&2ro* תereaZze z]3,QKj$_ GvU9)}&-R9ޥ(o,5U:gWWӛ$L[iJaď'a|Ġ"FKIȮYQ$): ^u('5øYҤ(~䨒a+'0bPYR`U(#fis.cL \OM+%1B\ؔz[`N<~acjӄ?/7 7*.~H`Ԛ-ētXDɍ(~%UٱV@|QQ>ZLp先J$.hYz\K깂ryP/9G 2|iQ*2f(@=ZLXcUZp~0(??o2xIɱbb4.@Đ1 ~B;em1hI=]<U8Oˎ~gϚv*>@painffKRDq洑[~Ů?{)h$^)R"fdjqO7O]wՔ6W6 -C f\|Ȍ>/{nٳ fr{Qǚa T@A*"ϧeٯ#2dݕH~ZJAc{<)#R튓h$A!Eԟ Dx`J~,v0( :X93e$f9XK1߯>ɮEaʪ]>=AIbi܎tMWI'#}?Ͳ;M.~j zH@#ѭ+Ћ=l_&,$$-ՉgUpdD=n Uߖ)^Xm': ]Ҥ~GM;BYFJJT(25ǯ˰.EM CFLBĪ1(,\ -p#EWh+Mg("6N`7P`9Nb#{C[Zo)Wݱ_I@)!1YXFԈD[@{Ig'=Gbj7#escV1-%uj$zcNWؔƌO쪀v Hq܆XT5 0 IbmϠD1^)#Z(c1';ZDhX%T=`>J] -G֊BåKqSZ>DJCJ1dfZibjSz\5&WUhgsڕc7˛7uU6<)ivWJ2HX&= y]7I}@lz4HR8P\-BN-)l3ZFrP !j)ܴo2ёaVP0BRExiB>z*oʈgb hXf`H)Lﭪq`EtD5VJPL_~лrQ[+I15YL/X%zU q9+E T̊2*^qRLR|"j( -cF5C=h\2-&=m$hR)qQQ*m*G bWc%͔>i>~B`! p@Y؀AbG$/HS%1*ȿ uT+V%T޴,|n8P`<ЬJGXLkڊWgG X>YeѯOrz" ,1R̎}N. ER"ɨJ%zSW7E,jiaAĐ",2afZ%`1B"DbUzJPHx|(B%z rH`IGȐA"FzÊR G ̌˄c%xp?pK #aH>Xb)R1 -_O"n8=RV~1yXH3^).U*];1 ؋"(T)FHUU|#-"/b*m,qsin"  5RͰw@(@/zF)phN&6h~Ba"6̈1,cLxt-eF-\fJP1ǎ-J})/HTSĞ&xE@@0)D~# 52>ZFX2"~@2cHbzͯ(M&>%A)P!SHdIxȍD@2DDP/0$E̘ JT)jӖSrYN>NT@Pi*(Y# 4 m8(nw6šb!c)%Qڲc=`&^jb -&lp9F[dUB<ɯh׆-XHIAEDEJO|u)!$E3&0$dAx`ZB$hF 7X9q2XÞ6RKpR<*TIف!.;^LD@` rb%#bTQ!:J aՠpqB[Nj2D -sԼ1Ar38R|u<+=z+$F8(;1Gd0<~*=KvԦ֥(kR(> -z -2BLhl49^e+VxHQR7/)npZ2F.O GK.<^NV q@KYzVJIWT/+R ɏԯ^N!V P\Lց# ]6 J"Z)T[᳋Je1.ɏB$%joYCxn.=ſ?X%dH!͋2)4ש*jY$yH#%E]D1`)%0'4L`*Z 0G⅊9RD'ϱ{ LW'ϫ:>oc_Pp19' ~ēfc{-@yt$*!(xW>NRLЈ2` ^P1o;Z蘁qŊ'/$ r0 ,+(Ì 4+>`eqA4`znT3^΢H/: 4X"~)$=w;mEID-X']H5T`GP3JBv[JTanp)ޮR*8UA)_}̠Nf0%M̘{ ' RMWB]՚$UDhEMEx"PPl,_$ǐjo==yUѯ )\Lx%%L(}qnԦ,X&.(,'qMt B͉'0""Z$!C+7FP-}5^F0$P )KbUB-%٫N%w%e^ T:)x0kS{[<˖uDmT*%/$(܍'$2ձn{O 鮒+J^LС2 -jXĆ ')}+~=3N<_]qMSEPzq" -h{ѯ.oyN3emIr'cEɛʦS1s\3$s0yNٗ`v6(]]7]㫘eͬjnmRE0E!yfڪeV]H=UZR,3-`Ī+9V?yq29:zȩ^uEVAp/Ǔ}'q#{st>B, Ѵ?MAkʗ$9V4u!owˮY ZU?MSMP<@!U!ʲX`؉,YLt1>tEʑ\{N= =%j\Ywhx{zӋb}Rs23+3{N8b/%0_ïGOEfQve&^3.-vadɌN -_M2RP`H۶r6)ۆ".VH1!)~^x&2P)|DRG=?evnݺ_JMK}~sORiȐRxw56YP軻G1EJQR8`GMT<֞ۻb"I5R>&=/] z?7Mtϫ״~aeoQjP!80{߲ -l,sP Py)Nx4 X(9Jp AŇYCf~`N7QIjarM1)zq\Tr`z]1R4C)QY2noǔFy-)3t>IP!,2U~h%)w.7c 򼄞6I,:\6tq5.BtViR`D"L.RM,s쉵 -M.߲ldf #3bA&tE`g&azPDJBK'jYݛ4sIA;1 8R0-$0!؁P0c5P)@>,H R^/I8N+q (婲IRXnhzaDŇ'B~uSTgLZ7ͽ,}?I WQDJ'6%ᡀ|JRyJ -8Gn?(f'’!GP #`_HCx%F0Eܒ23r[k[$NMX\<,q ~"d! z⣴wݳF"ׇM.l)tdzy dx'?LF'5N,8|$lAY'Lr6ԝ?J&ƒIX) X<BA&Ex"؎ %\( ".z$˼ū;Nh` P,B -؁&-\ _i,&`e1sY_ߗi(8'LbF8j0Jp j`<@0B( Q%$dՌ%h̊<+_w,ߺK!xIQ#Z8@CT@0(A08 | |~J֨"sնDۥ_DT19Z;x1(RP&L@Hp@!0lT $H->fi`ݓFYV|1l||06` _@ X< S~)7)g;:-h`/Ap, - `b,0@FI*;T x>dO}[H 8? 0z`>MA -xh :FHpUx@I1ed"䅒A< }jJ X 5F0(z&v -@BpZG=q 2"K0d׎{|DXL`$GEh p%t^"3J" 7% ؞7hZBft@ -^P@,T+B FjDR;0A?n^2&%}dOpԲ;_?E`QC3pB B\`56  RD`0h %ia+>%.V'+uGˏ)CE=0bSXBX$A0)H -b%@(!:ykP:'7\x@1H4X5HB4a t-&* ^<ljQyYto2l` \HOAX`NX`31-L:jysuO@ `=D 4$L WnT Elk{GȊb dG;M/ؠ1*&>p(< o` "8VBzG+ -XbDĤGk^t!P*Q'J;!@A v(p5 #"UOD -~#lA |(pTBv&D S,C8 at %`<P}tjϑF JKd>&p4QLTg /xʤK :bfYm*Hzyʋ.h -`, -0@K?  - %¯ChdT6?zA&  kPFDЀ@ D -0 r41xIphl|p}7jDx@ -JP)!= LMHjAE,|xȰ c|P&34t0 J HLx@BPc׍"^: (j.#'@6ɒxgL.P |J-G>~'au(8 -Ϊu䆓j agubظK8&@.:|p#12J#0|%YzHUgz#¯H#ʖk-練2 -P A '(Bf<2"@#,'G?PUJ roqƦQH5qk$[4L0-Z_brÇՈקhc::b}_BQxCv8y3f -)zĨhBA1DhCGߠL%$³HwkD?' -rݘߟJ F zA $Xf)?٬ -}rT٧esnjhRADbXFˆ%4w -6Wޟu{ 8qaSP49U=~Hi!Cf$`,~.۔_ˌG%.#er_׊ݒO"yzE:6r&;q2x,Qx6Ʊ[gxj]yչYs td8qfiΏ\`BHɍ R,4>4B<_x`鎺5 If~u)hKsL̈BPNF9]gi_Z%Xv6SޕWN[x4 )Obn;h#zˋI+u=iuGCbdmH**!S(OB^,fRZ0/6w{s:;ijifW<X(-^T2Gr՟_hr߸v:ѷ$Sz7_6nJ0"~ҩCLKeuH)׵ADpX l^\ҴcT,9pg9vO2ݺ(%Nt=xj]ͷ 7?AYS;[}yF2>bcjv QătVCsϧ~pd;n2$m2=3ha'7s%.~/Al֕`&O'ؿ]O A2:)GhD~b*ti[mkڮ":>$<)oP:eƕ$ /"meZ(z[|R 4O4⹒gl":[=W=cWӺ(nIPNz,l~/6e-xcۯh~Ng:ئH\><5veU2U /("z`=#8.s] -u!j+,l.(&qcgkA.LA-gikK0ZdN7@|ug -dm'(᎞!8>a1=mM:fڅ/KD-p:VsIt8rQ`fǏYN@ mxxۦrKeuߏ9KAtNG3ͶLpCw_b`(ݣy8% ީu|c mYi>\R-/OLǣayv;h+jqƩ\F"2ڧim_P,=Is8 -١:(RB>U0y<ޣ(JO|^%i)bX( -_YucG6IahnX_(cyin7ii:hbd(=^WuK.U\ɸDuM1 q!B0lu#~"Ut!6;UHU,Ith,fU8p -m"F&BpE39a@D+m$q\!JA ""sp 2@Uϻ9#H @(Fe>v`)2xrwnR)Hg"0<Ct<,r(̊ȿvWQnMaU娺%lvQ‘BD2TV`C -&#* z͠D$Fѯ|ȱIfvdK*C=~jڈ-6ZY~Z @"&ѱnd8Uh$ @o1 Gx!bE a&B& tDH`Kl X@?xiQ| /M*"*, Bg\GF{P{MSo". #m+?`N <X#0 0"?A)L+Vt 0&1RԢ`ޯ5(  !Ex!3v@(a~Q>9 ^HA##Z a|$!@ ͍pA"zn~ }X۷.͕ۗ'9Kg|O nGxQ^@CE7X5zqRFLe,>bw7ImhY]z}HtOQFNq1T_H_A4>lKdD&ɷ@(B3S!`XF,{h0ϯߒX~O]yxuIHŢyB imיfF՘$]r2b&J!%y㨆 "?$GzKEeNgDB%!~y)O|&UC_S,VX/>3DN!ӂ -#t Zea!E 3JȘQ:-}Qur+fC˦1}b|rS dTk&$kϖ*~* w399CPD ( E41NP`nΥ M(^ /@0BfX,R,`4B_p @G)Xt@Qkvq`Bz|<\8A>smrJ5i(@0L^0׍ ĉá0M.(XB!fPJͰ9IaRb&e+U1)c2d`"յ7I)P ^%! 8" a@HLxԪ(ZւdAqs|U'#]y<x@rYQV13!~t۟uA6$9Nb@}I%v(+տjvW}ФeYWدˬD!#C *yYUIƊɮW #a -Io8ĮޖĪ'"*fC. nuо,Qi]EwtB £֢UAB"BI@ ACb1}VU_GWUN٬FZurZ01!~ E  &5 " .\@. LJф5N\VUiғHnl:~^;ٹ պW$mqL0ʮڕ)T !侽pfUk:vpb麞uWCqDFqinZKUP($QF%RĨP/|fٱesB#BRS&vϠ=6is1yg;@" -թWQ=G lԪKĐA `$bb%r%U- dˑt$$u罬VEaqSL/3B^|ua\J&!4PDh`+zEyZP8O;W^(d]O0+yiޣ9`j~cL,(7JB\yf5 6} 1f #t0" ֊Ja$aS7:N8I^`^RF/r@T@"!r* -2bCE,o(#,) -1d&#aV~ǤP06oY֞Gp:P帺kd˗𾨅Tp Z[qCF6^,Ac RG bт&!.dVPACdժcjyC~=3~R%ˬ^u3&#; P#4/Dh#eELi; LIxE'w(qBŸ~"V-MS"jU$-$!.F`gn2:$BDVm,݀^w鐐6QFkJE$?EwS$x8 ~/(;R(q#x@ - -OO+&9` AT;rړ^WfFV_dt{و"ɦG2 jYd9%yy".'!+`*!VByu}pw!:z7r6fr{ߢ$$)}dJ!*Ug~e/1JX-8jbH@񟥊'۲Y `A E1Deq,; -Tw8{`yqyTĮ$w]6TFVX9M cA0+*$ų'iudCp~ume4IS(b(dD0F ȇ/@.X&&N>*IHY)M j*s&I4UslUFZ $OO!*H{5uEP8vIZf^A&*Bѓ&)2ɠJ,{K7Y0ʤ_ -C| i$"JsAE Kz5UAdmd$!^)^C$Iq8O6RDF BZ7"@3㥥^G, ;u1DJ7Zb,'Ј'9}vt9dP4P?B],[NQʪ#V5l ^_#fTӾbe 2!GT!M1r"jGV-+ {ުm"m8'\}m0q#_w!}v hI .003-* RCDv}CXN'%wh:H9im[LktP:{tn:{c vX"+Q5^x\ш{[>U{tG2:`\T_ܾv)vzI|-,2RPDʪVV4E7%&3,'mup?pk0|񽨞}ey`X-,*> Zf93/GˊLSa9XƝ9OMzImfiuv98uKj ~a:.[F=P1>$`G "h\v\L'^/RNq4->&crmo7GЪΠǗ#M8]IIE{M%QpI"E 2hnfF&JnCB}(IŚb¢VUsiG5RMk/@P>NOhT|ܸ.R̲ʿۨ6b"-TR PAX@}Nf.GH -^= IT<  - -kvtTWz,pͳ̴3Fg,;K >1D^2'.RR`mSJC+fW7(BjRĽ1&0TH[F2&?H\/!˞IjrYQ aDc 2dX#ij0b,t<['n8' -jUN ǠB>dPzhSCń"tH -ʤ_P89)zMjב&Ez َK-4 q˱; ,kD*X^2mAjZ ~ *r_Tɤ[,R՜1(`XDמ]ꖥ~_jZ1L5Ghwm"wN"}+!HBf9A 䮋m98*8XU޲^s܏ٰ>/!O,`v-=Hɻgt,k9Szwۛgsp?Ud?Y;D*ZbLΦ?djⳛ.O~xX5<ĉuBlyWxQW\e|1)/H^~=M=R֔48؞t}v9u+β#xMqJi M뉇Yg{lcrO.'Oz| #ȋa?2ǥMAIU܎2.~+$HjQPjڣ!:=$=N9s.-=xHM=Mcq2%0!,GP ?Tb-Nջ^u?EjM{0縸m$)RQj$\Nv(y%9bWXV渓CO]Nk(E7n<0bIp~$5e$Φ4QUꗢO~$6=no'QҧEOPR޲JrX ֔QKciiR{FŢ,wIхߟU],=T. -ٓz(w^u#bUznqh8::^jY%S -xtY-?w(aXb uoqׅuqĽNIsɞ]fؓbiMUluvl96TĖ#zM-K{Dk9-?2'hKKcD|1'>ĤȤB$=ݿ]Aڒ_Ef%crו'y_eCAheCP'T,Ͳ~$aC_,v8/Xv̠B٥gU`/eŮ,wRЃm,$wI8wx.5 E^Rz*9JI:Tӓq[R(%"}4]N?/Œ[[ʝrYSh?Oʀ<>舝Bf5Ksy,:S6Fj:7yBծ0&i96efc5K戇\o8(Na1T.*P}u1 hhu( y)veoUq<^gK;yN+jY 2Ş}Za z\g xfC/{jYY.#1"UzͰNkݥIMRuT,]a -xVJ -9WZhƪzO'bUr&}rg_nmpahekY_Z5%UoLbiݠ7hq)8E(v&E_M_t/-EyW]4$4ihE崸nԲ& 2K^o,Up*]2$b_zY8HP ! z3 ~M[;7K4L;9tLͰ}umղ9pfP1X&=bM#G14)tj1-Ǒ8O^/ǽ$َ+;]KXcx]+vQKM~BEkIu. Ok=樇 %Y>1%޳V̯ǧBZf@hٲ-l$7]WE _PCJͮE?fN=)PI,/Pi֠ ArC/IyX/Ghǰ/Ş $]ar[R-wſ:ֹ=&z,]~%6\sYm&55O.({gV›1ɒvɯjvA kW,^ܥ&-٬[E -eG2%4npf[ղ=Sڂ]Ӫ)99 3ZnYu|Km*oQNIЬk!un8O2,MۅUQ'RzNĦ%6Kr:SmA@n1 i-Cd4m3;IXjH"v#zz+j o T $(];܆pKfKoaQ$Tt؍ i[0[ZQSԴC!2\:M^sREY у,Vi=͑?HJMˮXUӴCOКWjU -yf!MG䏚y$OZa`hEKl"m4'bѕU(]zR/[GЀp@q찇#s(%~Β!D*q`hlDZuweRӒ?ϖ7>(wekA;\ C)BMi{4,89C:BQRzUr\ѳ|!Vx11V0KB˔hIaHW[Oz}J/}z^ iPAN^֢uӒ0\p,~UbQxtgEh$=)W Um2Mh1 V@ * o[~%wu2jy,sCԺEq'G~wO㶾 )ۣ(*nQn:L`&m8(ڧ>;}JE.?Ħ:xQzP3F(I=yp;e:Vhq%WE]O{z^zLG}0K/ZџrG Hˊq0մ 4PfJҪfq+C{ ( -4#Q22!>F?rifj[ 򄢰v}m8\7:nYlZJ},;;'MT 2=&b՗=w+AfxnCo'X-8B+@@A:{n]9V=hY#5# -e,xzۓ]A^QMO)/e8!j^'V: zˊhMEn[ .bGy_UMp ۶w䯦9O3?Mm5}e늞C+:Z͘B> bW5C+bXDx4;$Ygyl藣k~]@)חgM=*_њ'u4zų0`x칫AirSVGK-*M*or,k K|r \2r4ˮJ^ v6V֬Csۧ${?o/I@(jZ|Ӎ H=Kn-݃2|>!WiiMM|_z܅  z ږԲgZ[_2dO~iT˲?OWvJnGx|E4jn{eEgWomwt&I% F뚲]i|Ne,g9KV lrS}K*JJKXЎ6v:]jYiu s[7*odyr_u!APچm]/[ƟRQ\fOK#Li3.I* WQ4޲@YZQ$?I{e9FRkI*JRQj~86H==ٟeϫfyݴQ3-`5Ib -5 -Xd0x $C<>w -^-9>R5dɓөŏ#j`^A@L(J8br;9Spv:3IRZtr1G:]U˧lvQ(EA Jմy ȯCͲFnrE*\WXmŷ#qy^X5/Ԧ-SZZO9GEK;[ O;eW]OIF_bxb=LD\^ժ9z*CײַeK%YAQv7KN=2ȍR~S$a:)^$ׅ@ -}D#5ܓba3,Jn#ek+0qCrWm9KU\vC;fQJZt/&w]|^o=ȟ%o 6-/^0!~ZFT|HNjɛ,]o'ZiˎO/ BOz- o]_yB<(* -e]rסvS/ɽ$W~]ժo't0A6:PPPt=n6|K.W: :,bj6FR8RAfe]R (PZf~ܶHMy\OWTWc9z8I2 -L"83Tף,[@=ItLt<,Klfo+K7Mۺ`i%,#Yq8,Q/+bjfYm.>oulKꋒoo::1òD #O̖Q?. {ܻuZZ #/.߬ǁZV'7ǓZ5L?Kq;=b&ǖTzuJV$ț" ql ),ݢ߿UE2,q]@ Dp'5Kߦ*[T{`V|U$f6`PbD`H1\_=V*#_FHEH 4oewG0%cHUIjP@ $Bpi1'^P}\~Ժ\v7RTXXH'?%eIX7I1A@Gqtb:mJLĢoǏojW]U_r<ϧŏ6Z@!|ro$W<;mOڛ#ZЄX66ZańG -Q;&+Y-S9R0[JOn1d- endstream endobj 21 0 obj <>stream -%Ⱦ{N?.ӸT+F^6L\3hEC S -^t 3~SN?Ȱ^EUyˤ1 -fs2Lɯ^5uzSs&A:& r6([<3!(eGn^ ~Yt/ٚz%C2ͳM5 W8xcL(#$ymپ]d\\$8os?j""[,fC5Zc-z4:1'3X8HpVnN"דH~fi_iƁΓGy⠈ӨP(M/C`-G|RdxR@vGZbӞ 7˹@o,A)rY<( -s_)2$b"ycOڶnZN>ZZDaL(Wtŋez߸+i䴌kJ$(=Sv-hx jyR!JI&uځF&dc0BB>0,TKjţ犎oz`C%f7 v;T,Ovƫd# -g(zYVJâVE^bW[2l$qV8>)ү);ϒGq&"2,&Jvs5M3(K)NoKjۦwĎS%v[$++ku1\!v*ZTbx!Uq˯Er#(:Wb%VIR8  _BՒ]f -7VNVP&T⎻pGxllSXۺنr4z׶ʹOYlV~(aU`14rHeaNQh9;JzmC3aٜeK9t;([nsrŰ:v$2! ^YqrL/%#R%݆/I.T0 {{Q)caajȟ ~!Ԅ!HtyP(qdW+؅GKAb"#GnGSfӧ5jmCGG~Qx+~GzGEK$UCdvYxۄEcYR䲡5$j~[yg|5or÷|Љλmܶ"b)^S3Y~ɖy!h`XEDU #EjԮ(]emC0+Ek0v"@As6-kU?lzjZu&'%r!^IʬT1JL`DkKfQZ"(_s}T:*R% TQ뙇߫e;iyPlʓID2}TS+=ǭUCZs_v:cuUʓ}REUǧe&͑Ħ+ǦV% _4Jw2DlP/CĈ/Vզ!sA/+V!џ#!I|ȡ \QSjjye)^Y<׍,wu<u4%hIR -ȚPŞ-ᱨUI+<=KBĿ9^_y#vrb1(EmIkdL lNn|bڬ^*KIWd23#%9bfpCĪ"5׌)Ms;-Sp\P,}sDu?ۦ6R_vQJ"TM6&8_גl@Ђ2Լp~b  נrS^4߂ZwI)dͱnlY%=6\XVlLz]Q#t8 "iUizz׺T=u!L\aP3Jb&9NjɉVĢ$ۥV JfAk Z]V!R"_J$.Vndb7Gқ=EmcbC%d#-eg)q0œ߈|NDcL$;2MzjӖoc[,W'G~]b!-b;vO#Ű/IAò -g] 1#it$"wGr:"wB2{j62 ')ZM$ei$qCe~IdiG s:qPVsfhULͯ4/rW^_n{mGǕ"C \P`FUߎEdS$jCeG -L}uE&7/: -П9}t嶟=Z<-(Hb#Ӳ14*)u3\$z]ݖnEiUs.v{#HZќY8=={x6eŮhM}Ӭ/eArEq1&9HV+VPYL%)hEOrb5R.SpzGbF5zMONRS ^Ff) b7yivS~]%D\J2C6딛M9px@0$*S-r8(0ݠ/,;<>űMдмT)Zj$7^RLB!޵W<{4Ԟm!`ĈϯXnZ@){gE/`"Hi TDVbb2 -(@"ţ/RxT0 BSX@(Kf[@{ʯPx(I(yDiYVpQY.M":2?IJ?̐!R$^GDp{_ok;W%*^J N%~`%2L`0Pb1H\9eR$kd'0Us䳉n&V zg8hW-/eaZLnZԪ#m2@N*їJ4Cŧ(aB^BuǧwPE>)ILj &1hX=㥸k~R'|cdw/GSܾtzKj)k_ moE= dxťB, gV'Ida MKpgѐE1R(c!XX!ɱKkb'?Sx&&ޫ'uP{EjԪgPtUb!}^wmi=YwcJ ?럖y_$E*JrU:z!4IhCXR3V{I_9>kدjmYαqTp9ƫ$#TCČNj۶'`TF|/G!^(2.Պc%]$a30%ӠD6H\*V$܂q xXճG!"eH*HEk?-iTSMOI iͬF.BP/)eMq ͊g'(Mcs#.d\T)1n]2;bQ:"8N8y`hDnRhbjo~xT@ϴRQdN7DR@pFG-a|}ŵ[ !4_ѫhE+&$*,~LVVUii@9I }~L` -,b^J, Ӟ,h(A\ց -"f$II]K/gn+l[lz%Ju4Q(!/F\,?U8e6^~,*'#O]C JMMq/Ŕ!~C0FljBBGj6^<!0 -kKfUWZg</)-} ahbNϾuR>:N`0:& -ncaF')'Ahgˎ_v dCC̊JdvOKv/G]Pw /);EL~}t|AeR_$`1KIW)ƓRsO -L`dE1,,!Ċµ@p0xJIls0b5Rq׫ģD$O['egJ&6)w`7=8HZLHD >D4)n[E -VDnR"YG*1\@4^^H@ )1_7mMK>{8`Hoc5l(=+:#% - Gۖ6gdA.*f_@ՎL YF k]0 -Dn+=H^*Mr˩+iM[@V)_4""%z"(=?!GwD59#EK8v]G>dž _ZZ:ש} -Ui'CK`2i~f.il`܀*`H!Y^ӛc;pHslk ?Ki -ӂE+5^'>b _Èz^,ӒuXD)=#W@YtŪ=_ ~1׉J?lZZU*0`9ƥzhu%%j HgFZJxHBċQhC,`XF?=SHX4bN`7 -BDTr -t5@@1̮?Brbc@@coP}_}r&rӧ>]`.}8':+BO lB 9sبZKӑ.Bim}ӈohMi.CUKDOqs5*Mpk'$Wav܌a1Opɮ1& -ӤWg's5Mvq܍y0Nz9d.8'[dW4mL܄aҫ3On\1&:I1#&g BV"h\&8§Y;3TG1JbHp0~g+=e80nL8A*_ߛ3P]h#&:dzwEU L:[N;A)J5Y@\9U%,NC D.#`C! zU$hIi+:U5:u0Aiϴ,FZa`aրT5!7PlQC^!<JH VT08I D!M13{r@rrֱ$^106%3f4czdfH?*r EUՁyȤo0¡3S}ROkPKP&ܯӟ2ꄹ嵽oԾ2\fQP()]ez!qdn<a`Y|&~# O v6D}Al]6HJ`HMwTx,ǕE GN:b4Ea-[AVCEKժ LgL!}'Ȃ]T#: G8"{=NHt:;.9Вn{@Y.r@M3Ep#cfY1O$( Vgs'x݅@iTB5 -Hq2vCH~#~r_S_e^YtO5Rs\u5m0rICn*6Hv=Jҵ_QAm1<e.J62atV9<<wdc" >.c&ێsL9’i - gώ,&R ݨvh>:bR:|;D ,8;Akll,RC_ь`cHwMs YdücDxX$(x:X&6JˍzV.F) j+MtXlHzmOOn¤R -[`ROu@FxC-/3ۡi"f5 lP`Pq"W\ W;.Z^g#S=ƪ ]?$_G/u>@>j`> f[y鞄,EĀн-\H!RRxOxD d/W` OcVlbxD,];EyV4(]"{ŁHx]>aފf &>nN0I֊LdžbFh#흆@J?d;cD31^!UU -rOS:91g@߯|SGɔgn,'"UgH8Ҳ[%!miC8s",ъ4\Z6xM=G4ޝ3FLkr8hF;š?jH<єyR5_Q/&VZJo `$ 0v2#8RQ a\[2;tzHeg"C[&Q҂Pp(nDe5dhM#K$ i/I*$cI*2-W.Y6>k ê(>%JϸIum# c:K*tQRkLOZc|e?glw -$hڈ"vK"UgPXfڸ?T٨s˔I;[7j@⌁|,D;y1;Ǔpxt`)~P;*'k*_G 1D rs?AO!0d/yu5G##dmj{Z6u%ʗ;6;rk._I[cFmO7dwAB4/GH\(lPD;"V@R!3疒KB@y4Y%\@aY7^tu $;li -e}tفPG%d7MMs3D*[@6Z&K9 F۽5߷qx J''q<ޗ[ęLQwv}!ҍT.]X{@:Kp\_R7+f#/S-wz8">W؅Y \ aMSttr"H1}qBKAR82 LysSvnhw:C#E4pX­+T|(I|H6$:I^6wdeg F+,_=@fdO0)X' 5zm~:0g"*LSEn*AkC*D`N-FNGJFäN /yՄ,§Y]J)=KUJuls!'ony߯EP dćQHW۬`>%hs*FÉÄbfV1D1:X~˔ÉtֻQna8,O \fɣ#+ Zzgz-Wc@0)Z\9*n"O!#5c -'~TK_L<%q O.ޤaJr<d)XQ~FQVx{]f̥,=!PCqceǷ/9Zgja|(y'S_9"̞azYJ&IT~4cu㧊J%} - -'4>ߏkwI`[>X&\;uJwT;L_ mٚyTnGGUV;'Z -3:]7 G;f e*D5|tme~ nL(W;N4׬wxcwb[0XOOۇǤ7&y*/ -/28@JQk..(kz8hTEL']n9ŖY dL -?ԜyB(߂WC Ē\{OB,+py 0qhjcA믥ONOW*Z0OhAJKh:ivʿtpq -!jL j}jT?^E^`@bbׂR7A\VZ-h=FC /%LY*'~q:&/Bݕ8B%xKC9l]1dF@@B4 ᚇ@wq陖;+0 9rR1s?"q N6/h(  WJ5Prk2^(XרxJp<І&ġ/pqIteYtmԠ.$u A7hl iK^7M/1/*4`BR -+UUO)~&l_IZYOOUvK` 9x*e0:IzwY :QBAL/b\[<4')D}uԗj'_ad&A9 -sRպpQ8I<K[X8Y3 -CDov_uWP͏*_l3Aٛ65Ifq@r F`=t䁽X54 -zJ$u&քLrJ3.n zīx.ѮEw&9k+||N~!+(" ,v/G*PKnW(9hG* ~87Z>8ӤI I͗7(?S8s0rD3Am fG@0~V> MuǤ nZg]m nkTm+ 8ogꉻǏ S-:4h;h=mvc֛[eai:3=jmL6({2GL aKub} =M:E+f4oe&HHa&:!"65V}2(נBW꼹YbPJRA(v8b11y,+>KmaI-ˆfU{H1aO|gHAZm ܥ_.˳fj2Yj4,eGɨ_-o6φz~^h{,}s,bM̂%Y&v}>vwD46ȀvxbPHfe1?2+癅~UdD8H2nSL%;&w A<8^!݊p"8XG8F,C[a\rQ2fSmD DN@7bCxYo:|)T2I's%)j d$O YLjgE숎sPؐgٽÂ\mq1nb(զɉp% /o>PbYjSrp&.һQM8׳ hx j97uAOɋbhW5^/Jk >Q%=B33iiƭ+54.̾{ܯJy|K7U/6_ 2$% -ȋ*xCai DŽH4jxhLhh$=N#\@yQ"ENBG%AG@c"@K]03B fqa_C PDS՞CJR `a͙5L,.' E/E^_yBZ7[O)l s8WX+JS|ԅXqgF(נ-9bcѵ@M$'_7 ~1!{r'f쉬 5Ϯ{v'8,{;Ū7tLM9J˷f.(ȩdԌIrA굫0.݈A&݋dS[DuI{~xt)tjf" evxP>jx?P,Aȅ#!i"24MX F(+n=oBJSg  -֥n BE>IDNA"!g+ 2=]\=lc)qXW9!`2^Yxe[M5eb0XOZtjO0_p =uÍ6/1JѶ)[q[1f"izZTQB \g 7qdW$2?k; qU"4#`iNjEim?~zqo}t:L<G<.2@@Ĩqocx4O{m}E4q -W)<{m[E4x,{\P!sˤO:U'@>+)9s'T?U` @;i8 \ "S$I z*Vrӧf/z z\0}0_W -3K%8_{x~tNDP*!Wɞc9#t;mXԴBxMo6K{Cӿű"/\  -9qZZPS)=ElM@U p Cx>}!i ~6bi8TH- (l̾^_T2cb6a1328-0352-49ce-a55a-1fbd0c11f83c836559b-c26e-4499-af1e-ad3f74750e74324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulence;childrenbaseFrequency(0.02attribute; ,numOctaves2result(turstitchTilnoS,feCompositinSourceGraphicinopeinwidth100%objecthxxyyidAI__1id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-20000z-5xy1ystyll-color:whsurfacespecOusConstant(Exponek0k1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.adilanbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(77spli(1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 5PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre1000112%##h -a4TP aa `b@! ߭0(‹Cn]`Xv/2%I1!= %z"0''WwYN5St/DftXtH^Mx v(v#-H42k粒oEI1^ߌ8VξN-Kn}llytm7xȎ0;:#^-V&tRf&tvބ4ueaMHB"!"^l/&w24IpwYϫz6Zol<]6.BAˌcEN -p=ҮGH݊@8%>R >"a3ɽV.,B681щ^0"ƃӖzYiO\A_CqnYƵh)laEӂP: y,+,X"ŕ*z,Fo^FlGFIОvRf8w*%%<жg|,^m>bB:CsR/&UA$\M$`,;wsg^G!ჺ4S2 $世'vXH/bZ)\"'HERuH0Ϩ=A4h\05b+*''1 0qX̉"Y&Hr"ID383jƳ4`G~\7{{c+^:kA{%gR&M )(h##|ej.eywKN (mK tn -@C= p2dq? eݑؠabP eE'| 9~k^2@ߚV? -AO-@"/S.15`b()+O*'Sx)^SH'/M;`$`{nQv jm2+ЬYXˆu_4l)Kl`0C)'7<"UZp #5#, k|qÑ8@ Q~R1?. Մ)âYo5bD9xtsʑ`"+%VC{%E5.T3Qb:*Ց?bDնz\1>!C $Kvy^H;DT' -2HZAOYq88#!rNIqe9k 7͈eӈA pAzLrMFnr|rTB,#c ߟ6_8 Vt'ϐfHu;/sKJ(T|zHb 3e[-|=rߒ9h#3>1e6ecG*x#ld? qíN|T<~RYfVGt:A*nx;eL9o Dӎ8~n8:#Bkӄt3x'AՌRniW25#XXu>}viq#H~~}0n.>{Q} NGrz}۟}0^?Ƒ|VNKOr[<TE+}E+'=* <¼wf_'nlR?rz`H.*}?rwG8GG> C@o5=¦﫻Ɵ]u:DH ڃ -&~ nxP -(Pp&$8PBޠdbBC1!"`0AXaP!$( -T< -$. @a -(Ph@BUX~Ȭ@0l H@TYK%fH%muYC%p80%@^%xuf5œŢ63R'ooQ6h@nhǶhXY#@ //֚X"b,W@R1AQh4QB &HHd`D;I5XVU&(RjD"pF<7Vj} N~) Cm:GQ #]ZkQ6KФ8YGq% c-/JvTG972$YE3v(496`bB~7gM9O\{v5՝3o_z^SQ(F1Q(FR -kEq+WxEbv(Fqӄ(Jr<츰((m$l\`qdQ4DGq@1q=ݣ(xQ%-6Iǁa1}Ey ɷU1"Se%%FJGkqn"} nse޹z3-SemR{TֶUrx%?Bd+ZM?@:w:+#d99DV*ng8<=¦-ə6-8UvڻNmڈGJq0Q ͯb99}Pݺcn3 ȨlX"/nW7d2X;>yFa88p9##=K7ӹ1 J=җC' y\^!yŅ \،"8 S>M'k&ki{h݇mutG%|= v m{-xifV7VӻeL]˴[Vj[ Qn__S6.Mb   ,H "P$!$  @fSaےN<ٹF*lc6cWwtuN`g6qVΔ&vd.^fҋ1酗NtWx#H+7K +}oyɈNv\u<[#!؜[GvtňķLy-?ؔRҋi#Q[:I2=;gͳbתh72u/g=u9)2ƷsGgBcVPkifت-{KmƎkk/_#mj+ygt{b[Ef{VI~FLkC*72!o|?I3j\Q4MzEįբ<1f$ 01>emtيT|I;%Κў';4٩Vtޙ_~,@ @!`Aa.x`D 9;aM1Mί /7nO0{` `0Œ$܁R!%6^jn~UbU>Fҏ -HR-hpl`?zk {\uLgdn#Re0Civ7j`  -. P ! 4L`B5„ fNV^R+$$Tx@ `+/=fFB!Bw7Dk|j~}J5lc;^DFqwbr q;`muwUCuRMR~M -򿻻{boUj v˫Zc31󙙙wLCDEu鯧SQOU2)3-󙹔TOzy˻"e;5?CSPiihfiiffffhfffhffffifififvwmv}ݵZwǜEڞ5"5 &";bfyMTTBSZ;f]m1Zq paKm m7ĴЗuy\g34۬۝ۑUY2լBCB#*-,n0O L3>O[DdұSo*2"TgJuۇo%YVFL9LTh4sh$#X*fB|]'@eg) $bXǠ5cX#Ww!I!񩌨dI QV0<H:޷cX>+(&&T Hg/5b 떐?. `c/-a)ʶ 8 %ەfTvel"F۾j; "d3Vt)՛j3L?>M `&c~HfdyEe2+kSZ(dG*2Jz w+>;u4Gf?/$k4@{ Ŭ;x =&`TC$I's mhS=HT®Vo_|6ݴZo=q3B0@ı]F.D6UrN4q,5u } „i^*X%4O -[ĪL2B:S o2U֦[~BP!vK5onUbIe~9+ʙi)i%b\80U cga jJ)fUJ(^Rm@HAPȮOEUT/VB5wt~$MD@S<Jm=L/ o [!0ApfD44 jGS _s[G'R\9T*ݟi}\>o)]PFzBi fzou3!{uN6ڹTC_FC48@UWPO ƗhhƣU -mP^hA` ZkznMȺ ] -jq&p]MPqCNxQhnJ!W2B*͊/9/JR - &pQ lAWQ -xq[]Qp -%;k$yiX-a,F#IKpϛ% @{T \ǸI&`4sDTӲD ƠB~89C ' 5QyNawrRuRI R߲7o;b{{HL;DTVmvMRh t-q.8 C{|ƽU#Ms1.m1z5+cm1^wBf1QaX)_8%BqE˱s+DZF@l&,w J( 1E(̗{0x5ր}>+27qh@N'çSim|mW6%"H<(iRj?~Y2U)؆KxL܇2)Z_a~l֏bPaLZ:Wq8-So.Ft58B6}zbgvfI9oI*QM;4miGq] -KKi]ZNf|cbI*o= ehwǕy\`k|%:M6 juh8;}ZI-̫j$2"[]n_Q82Bi<"Ls݄ƽsy 3qV,࣌7we|DZmf2lTAa{(do}<$l3\8xp# -1J9uTE=<>!gZxŮҥ! ZHݢs5ݓȋ/+~C<οܐԑ#~}ڠmyo:̃RA-Vq_def &e+C9cPQ1D:`_ /YϏIb`XqFVǴ"@b5cDҌs[)@B\Ȏi%r'v:)G=Y_`)XCKVʟsE`P<Wtٮ05sݞ.*+ڂvfpE+za T. -ReKĨ^ oVg@,CO4\Jg Q -HmaA\,t$kayU kH1juс'+<]wuUh1Y=ݼƂ9ͫ#;*jwlc#\&3S -vi\&M+ѯ@G\AfȼZbCWpa5- -]N'v{JsN&oWbw 9QM4󗠵tlE7LkE SHzyW ;@(|b3; -.,ٲ[_CkJD\8\a{BD|-[O2Fm%B3ӕ.?V2$rƩi0J>90k? R+ϻ($F?6` |?8/rkvQF:eNsZ{W+ni\P *q!T`(՛|DhEm{ bH%0x%P%@0Atn}$vʱ1d t,/[Laӟs*K`Ei+u%, #`KXKm%mxa2,N.v#(OCQt,a& HШvK2 -H2vtAxL !(p2& o j.4AE(`#GӔI4!\/P_`ӷYxYl^̕@ʆ -χ@}dNU æ̥-OWu@"[k:_K.#Cִ[\rnzVӍ^_#n(vpףUܪJ}3\ƍ<R 00:5{LjW :/1,5q+R)"5/YV "+Swd$ɀ{\'=|!)CP0J۝avGE9+ȷU"B{$$"z#`+X4ثGzQp 8;\t*]ښYp,`l3+ƕ >p#6hn-=ƍTS֧9?4z RoЊ/dװ'I "ȫʒ$FbGlPR|rzQYˬSɧ{Jl_T#Qᮭ D Wsgh|WumđP&KmN 9<,g )}蠄gs w*h.ZBLOy:gc~0ᦳAVP/r-+H%;gdΠ\t}& DZq-c*iEtqoCƝxBWgTMU>?DS0ɧb -qҙj14~cs r7Ean&݀W2dc܇ަ3aQbKrئ ) 'D@C!da-%G珬Es׆Bi**EO -&lkU!Y\sv=īhcR(V)!Zkd0cMmxM6 .[eLA׾D},kn˶!20vv3pxMg)0H̩~e:+3w]b(M:sa˟kJo=gxSv g j0i2dg_xH  ^1;J )[ѿ0ٳJwvqض)@hzY4{˞_r ufRf;j+L$o Uziy-QybSR" -՟4ybh1LFu#"r_9!7b6ٷAGByW, Ɋ2=]Wfl@3mB eY'}47y{ {ѕ/"&ۣZ jbmq#OJRj X/ 7l$P J'w"2)NwH9* @/# 0xNdR;4Z]8y"peEμ]/VuJ]*` -ؖ9:ŕz!ĵ:)GtTkO9_ϊ %p3%M(x>L d6Y8=p/;smR ;8nrgmֈ"r.JA4 -,aOG|VC|b3 W]qaOu V<v[9  -k*µݳmgbXErHӀ[hp֚Vw7 n^U-I8tcP-+pЂ g^ӗOrɭ.ge6n5J?O,BO\ -*o0|]=98]Hڻ'I^'&Ul*qa2]9 M@3JT$`L}DY'7(#`:kou&[\ ONUtMOI:"xc9gKEME)ςc礼Ks(ԄqZ^wreؿpOӱb}S/t.i *q jsb\^em-M*+)s)1`!Іxs~CDHC c.5 -<v#Pǭ{qJCSD"KaP8c?"1I(t"s$"o -`G 7) :%QK Da|Y+{$.$Wp7~9ji9r-Q⺷.ő(UpGYʕM:I"v ]0Ca{DYW"a0[s3 c]c<#f87kaṀ o,هlQ aewqF`K`Eb ڧQ96@,8:<~XCC-6%ԗL8ک6w"V]/Mio$dŹLĔQk2SR3'Χ8.zFfm܌ƙ*=rMahzծ L[դmT;;p¢7l6p8C-?g.=hkNXt޷K|L 4+2]bk%mc*;|TlDbЯn"qi]V*QjP>Z Ka}+x'pn]^#0 +=%·.D3zC|ׁ]28>_Xq\ZҼdL9.u.;H\8uwsIj=OˈYaI@ qt* ^2iHGׯN'}Ow6(@YNQ˵a]*Lyr Mf$T'ɉ1ٸPy@ eGnx@2v' xR[&_חS5`qD3ZPgH}1jBlr -AxLVDO)}2O>t&/ &c3IfLIQqZkeg(C.~qvhQ -\QEFحx7CZmpE.:+IJWiswBqAnI @gR mh,-Q&IF y5dP&p“` cWj!MisQX"$6t7QZ6ުSwH{]/i:. IfYR'O1@96hoFdڥv #+b昹|Hػ?. <+fړ5 j4` KۓW"*)bl=*N|DS('%(v^0"|՘Ml Y+8Q\J#{y^UXXуd Y #byߗp`pM5-Y&aI)2:$CEјvp],ʢ2N;O&q -G)'rbm-7l!b2f*4zqTc0?ãF Mlۻ (QI9elw(|3Ǣgw3Xk7-_%ax싱3#m۴($%4$,$[BdQ)d!'D~Y"pT6;>w5#z.F'>} :?'U;'1w}GQ\?I=lH`Hul$ "P"`n*d< 7 LX}wAdz^BX5h%s-E!Ӿ1-tXL^6d(.+beuMv>i3p~~Bw  . T'䎃rdHt#[٦׽MVQry`mb5Sڃ̻&ojE&@;gyEi}{R]J 1'U>L5AU@(NVД jbe~7O@Un,~$#DڧF$CxeSRbeyw*G8k&ѥU1cX1-pڢ`߾YvNbwuWbG,1+0rѽ́2y$dBy;\|j F&o6s wV{ -?@Q3];sm/+C[(@ƅF6؏=,KvMM9k=XwSmHU 128BGRNӖ5%eab5`~ -Չu{-`%HF'4}&bPF& -y i-)uI!>ӊQĹۑ< Nr,Kz׭5tSm"HZx|[N%V0KXU]!rDYHU*5*3Bz} *,28LuAܧ'r31>F >Ag3:&&0"88zyz_3--,Z&Yb}-rmx~@D6y0i6nDU1ujJ Y2"Sx#f=brfzˉsjy%{;(7G5KT.i)p" -xrgaLyL h t 4B׀Y,iȹS$1H ;#"ȟ,s C\pygx#ٿV -v G(p %fCfIHkKb=;Lw'P ^ ?R#eAK!&B s&Cs+7]}ZF,-% /-PADȜشBM.е4P;Wh$*Lf-ޠd笔ylTjJ,"W!|?PJv<‰O|au~e2~HD7r}Xn?Ei3 Pq GѧƒuOҳaD2wID}9x5A-bSm4@ Tt?#<ϰ^c(C|rā}lR疁#e\୆HsM/F`S-(t/ޖJD~!ӻ& s?s kCݤ'[7;㱀dpUMVoślt>W>V+(,^D$]iT ~%W ' e{+3G E&;Q&3 C @Racd%;^Ss^w! -NP'6Œ&.zZ4& -D͡aEK -A/Xa*#V,dnnWB.uD/t,nA8KW9@!x˝BB6׿4U$S]#4(L-s X=Ur_%UeAR7 2X3̧tx2fZcAi[{Z$4oŃW ^=Ru`vy_*"vJXWbgWy0F<;ϦQ Wʥ ysH :4n *RRIJ~ k*iI~?C2 &c-_| Va+Z(k3"L:E3ʘ _:$2'>~1PM:@;84V9=2)]x1jsx%A `AN &Į zYϊ NaJɹIeL -Y dԉ>5PeR0dR>5T-eV1i4LisZ{ QZ &^_ b)L߳롺⨌S 7fKhguuě!1p^S@8Eu@j\\;o2{d(nsr}M7%12@-Jm>ٶ> -a5%`z^\!B<~CL^+"U3I 623Za0XZ %!4͝5f XقZwte-=7Xuܯ\? -=Ҭ1 ޯ6jҊ,mlocb}hn`7rZDA%J 9]c,S_nLޔ-J&m,ojYPjYta-FI#ۖ̅kBߐF-a _*QoUT@ -r9c" K&+#iXOtA3',V[JE7ÉDAMI-iq q cָ@'ZocFCĎuDM=C[J`NrSl5amC/r*_y wғt.{=œ~KG~Yh8.6;cXDAh`m*( -1b - V.mvJ\U;}cq\{t!k9^Omp(E2%ET)|'80g?I=L5@/sX-j.1"e" N#ġꐁоBR91RIF1F,ʈd${~vZ9unQە SVm^*MƊ[Iq j%X. R!ںuq).ٔ (MQq|hRv}]VHuIZ Sp$а#%8XaZ:\n%kG*q\UT| O?ugXImpj|u?&4Wz -lVʇ|d]|o;X,bKVI7?2T W2q_Y"eVY >1.83(tƪe8,Uf.6mHn?S=XfP0ay|.}Xew9!AVmd Al ߞTp6:1udhn.Ƈ"x' -hJD)kQJLIk ֏PF:KÜYrqO-$?2ɿB]$3,,xbAa 9'B-#yGnl1$rjGFtX#)>栶9ʽ$gHOI'_)jAUɚC2 @bRI3r/f\KoEKq1`(w!K狄g%ZlD{Зg׫'J[lz<5cDux%6 -\Ym_V4"gdaƑCK =kMjI`f:O ,0182_u8pvb8dǣ0v%_c3P.XDXb{Z2%Q8 &n ds2b[Y -ۃrqB|-#Ka!@e jgꏞUZdr7zqڮdV0gG fjfՂrgrUqy -N %G~bv8P^IeQ%r|Cr,Im]B%UAK~yL,1!gyhܑ<\h;_OKG='ڊ?SyP}6 -+SZ.=i@K r MC'h@CQ@׭7 ¯(X=fTH(NB6 ?vK͠EΧ eu+ԀŴ.BR?W\h(|diYCj=@$x[e(zoIauڈ>lmekԞ쑓mG -Ӂ1 vFϣ0mf0H#Jr Ip -Xl˖blGV܆J#FPVH&=U!Pr%d0bŰ上 -dӉϖګFD; *+榋{)$> b[6x!;y{@Ȕu10A3RP@-Moms1E3emQ1BgBpK{0I7? -QYf3a8%e šZ^ĚCo.`Qߣ*IV -)vNo!("{NK= ђ^-nSa&c#l"pdj!gH.郮U7E5\%NuM@I0iT0AX?A Jd1%FP݄™[Ƥu5pʿk .1Ę1  woW#ft.%n֟||CV(dU-d VI0Xq =?9߇FR>.r7n<)t4_:sOlM8H[lzapkp@u<‰[1x 1) 6:]9đK6<(/hlq7P%Y|F a$2 ax ڇpӖ)1,~ i@"A5AO"{fj{ -4 32cjIAkܙt}S9O%8CLəz;AŽǂ -C AAВ|g -EuMu4M`2e2e~N[ØgoМʗgV bQ~n|8CX6[?lk8?ܖ&SSDnx2FsO\d}jE~R("G+ W^6kvWPuz\{4)+mެ;D@U/\]=~材 -:>\ iq,U$[JZ!+zjcaH׭jԊl&7sH BeAW(F\LFMg9r>QBȺnRHeO_1z7Zld߱\#J3K,d/&AF+g`KNvb*-ģxixj7Z @HE -UO A%ҺLE"rKC_l фUC0"-u{&0^ƅ#ǁ `)n^BQYZs kp -)ٝofiC^EJ U͠绅K+{*KH2Tjdt4ܝ2o=@f2M -K"Xi%$eH#NsbgWwOIL+zjl."5j=n@dȏՁ(> cR~J - 0Ĕ~',J,08|g$!n8d ?ڬ,X N>\(F -onEA3 Z[HY< #9u X&Gf#*̅PBe&pYH$wzZ;=8<"q 1Ŀ)85YQ> EI|f]M}s}ũfS#8;* <$bz* E2YG 򢒴&fxУH;9l̯֋rZ`Xq Qgr&!/0Xn!JaITv pNV2\&Lv#DΈ@{ G0^7\cC\ يGlLz# Nad*, :^]pGc1`zYc|+wq6^ւuJlXG xԕ'hc0 SיV!ϰD !"~3l{X-wEp:گ2t|ZU^Ό -aKh W"Oоqo]]`T6_Hhߺ ؿH ,r3p4CRک 𾩐vq9u+^hn~1[j4 m`h)=*N1M@'UXLLDJ_n}++3rTl,2(4W Ј c:N tX4@@pGZ%^(6 Ec<c<"˩ ́?b'1mbZY+&"\grr5!='1aE%ո(M.] 8sΛv? -nE8U;{'hv':Uz5"wfe( \V SY: ˤI#joFNuiKRW঵-_U٭r+{r!tw@WjUaW=vǢȑlA}׮}* ]%CE)v -Z]0uhU}:xI(3cPk\a!̀+X0}X1T Ǜ7MӜ"U} CD9A#l]q{~ PM?HEwJd GÁmpxAR5t{-\]憔{H@5if/`r,lt~{9w,gP,|/D2y/@ڔĈF["7d>-Ú|5&20HQL/ӶT&tf) A}LyKPX;ZW$HBf+Hr}- : -RJ=Gv'npƶ~c7 HyET+-gs,ǟ{ow~%vT"6y|)B00ELE 1n'Uc (R1eELOoK+L8[\H5,i\!-U2TUR*$ D B!%7G47fP\ubj$N.pHf7p -\y@oDp. h4]ɻ ؕ1dwA+65M2/ M~,uPb=#bVf(:{~a/ -iu􇺉 v-,|E=^%)8<nd{ P@,s{Sבs%-CiIjS#ݜ$m<]#m,0b,0dtFBGZĨZ!ϭH_12a>cFA3ǣG&&]$Vf(,;RssBLSBM!MZ>Rhf ^G/+|vtkحA[ kc}j¶&:zbmbNi㿆e=4 <|[Pq4*WúՄb_a K̴J.$1GjRX)+RcMj`Ə ֖Jz V>ܡ%}1ui_{-+jp@$'9H-&^CTV{x͵Z2wdn,O8޽H,Od/hJE9Hyß"RYG\)v֭5s3ERygQZT?I~Ie&'vN4s଀ UBd鵜=pv,(O/Ɩ F$ fr:u%/tKi^ɼO|Ӫ;>ra% G v.XX-~1GH 5լ#J'Xy$a¦x) -=ɂtcu?CW1RJmYob;i5f(T*\'1tmՀ?_/T]( 1k˹E_F?(*,6۳Y fx)B9&J3_M,ޢ@\4$lgM֡Z ۮ9 Od7tR?ßpET) -%v"XfP @67%גDUЈn{oh܊d:_1OAS,%8 {ɂwae't4_V2Se)'E8Am+(qiU 2GW*=nYyO-]II RAS٢@>M,A܁j\C="ʉ-{rY;#d5Lgص#1T1"Բd~[Yϡ\>3[K=S+ q1\x^{V fx\8RNAXhvϚ4Q| -iA$$=Uȟ%0Jpԑ!en6?[AJ_i7O'llBi2E#m`izh9!d9X̌TITxp#|T7NhHkld誾l>`K_;Q4U7>$ah&a"|,w71*ِ.A)x/yEך!F/ڍSK LÖE_b\j0ikp(,@Cpouf6*A4q+iH))sYq፲ ̸;.BKu%0CG~v墅2N|c Qr4hJ7Fy7j/q(^4jn`Vp~ٕF)J&;F99WzLbBowr,l@$[:0fgʞX)Ԫu@ ˆb8&:97>89GENY 덛L]_Xrj(7`@FP^FY_vf[!^!RU+if3& -ےdV5ȼLQ#X@ȓL4@P<7)Jv7"d8T[6a=ZUCmK ҠSJSi`1So "3f-n +4 vf??gF S􄜂S/MlzEGu?c5>}p}$0]Ȩ ;pyć|]aM2*=䊕j}czhAxƇZI/I0wknn;[kqܯY%dr̻KjuNԉͫąf7/y&(3H'64N7@Ftp^}F {^==zJXlI81_m(Q{)^h7N_bz$%eM*Xup`Nk cқPwB_p$-ȪEWZd–$nXm|ƒS/NW+^BoVNk]JW/Y2 goAìH߸|;sgCY``[A-aNbhzK!# 5%!^JMYÆdh^A>eŔnIWxcr˝>6 C=F;yצ~̱<׆DfGp>#Y0ϳMF7$(M *ߌѬ2c-nKCU ^;U2=QW F\n"#9}F~v3(\y|8Tu=˻5U恸n_mC3АtncuSGQl͜rT*`лw|mAdDRԙCIH j mT^ޖ`}G`}$ʧ uSOE9&'I7qc3\wNQcI3=ϸƸgrRw3ƑWKۊ˝̺"Zcۏwɜ{|qE5|<Ǐ{>c9#כ$c9y5Ι|=-b{&{}]~ĜswE}Rȱ8k{ֻ;7Ix7xُu[ts85;#??|丏<3ߤ:{&Ǿ?]"~g5טIۏ$ɾsXG;\߹#}{w;'Iy]G:]ZcȪ8wIG3{ƛ]doqUϟgcH$Hj#k]'IcR{{ݷ\G(9wǟ|9;1q9IHcda2鰈Q?1#ΑNȪ8G>]S;w>3zS+mfBI]g13שVܙRD7%BUOѫvaʗU ^vP )th]{-z2gs9o^PE3u$;=)0^2,4voG21w.."9[\dEEjAVJHiv3}$ڪ^жz^KXi)[ kubPR֮|Euݫv\:ӓ}ۢZktY{Zժ.7N]euoZ:vm-}k Z\*{O=Ei枟N7L'5֋ [K@+]V-R[B8J\Rxjh T5żjZYHF1-^ -]:4@lzq/ [zS8ț^Օge:ߒJjüj7 }]P rpqp.wZgܢ.3=w -.;GB-j'V㮗LlT}ݴ6w]]":Qp ;Lv8gٻ*.w]_(Nډ:ZZC-4@jiQ{.su2m5uT1T=:e\-m%uvst}Ecgt2r!qc:=en:GIun/fGm;mm?3G;gj(f/j{[k9y9gg5L7d眩֤Σϣ]sf7c>oyn};qu"|1ߝ~s&Ο3c;N3MG?c=[wGR?b#&G9>&G1Lwb.Gbq';==n}k:Iݻ3qxfǺs?fo;?9yqܹ{q"C.ߍ{{#Ǯ?֣do?ǸoO~zyr}$︇ 9לHn'I?G˝csf'EHQϙ}=O~qw'9~ӜIIa}=9ڇYv̯5yccGg{vLͻEғ{ΙGǐw|-fvo?ܙdv8c8|ܣƢ&7;}}eއ)vO]aǠji@FQ$`/ 1 -N8@\#zƌk$ 3 ,mqS.:ފH5E b,D@(=cB+ESyWT@(L~*xDŽIP0QEʄ$ٛ`m<Gv;H4ī$ک$ - #HB4@ʁ0"ExC)K AD2D0!j3A t ȢR"b%|y ~"Vӄg-K"|,`R^NP -7T"7=\AyCL"nt)s)[sHdyNy -CBx& 1 -5LRq `b=E°2 -D,1`pIcq@@ibA I Ftø٠Аj LC[*)>n3؂klSZѴVXJ)(@N*PPBSP7` -%,V p&BA)(y$>y >7,` N*0TO5n+htl)ˈճ4O3=W)_0^^jynB -сOdրwi*pCy'>y)y)56!䱾Qna3W~obaCx,YċEP/)K^ x۟赬C{D鶽kD4EҘ[-K*艐[KGJ^?Pyy-P.aVœa)T@w+QVOD -7`9R6uZD|\bXFdXl& -̰Pn ܺ49e % -6pefm(Qo:c=㹀%MsHj\C[i Ѐ*6i -/dqJ x`0 -B"QHJ&=JJ'm -yyҙy絜 8y^`f iy 0&sTBVR" e~,7- u,&<"hF\" -͐xHY0lj]d"0C4dےJ'=;l-jb.9< I

n6f]RK ueɲb4ATbZ)`*8K拱$eOM{nѰIa[C_Wm5ukTzZ̄gY{~Z{ᨀ󞭵uQmFfm̵֏ Zɵ5][ZoK-ZP55uU;ߒfٳ5iZښشutPڬvv{Գfm:d۹ReN;u*ۭoBZw[kHZzbM_hW[کm1QܳC.VKnWCeX-}_:Tvh{vL ;E14E래\1ROrP:Esd_7t%:]uWKnu -mZ+Gl zsE fSm([K!(V\uo^l d@N@{ZYlYVDc'-[TUWVڋeEu2eZ,uїZZZlYokM@k -C_Zl]Xj]5Ke]j]X+ZȞj/es˲,nkM8iorO&m+۪-+e\˦o\]]]E6Utٝ. m.+3Dm\S+ۢjKdX ֢K|k06UauPUVw֞4qFo MU|.Vu*lnQ -Jjv-4Չ%@s}2WtٍT"mLdNm_áx ݋1!P:!}od. %7j*jweK,I(݆ u{e]1e_n3Zznעv$:=M;vu\5=َPrr]@oKy@Av)3_u)וZ<Գ5}OV̋[)Vc\,Q5腶hmYj-=Elu%M1 z27.D~UEMN C=o 譥-ۢV]E;o5mjߒ0 XYZPuP ROq-}kjyO$VKv|2Rb)酡 -:1/ p Pk뀴]5 +/ tR]Wzmf>qg+@~WENmji } LճKзCk֮Eaj:uPShQmE]J=N3^yZ9і® Pm}ߵ% @kO_T9m Y:sj۞<\ {sBQSiiAUvh U[gڞEi$c}/PwC48Tz#>w):X)3o7 -aѹ($ Ol -gacNF^V\eN $gf8`AeKʔ!Ṕ#4AD'1$Vpո4Jqٗ YHT@K`!*zE (0q[A&`*'։b -%/]Nf7XЍO$7ֆZq9!*шqci@`)CpUgAef#FN"\i|Gб [2d8K!uLJ6 7L h -J+r`3v@{ ?LA`A85C@;J͸IWC\,NF@0 q+N'bZ,pk/ -#/Za<[D8p6~Cftbb/m($Zl1E4ά䳊pʬʐ+/j/*% -,!#kmkYke.AsO01sYR= }"( -AtHV`'ۆVrHU [H<}\/(ăKK[H]#%n\ۣ2 =(Sm[xaEPQ#.qv>j$& ;Y -A+Є!ڏ18@XiFPbtq'&}qhl\E-l gZ}xaX':43m=O8X>NP` `SP3Z -K@7HcB”)P S&PxC?NŨO-J3?v@SRH 30T4Mn< -. ^6+p?.@ah }qt?)" :ďÐ D2­m?* -VwDͻ0w`ԇ8hOҶBj p 6hW.Ң0K}!;3@%6I)w0d0R}oI0@ ?a` VK Y.qQ&"# -ep <GK5h>N40˰uHI2hj%?j#L F' ӠyR$/P&[e!$wΨ(Ҷ,+ ^DgƄ,-2- 5Qx+SB".Mȡ1?}r1`EMF'gH58*0]+~8_E5EL ]ҐL:A(|h:fbq{fd[&X4mqVGeJ 3IРШt?n0^F>AE%mQ,$ <bcBB+K$cB 5u3K/A A_`2bf{}ɡ0;3 qdQ($`r \a匐 YY*I! px2 h$G%Ƚ|Rϫvv3KP:I]ʦM%ѥPxt:o(2$[`(qҢ¹Iz0>+*XCkVlpW5ZAN\j Rq0F+ Lh%MURE@=w)"Ydch`A)aKx@qEOvP4H[Y(bwlO`3M -\6͆ V""cG(ګŮ+!sY]->Fh[" HH%dL&9ak&mLbذ.:1~zB򃯚VOit2h=@CAɶ - -,\EA:xv2gq i@=` `:XV\YLQ!Uƫ.%Mq u("pAPRAAG 4NAd@썙B$ 1&E"92u8'$q(O9adhTX13F -$iQbvAHK!K 2) Y RId$d%Q|\E"U;*Ei؟2qdB y I ZP)a(A)[~ * ZHv2rwPKv"+IA)qDi9H$8c`1A܄dLYq)}2tH -W<Ux4F482"YB:&$d &tAʁWj4c* GJ~ھLda^ {^iBmyVd%G5y -?a8"843Sd3rB{`x\q8 D8hq8*1Iؓi9/'nnV,v_B_:#2Tzu`vzYK &"ZSRۧQ"M-fneSseR$;?Σ|y~jQ ,16^Ɯ]gD6GO`iGqnx:6PkUԜ:xĔ?^T@n$O!0l JH ?/ gZ!LZe#[dj\WbK`  F7*qTxAq$[8VII@D`A€8q` -p,AAEˀz b#>*N<~v!$G¢$E!/AAA#cj2kZan -g#>q_^ -P͹@|4RU@7 IBm ^hz hм^u`] m'[ JE8HzZjLE6RG ŝ:\0Z -3<٠"*AlK-l\xX0;,{ =y8\^%zN\JzH9̑E)חX>XMn!z bkn%Jl0Ƞ?.-tEYgM⁹DFLT+$DС`Å>A ܣ^4rz +tz HʕO|+7FE0uD3Ƅ'M_< Kad>.l#w bJ$4 -Q~CxaTCѨPP%z$69A86R$GwuRp 8a ' \}2Gh;Ұt8S90i.54q7sPa@`E*S^UE{ E:I k( 6|*D/G:&([%uzE<_2B !5O˂q 53Fus#h )hȁYuo[q`/zg4PHmF֭80@nct`˨0+U%< -A# -8j[PdѕkǤvq3-Bu$\.@~IDnMjt[ж$` N'-l1M@CL -63}HH@)@6i?gj - ǬC2,|AI`e $KO%9Ht; -]\`5u-Ah c&7aWn6Q@1 *-T0N#@-1Y9Krx57qd.+A+r̀G dY3@lM]k[Eˉar`b -.Bʐ%|DţeeTHBY$V$-+s$Hhf!v!lҴ%` [j2Bl*Sb4 -44Q&2eIF4AM։J=$|'=$w;I+zH>c#{8Y¡qlaawdshaskQHk(\$TRU41FUԑU"[g+ߌ!pY ~?RkNa ȉ!"盱n PCua>5reiL 3pbnr>Ve& YTHFO@3Ut/s2`px),th)d}=`hTx5Rʁ?:y^W:@52ѳEP -Q^kAȮjDRFadJQvJwH *B]yфaܢ ëS -Uh+HZ3 -g6 SENaKa)K60̮6bW([ kap3wEIq%&$$q!x~M͡q<8C(:C'K8CL nW? yM&ML20S8ƪ\,RWrpi>XŢWAZӒJP oiGqkÃƜ.Fj0CBg),J Q,d]w.<$Nf1` 0@Ŋ|$% DPb 1@A Q1b"Sy -3`#}MOeA&R>)e?ONl i(V|\ q[߫h0SUVtTT*߲2eʊG -2( -ʐefK`[ƮX(!F6O*Dz3Ŏ2 -#Na3T&B\ hpX hIeʒ:84qCSaox6Ƹq|FעMqQH6 f\ZRUDZT(4!$'yKe5Ψ" 4ЌHBLg^(ПqLU8Ml™WݺX -.ya((r6Vq7X]+ !bVQY' Sz-C^a vЌE5Kzo2i+^p6ŌpkTnKp~g /LT'1drADH hFcKb.bb똈iĄ1cr&@b.:QjF*۶QaE5C3'vF} ~ JczLҗaZ,U&Ӂʸʈ^v&,M*ТtJ[VF񀵬L Z@ 2VRR*T82 ,d&1B] J -. \iKfWv)A?gʔꤚPgb2¦xa3xaS@p8MpD7M)K4DIxDqw$aq -%ICFmW o,?dsh -N'K8 njpQH̏xeJph@4aXː%i|K4n! -+O'KlJAz2UEkܵoؖJځe^G`]+ǭFV f^HBLg^#sȄQ9fD C ȤbXP^,D66.P Rq1B)*< ^:?T1Reb7iKMhnZš ݬ*~K0rIdۮ0!|WRFOK[LHhm -:w z2h@OEƖtO~\Q7x@7ݨ83Ûy 'Egi@ZQt }t ОK]Ɠ<<=V+zPWQ $15ߩ0{muӿ,Sk{öiA?M\ -_ό. K̊TXk95[o`cOxqPq-I+R,$LR_:sl2 Kg{dD|_Ó [>.ùޘV0LwBsb~YswYJGe$)zY[B }KΧv-;9&%fqy+H+/8ÇvO"bAԵ%O}PDSc3Hxgs9/I#= SǕX#^gO-o⢈':ޤ4d^5k(œeeКe\"hV/B6=_9m?^:425}_`f XvSTyR@MH2¥Bj&̏ȝcR;&jE섢Ώڳ[$,,h*9 @,Nd`bT,Q#NH$r}HOW)URG}? WJR`1efhf<:nMuZ!`ZC3x-YF3XJt^0d+W| 2iP%Q*E0s|s"gSK | {~="\22ŽY})pQ^;*2ҭ!!LbJKxN1ĈY0SsSjM)}>ݢkf-4 PĬȵ\]!m$ޝnEc5F2/)Ƥ'=R]Xc2{!!ơ 0h_>R]?tr1-Q̚]gcڙF4tci"F@^37M˕u ҡΎTHBT2UsmkLOrCW%KWs\䋫_y6n8 kVe[։P3(Ӝ+u4b❤,y2N"LlQFJ,1o&x:BU6 F T:Y!A%LlHGwe{DIj!t==o.iy1]6xВ2gS$]BdJQ~T{dr& -<[B[OGjD'AƖ1w^YQi7Gxh: x4ꭞ':  8}-vWMsDc}(i=9 :ԶnU)xLCal@: UO K?rέMr -R,*K[c.ڃǬ́MpBޏqكe2!* -#/$ޓ#́|3+ -ҕ:ٞ]oXgʲ]Sp;wXa)ٕEZE9.oP%9XV557QSK8|rl7-"7ЈCu;M S|bnn? ߁cHu_ɸ1iKy+ϒ,ʸ017_G0Б>!愽RIo9pk7dE/֮]o5[ };BӔ3zG*=F܉y(s#\]bʂ_td"ԃI?2V15RjVn;>,2qC]vM64ӲV-o`>NkicǝVj:Ab q.8@['ag㴦Sc-]hX((6VH5{jZEb>}4ARMg*JJi L t~Wtwν5‘1@x]wR$~-Åḋr -t䤺aKp=/45{J*dj~!lTcU1Х'+Mj-BԵT@ZaH".=t99.YDLI-PV];só - tTT漦z>KH*_TfV g{`N.7$Kvt jkDBlٿc}4hi"F577 7z-Ω1z~LF97B؇^MɪD5(N]rak]$3АGDY w_$3~ -)bbj,]:ٖmHJEF-60Պ-JlA Fփ-%/Ru*abf,ʏ㠸\U+c"4^Y69%]t61}3<֘,"Ac0S -rߪ8ef ވhg"pDV(57_k6:r^J"uۿz06Dm%Y'd޲_@=Nw7 PKh;zSVwN YT߫؎KRzOw( zڈZzǻ) *DK;h_Μgƾ2c;+YFSB㢽osW6U'XzZCg<[jd  iqU&mO ĊX;0x2zK1qBZ ^ʦ!IkC[.;M&|8v[.ʡ ~6NRoD6hDeepS l%󜤆x RFb>R3vCdE6)xNu>t˕Ñ ;8|7ʣM)HYKZ{ĸ,5+K,Btn|ga1\awV -c9Tiž2dƾ6Ji|}v 翽 ,].G~cл?Vm8.F֠GEGCO~ݢpFP@)[$:xN֏5ڃEe/]V˔3fMo/ܕq Αk;3p%٣_Q/$F ̟$H~zwAŷwZ=@\+6.^ tɹ_a&Ļ2dnlX>+Ts}'Ykϔ0A,{Ҁő =-NSZPz&U:"mK_)t գ+VI(^9u*uYX&M[.†^JZAn\F{ &#֑rm)t,F*3%Oņ ~]n0 "XicQyE}sG26$o˙x@lgr*b5 \g/LP~rBp^512s SQHm$A6SaaUBbyS6g(qCtT)An>ť;(H!.Rv9~lI#6R:.8P/'hժŚxL=4AGV"ۄM<$ne5#ܛtH& 0 "Åd^/оb\nj CL[*+~NpsiռYE.?p+P3ݭgaJa,]TǹW@ *TeLUEJmRB2]k0c1Q32 -[amtYg wˬn JjE -V>&tn@@)"f!!*#Sgˌ{#eh3H}CWƭ$JD3RF2<ࠔVdu)ӳ?rKұ%I"I8 _BJK!0"NXHdܰa/(%p/DH )_ae;ry@:c3n!8|`SS8E GA%OS+=5*(Zl7-!T S@[@Aŭ0 u)6ժ* Qws#?TӶ.ȘL^S R:< T^JD/Ļce1_(#ˊ3SSp) -`@|iQf F?k9ۼ+)PހlEn 9w2D'уqF68U3|Hb dpMVJ,hʜt(Q -H ߧ:4S73-k췤5OL\AKy#\T<.}$(g50Y7(Ǻ9n1 -ԮIJA"b{זv]㬁M31js>YYDX+oFUWgrLezI:v2ʹgfO!j}@bom;@Ecs@4>9^&9 W_33BD떶t;t퟼GK(]ʄFoZq5S`-r];H6h]@A$'E>9) -C?˿+uȐ<+f=/eψkSjAҎ(Dո`IɝQ=[r h* >5(Bm-99EݔC#T+8,o<%XMӱ N֊ J5|˲>aVɹZx])7}Ǖ _PHD~-Zh,Mr`g*/ g8X0,.- FpF|(\=LEuٻ,,.Eoma>MìEaa?_}m"1>3{X̟ -+` UG%dX-QF]A: HR_92;HRgMywRQg2KVZ٥~Yf)]xjQM|a"Rɵ\·W&Ӧ\hwrP{s5xkuX8GWCëF(TT $6R5vD{% sA6?["ZBrjRG8:<"B<@(KV  {}шBh88S3fLXҾiwP1p ?$r-`ALN*0|wJg4y.eQ2=,ps5zqus5JMeP 3n -^yYhkv*B|]Jv$ۜ-JPL7B,&&o$o$~l:3%XWsB+՟Mzg6ug(y-BdXIQFV@ٙ >ugafn܏B@GTP5r0:W:\Oi4rG#[OP;*8P}1Kgi3ɻ1)c֪O|TJMȤl^~u+k \B똢' !t\[xLu㶎җ[=ED7^,qeZuOV\1_zPBwc "t 9R|O$+k65,Ɣ4c=e_zF'[]y1NiC7EGXs,&{(&' .?nދdL7jA%V*`VP[ -"ڂ Ӫ 5q;e8CRo/t7WRtq0iuvǭ˿l䪸P -$P๗C3uʰCph(:> 9-7vj,V0\ qKWi5dQY8HDTHe@Hk sQ"&"- t>6j^7 3J.^|zרry"Bi:?-u(T%;lv3=U)J%<2>߃QOY1p6 o&NaeL9ωzudG) %]yDOY%aȃ|M$#:9?}\u}{=v~rЖۣx+(aX^HO\)5U1c} ;j^7ޣI#.; -m$#jLLMln֡6FLu9Ch+f~T+ -0~u[9ʡmp:tY9)9bHۮ._I>b6WM:8>׊е2VVJ4CCBdډFJW;pZ&L%DpMޟ/)\G7 =L#ps;]Y=)ijh6خ"͂ -k`uS~+v&evyPw>w`U-aЮ)W#˃{Zg˺tSWReA_joY^-( -vYM= 1̀=<) -N5Xy'&z -}*{gD@ø/10T;خׯM/VY/\ϱ%n\"E,].K ybnr~fp*Z :/F _xW%PNCMrk$7.ZCct[^ \#"lu~& P0 -!ßܯ-* -ZuX*L ʇ*3L`59gP|X1 Rd X0ɒFnJ bTܸ%ho\t3$>:"E|/[\;Lw^ɭ8Vߋhk-m,X&om=?eNTbp7½+5z:KVEZ[dCv.yʄ#lokkɆ8e.g{\ )g CEV -+5AsFӚu+جP !=r Fa(;|q[4_O!PrWjlmyNL=tJ9o#^$ :MY)_tg!mJs#%ewMݒß!ߙof pRX5ɩd.*@ қx&0߂ pjW! kj١]jzP[I;ߠCcnrnbo%kXB.tH&r>ɚ ӯ9Dq3܄&h<ƀi(wIqH}7\7#W+hf) fZJ,ܝzCY%^/*́+rS{Sj1nm)T@5H VQt ҄b -EI@yh\}ª 6ISts$:6~dʄ+R.pK67DQϒ`- -i]W(_+`Op -OJD<|9099~hFAPӓ% G! S3W6q7hن!^Ad\M6JD0!M4Lj>ǝ'~arlB[3m2&{gYC翂 -L')R$^@ H~%-HU-2 j&_cm<"z EV9N<,7UId[+F!Yߋ/G6:f --cf0h7%2 *I\ЬɆt# ۰o.^dRg-y8惟 6'(q_3 Tlj HvG/Vmj!ލJ(^kx3rZi1C2T>o3:Ciy(pKZeN4ll*/E1g^uceFNWlbB?Wvퟠ2"kj{Drʅ2}rScmCPZ)]f? -XhoKQGtB -d;}9^x0v37>E瓇*Ǻ,I  -LN/}>4/6fsUp+1A#CUa@zI"V-$?17l0%>Ɩ>nLU]uK3W˰ -W܉FPyƊg[ G,vtiܝ{k0nz[+67$)a@i}C8:^geXqޣI=OmMۯ6v3UĀ&N%WdrR9!ExunXtc::+ '7sh,DN@>fAHѓS|^W endstream endobj 22 0 obj <>stream -M2L$e 3]~ѣ%GPtj gPl|r6AN̬bIa5B<# f~;j\;}P!&; @Ʀ7yu1b,ɰq#;@L D>w^!b: CErɠp‘jv1Gs\l!Sy -rYgʪ펑N=Cegjjz8+X;;~)D_ UcB HQ $,-8-e*4 $y<(r((C"H!RkbaV䗹DXj8IM$[G*8pDDfNX+f[ar͕IA\%N+J+nCP -60 bt4=l>{z/ !s EYQ\JZ֠D1D@eP)q_̂i/iw!958^k@.9%xG ohTBm~n"\;'m245oaCH.;G 7DQyH΄&7脉A&WCLbDoHGkcHQ/ Y3L*mv 'F,Ҍt¨k*׉iA@*v8Wl0R""U0y1H>VM$فBDw )L&ȥ)bQ bv#r#ӿZ 2$XX9"[p.TOWM]ԙЅ 8yƝcǁ)'@. PXUeY-bcJXBf -Z.\4ƹ=l&9Z^/k}O@ ޢv -3-u3Yn܆J74 .|Qȹg|jӆie -(vz(Ⱥ>%c8݂ bx[QR;+#Ps -@q}Cyc,/~7($E1E9t<t -R||\|P8T$(b!^tMΘI0&U D(i7a>cNV4A{\xQDp` F,YfFm gX` -XȠۈ+l='sDo|mG-bfA -JSӤ8.jࢾ6%%.Eϲg^AD1Xā/jE΢lY! T[D@k)H$+M $腂D 0 7ш[.Ӎ-4ᣥUQހf\99\h=$f3#B)u ˙=G4\wiʼnt?K+[l.hYЇmZbO8Y=2Wɐu^@@ \odFJH ؛q2jpyawlP -k;̆EᓫZqW$0/b'Zk EЅ#Y7~l}~e"p}<ٍv+D̼k[5ҍ6|m%6u =X&Z=0\hzzr;evh7?5{<'# TGL C5[`ֶ -kR"R2޾I?5ҌR%# ܡЋ'pRBXaJ3BbxpMibmʼnаRnhq(rx _~K -z}i9y$?^.1.GVc@xή\U+S0鼸|uC ( P]Եy$qQxV/7+cgRcj}qO.u^bO疉[Mpћ.B^B2b> -@2W}adM^0ze)O6M$Q{mߍc+g{@2(8ҲO67o=SS}ZJ]>[RsZ<-ͨG8Ly0cU5K'h)EҡPVqfA?4U@K\M%=4<~g4l`;k*DvG'ٮ]ytPDT(z! c^wm5-QneY}:)Nhٜjͺ; -kʑzjSBKi 5m:=qTgak' =Ep> yeG?AP+0z䆧Xr9n]>.S/w¹D齪!qy12M"kˬIP/B Eb᚞7"5pcXdIց29 -:~ܒidlU)l =ے'RKOq=gyǜI;ӑ#L~\zL%j?Ԇ=Be(4q*$$""!p@|4ֺMHHwA%Hq= RMEܼ8SjSr|5C*%NLoSHnd'] -~BPmuٌ2jafkhrRvS:%ԴSC$_>\P>ߋRn./Ò jU1_k$1cE4tNN2ƞ|J$AdwMWݩ٬R$s k "bNXз5 -4$)~N7$>3_Hk6]Sq ۦ -SsQ{!ElX`Z)f6Ogd!MIR[~2=(a6ϊ<$v',\7^ u]gBEcIs@ l(9|"PXDr|jG;u8#!g _"74%- Nk qeeegb33-X 5a0 <`dSARQ\xyc&_9Ͽ /qxDF-yy0ϳԮX?XcER3!RFsC i1S !$"ZKdBOԐb6ZFlz#`dQvݥ"&DBd~CB -¶ F2郕L3$ LuG s& &J۸|^n'!yVM>}@j*8Esf*2 FFt1^Q9ͽz )n9`ﴪ{Eeూ͋3jEt-mw:ŀˆu,k܉RD/o M!U1>Ɣ^W(٫xt(0 ^ܳy |\ݳ1GAz=Jqz>ux}zAqg7A<MED9] *Ms"/YEKF3˧'sBM% [U}kc7q V) r$Ӂ(y WGkr)&1&[-Am{M]Hm.L ](:r(%)O-h>Κ^ i - -$;>xg4pkbZ ô&Fya"fV~WE~onxp=ӑ%w*D!xGI8D RZ~rK> NEFaxΐJd - ^Iؿ1/&r!tl Q9L &wb^i(B)^eU/Zz'.Ia>΂Iqi1@Tw\%r[m$z̰gYoqR!HG \=ѐ7'AtpE8G^A|a)vf+ DEԀS"PXn6S7b׽ ,T{fh !yip4-*B(<7okDbymS cU 6Ϸ ĵ*" =(~l ;f$@O^ʋ5@o#dgJHUyuj;sߙq,ډA3ʛN͠*,.M%kbH_!ul17Za*Xcq޹-%Q_qpQV5 tv)l%eidCyз\lƅx -(4QS``;3m=dcϪHNOT sA'pb#HP٭:*mzYb#T1')Ĝ!aښt$\WnJDAi.[ΒX/sN$G@ڻHiP7KڃD1%JdT7ӊGDPLUdr +>>s.%r? :9`ff-a`%\j)+ڀ&LʵvGWT؆y AgN4a$3:H9E;(]H'>2mҳ*Ugkoǜ;Hf]mI3QQ#N<ŵ4"]m̙<}hPo +>xa Yt- - :XDr=#(dȱ]IΉnהņ9;195rOV)nްaiX?јy(Ș*HZ}>j@_ -x™ etw+WVeA!O-@Ff9Q4*IԌ\oE;ۖ ّ:Kyr (]t&k'ȈsLNUsÊHʈq6 A\l']g""uEB}-/<FI[~Q5Ff,Q07]YPͮGDFGUa4rxm։ PHX 42ChjQc;ꄁja )  &Bj3Bs#ric夑_5kra",Ȃhv&܏B"#P坶3t$&Nw^=3̻zhvCt;#EH"p~7UI#q̦b\#G`QY5:7_;Tbd{P'.T N<ϼ.4 M_`KYس1 2bh!ɍ$0z!S=9Mb] ^][8Nf\f৊vyЁVl28B|1L {@d7%~hm b7~i:?9p#f$ -JJEkpJ)!VY725/\ZDVvn/TҖC~bEܰ*jUxܠ5/:P(#\uK30jłfv(PGsanG&d ]qS%6\ڞp}͉+Rt7UEu0ͤۛŅRۇL@ٳCnPkDk4JX^Byˆ+ iܦE\ Zc]*mCf -Nhq x<Ot#8O0S\_}kNiO8N`of=ţ<4\&d;^(N!ǞϣUIP몍9xx%cw9lec`STaSeVpB^i,Ȣ Xn!n?yAϚչbIN)o4wh {P:ס['G8Ɯ]FJu#v{>ďby= 2A_^y̏<6wkUמO>s#~VLX:wXK@K1HdO -(4C2LfMr\(rꅼJ8Q3Զ B=?}h| /bA_d*jSGDpҧ$(QKw#] 23 vZvǹ]Gs\e>t{$4 .q U!6qpceύ->HOںV"6QC=`,@p(_š}V_2%2 Nw) -@[fpPX#H TbYa@w1|4ui310gQe bbqB V݀5[!d9+@UJFE2pW$[e[eh˶ aEyUc>8$q+CBa *B= I_0HIxW$Ȍ0"BHԂD^:O_!mhL[F^AaC l$Ӂ0[x+d ٲAao%5(XLr󐤀S - 5:x7/ -SfYiPx2T qZ[qe9a]mZU3 -b^tVqZ -q``m \K$ -ËV?M!lHQ .aimȀLf,PT_@+j @rSga3 D%j1|{}P|it -." 2ǃe<$"Ɖ裎CHd -R]Ad@|:25@Ϋx0NNN,>zPNăwqzbtF[P@TH 13 >ex0,0y)q -@@(H@=g -nVu(.ĝbUe& -6mhAtp_ģ@b(Q\-+ -H6]N30K'Y/SZ$>N% :kQ:CPC J0(CF ֧u0q>Og{Zi\<[=k ŕ:mwcQ3)5ݫ;YH3RVΓ9Ӹ=Y Oۗ/蜡b)#^2/ƦYH3vWsr2I9nd9ou路tEKD,<ZU)L>XXG+I*RUʴCT*j@*PqzuXJd`2\SWv]ݒw_N_zOYeQzOcڲXxŒi5 IH_'m -i 2ھfNm5N:ۖZs`"[Wy}k(}kx ) aAKsҧ%$ѧr'9JGٶmT. -]1*T*vT`Ybuˆ 5ӝ->w:^u#;oRk=e˦9V3ʥcUJc(㌱Wrw4)}t,)1՛i]#8Wn9g^q{ӟ=kUvӎ[ϟ=W)ǹ4*)ߥdD6̲+SQd >jN%f.vs ?.dی4Ge)0&' -.߲\ьkt'Veow(r)(y{ -/'.|,LA0c79LU[&˄\T%e\y@͕o&umNШgA!i})u-&.Me¯3zhpXĤ-?`n)J,gs*h#F']n ?ruU".GMt!{# =jNɳxnHP4J.AWHj!ʤaeH^ KeС<˶bwy|oISH,*3r8UaTSmm -d7aDWO'r?/̮Z5' GL u1ޥ@A0ИMv6`.W "$WLH#/W50 /X0k(U` r(&ʗ?V&=VZ d0Pâuc\qH$+g]\1b)=4Ub#SMQ(pIf wBE-ϼSaI[\C]V0xxC<.$\N5"*K C'0@N|jZ/jNXn'FlYl&7?P'+iB0N.{_PvɶŤV+BrXn+.'D~Kno~H9;$SbNt)5GMN|r]|/e$f~>'<oz{##4f w≺ ?P27lex~Z H󰚫&8S\R7Wwz,z/w'>i%$iz$Icހ3QW(QQfN,NhhsI93?ҪALFҡߎVˉֈלS "KɽTzqDnגwi*+`LVBh{;]1^mC3֘Sxxs'?c,;!q6WFZܐ@(2Ŷ?p[D!@rtMq3an1Ϩo 1(Yq؟=~F֠*Ȫw\nC#c8;Jk$J.EiHYvǕ&%w D޼[s/:`Z4Fe8xX&Nۙ7Z㎿|SoN>} Zq~xz+tm8g8scq7-;"u704ivp; -g@ǽ@w/يN 0ƀ5*\cず1D'dfsXZ78Ɛ12l2%ycddxPȼ<`|5,a -vW!0wGe+b|?֦Nj#->?0hAEֹPP,=uajL1D2⪪+$+n!H> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000049503 00000 n -0000000000 00000 f -0000049554 00000 n -0000000000 00000 f -0000055429 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000055502 00000 n -0000055742 00000 n -0000056910 00000 n -0000122498 00000 n -0000188086 00000 n -0000253674 00000 n -0000319262 00000 n -0000000000 00000 f -0000055129 00000 n -0000332866 00000 n -0000049966 00000 n -0000052088 00000 n -0000055316 00000 n -0000051945 00000 n -0000050826 00000 n -0000051384 00000 n -0000051432 00000 n -0000052123 00000 n -0000052481 00000 n -0000052236 00000 n -0000052361 00000 n -0000055200 00000 n -0000055231 00000 n -0000332891 00000 n -trailer <<21BCBC75D104475EBE283B1C3B81500A>]>> startxref 333084 %%EOF \ No newline at end of file diff --git a/misc/branding/circle.png b/misc/branding/circle.png deleted file mode 100644 index 117d614b..00000000 Binary files a/misc/branding/circle.png and /dev/null differ diff --git a/misc/branding/circle_outline.ai b/misc/branding/circle_outline.ai deleted file mode 100644 index a9bf6135..00000000 --- a/misc/branding/circle_outline.ai +++ /dev/null @@ -1,1744 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_circle_outline - - - 2021-03-19T18:07:37-07:00 - 2021-03-19T18:07:37-07:00 - 2021-03-19T18:07:37-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUNfanp9hH6l5cRwJ25sAT8h1P0YtWXPDGLmQGMah+ZuiwVWzilvGHRqemh+lvi/wCFw06n N27ij9IMvsH4+DH7v8zdclJFvFDbL2NC7fexp/wuGnWZe3cx+kCP2pPcebfMlxX1NRmFf99n0/8A iHHDTgz7R1Eucz8NvuQEl/fSmstxLIfFnZv1nC40s05cyT8VHFrbBxVERX17EaxXEsZ/yXYfqOLZ HNMciR8Uwt/NnmOCnp6hMaf78Pqf8T5YKcmHaOojymfjv96b2n5la3EQLiKG4XuaFG+9TT8MHC52 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 i8W12KuxV2KuxV2KuxV2KuxV2Kv/2Q== - - - - uuid:3a6dee49-682c-594e-bc58-eb9c3519b0f5 - xmp.did:371104d9-8238-4c31-a88c-798e88db31b6 - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:371104d9-8238-4c31-a88c-798e88db31b6 - 2021-03-18T19:49:20-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HVˎ8 +!) ,{cwspL-;hUnY»?QH4n~9|ߞ?QW~-_ DJ56[ͱnJ4|s*1y&H*EM0꿟x8ϟL˂80}e%67R(&RdQLVs9b=]YqVrTKN$n(rl0 -6FX5NbB^ ߷+oj̙FX#Q9l xͦ=aLb"X4& ƑĺTss.@J ayMQum-# Lq:rP0[ӹ^4SK2DTr Td+7ټ Iꝺ0nDxT_3 ջEnzt7ݟ -[l"{_/AaBϽE}`Ҵ6K"} ORx cXRʽF -掅c0CŋxW"Qn{{7b.3n1?*wl֛pa\M<(E8V؂hFP܋~f`C_sϣA\!2b1L!j}\Nxle88sWÅ;S}ei-"y\<#&̽mvBK-!=&8Ѻ|B*R"La-r4ߤVW"Tc᷷\1-i"VӒ\! bџoWW1^RVX|mɸc/PXP ~vXpy.0A~˜@bط#icxɏ'!BP^PEM=$>stream -8;WRq_3Mnl#Xg]+%B'Xn!%3Yd:MDfU/2JDOd:Nn>4^K*9%:=Y`IfFV6GDG!_J%3Gn -9rn*7`F=1]`(7SUX/1\YEgGP\MDlV@<&m;*/u!T&lr=;EVbA#ok5X\@_.!o]#O2)* -8j$IP'X($/a=::?8]@'3L1;:a,@\SpH-/4oLfsOgXr0B^BsL^tZhM\I-MjNO-V -b1)gmjp-0p_d/$5WBd8CW&RP/G7N&sMJ16]Oj"E)#1fT%d`Bg73>gaU(#SMar5_0] -ZImE/-jB?Jk;m1FWK`gV<`QI0$)7s,^+$0`fQBn7)tdQp9'I`MCSt]eIkV%M13G'\ -?q_md1se7`G<`IQkG].1"oinp)5I%!7mH\F -"#MF+Eg;@We'j7$[;,="gJI#Zk80EHo26I[4FRJ7m6&;F~> endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_circle_outline.ai) %%CreationDate: 3/19/21 6:07 PM %%Canvassize: 16383 %%BoundingBox: 9 -292 292 -9 %%HiResBoundingBox: 9.65074967987857 -291.42023087023 291.368805043308 -9.70217550679263 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -357 205 1.11720768853445 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/X --m* m{QΜ&" -NRj0A - uJIuy,>~aE%EZL.9QF&Fl=I БH1 (TaI0c#G 'č⅂BI٥q" [Z+/8xWRh%U((vK,J4jh)!lM0)Z3$MY2RHI\bLءQ@$ $I"1Ie{{b "%a+Uؖ"aG31J%@^g9-("zWų1M˫r`9@C3R,e#:dPk_ڼmɜVim롒^]:s]E7J2ۤ=U.VRv5MYjb]d*g$t&, QH F I)\(Z2 "x<򬤰r ǫx(eؠhYq)FՂg墴dg⒨D0:_Q DYʃJbQCN$%0qtH6#8CL\&H#D2I񩩑L}[$LݗDdJ;"DN,"ݲ)իz=lk;_FgkUvHt<2U{Ԓem -M+J2lM;Eó3]XqS+@I͢6L R1*bH!FC-WR`"D*H( r rB JrFIYD"ʺp^a4'Q W6FRgH`c1z(L21cy)4clGJy"*w5{NCxHk塲ۮPKzȦH!& lpZ*ա -6_f/C暕VIf{DUe"TLCxxrjHuUwRqxuv^+K!U.WMK5)!W)i+\CTM*8 d/.ʑ8Qeuz0-Hb% @'NL2'Eb$G$JŸnB0J$ &ԁ"Z )VHL\0T(0Œ%qHJ0 - -A/DM2)<1$IJP &2' #I 8FH DD"idOKJg4EECBcCθ|t!fKH#$+aBA)"HqM0") -T*VX)gq%8Bc!b@D0R:+-/1357<)/I9\a"$L0ĜP@A@,H"RɁ&%DCH  1K*>TP+=P/Qݗ{=TL@xp!AU4`@!A2{|;d~Xj[_"A 9ʜ -bUN4j($k[]^V2p1R J(AvFׅ F0pR$E4J!`,(+(G"d"Ij-5=EEMU]"hBiZ[\ݢ-#ty/n8S -+" -xQ()60 4Pca0Qw{(8HABRkk_EeqRHRJVV--VXaa!$WWW J'Y9O)y}zbl[&衆jbVښڙ,QI!uTQ--++Uˆ%}6BȠLRb!$H888~c=<Î:Q#a$baFaƍ5H 40")((ZhVXQ '^((( " AC L<Ł HРC.0N2ECh0ʡiW$3]\1IWݱ)"]4])K=W)-{Z٨)Ǩ?gXyٳٓj]vnڔwgJ,{:3:(XoZ=Q-Tn[1ϪQ׋>Hgꮪ+:jPb-`e"O67J2>O=]<ٻ5kSkҥ=Ej:EJ?W[?3wסg5hژbM(hc׽]D=GhrC"mҙ -옙4.I,^jlΜrm^IJYY.UsԓOʦdݼM&^I[Hkuֲ -l>jSOR5Ӗz2>v+)ܧjute hvu ^&fHz0"#^MYB瞓*nӓOQoz~wS%~7mEGǽ=_*yf׷֝]OD:<%λ6etphOU;5śMU5ݞDhgw!=[R|GxFZt{v\rs j|rNONI-\Oo1&)~x,)uFN]q/S?T|Z\=7JTSR*\\Kͪ:>%!Nţk驵!wJ'_qgG6qO ~j1 }$oX{-ЙY{&13 :uh3FFi2S:dRi. -}ӨRc߮v%JsZ;&ro\GcwxǾzVjw&sSf":s&o13Vd][froSfnO\nl]mY-d4+c{G݃ezjڭAMͳfZKV"4/Y3eYzҌ߭}ҩ3G2=6CLC3:4=cy3x^=Fsݺ5ߏ+MVl%yƊu-R<4h|xT3N]Bcy͵]\07}Vֱ];Z*1.ڝOj]Vkd5s[jZvn4zgʸXkM;4҃gf&=i蔚v]?iNkb"ӛכdiLNѼm]Xkpu=Nl˫Ǚ<׬c7.4wZnoL&;iY4ء=k4VV[zQ=L;y -pR̪e)̳9Ϣ}w0׶Nڞf7oXgXltڒ\沍\deK%BJvʬ~.äKYudaD` <8H`F3T])RgYN:֞fzmG^|xF}U"#쫾뢞#MT;;2E;4B3EC{AR}\-hZse{ekf"=E=-얅Dzw^_;lHlkmK}I_5S)DwοvnK_ަ婚׳NVW*Ft?D;w!+_ݩꇇB<´,:ίr}{uuVvcNWX+=qZ\P(x@ǷP:`C<.;Ԫc+G))-Q)ޫs;xNGΩUk'Ӷ=e?Q;wEhZ;^4LMZXtJzNt*՘K2rn^9vЖݴ'-I, o0kI2'2mV1iJ.ΑmZ`:^Ycک<<Ϭ^צc^;ɶ?c(֦j^!^U//(õy\ڃ"%m|O,L.^?gdFf3׫ic[իGΟ9_h3iowJE4ΩC}}F[/Jչ|RcVIeUIiw,z煉U6ګd#+úUݝN;U"N _Bu)׮"e?PJ?<έ#:K馞'5ֵwByJR[םuuJmtR}T{*CZxдVեU\BACC XP~q^d{='7-ly{Ky9יjZh~]{s4ܫ]ޮڸvbs5Ϩk\œK;JvE$\'坐WdϼwGDY#=zxʌ(Xyo/KvohЈ~r&etJ_tny;vppy\Uyvi=gD٧HWSeD koA[5hK߳#:0mϖS~nс:}ZfKD?UFUN4֫g-UN^ɷLq/ME--+lx4 Q^iu75,4O]KՌh0z>HwF#ߩ|Ǭa..~yj\ɽ>_wB_XvZ=hE"'"ZivzGOѵ0lLK=6bVeKTjF2 T@0 jn>lH2Cx$CaMZp?8t ר*0+Z _1; sF0rۍ e1aBb@h`P8NSCCcIV193ɉYš)s_[ }(3cw_]G0X2)[&I /x 4p'腒#eu_ 317~yrbtszW&**y/Fgm+,/1 z҇s,Q_-Ex_r :+ֈ/ DB1Ď%PKlӏZ7xҶ pjYZaT=i?5h?qgd /3&5MF=NN(SXO*Ԝ>4WUߞcbUB!2"Y߀`c\7c*9q hϒp`$f~m: w4%6ضHXx"(1Cho2Гm,A2+56]ij$ZXYmFϧM㉭҉ʋV2?%X7N/1@ތZmR'GqL\CuCDg_ؘ g~WPY R",>k?59Ś~1 -')@@ol#vERlbiF.흧D½x| [A/"kW86k)ttށ>q8S`f37B(Q+ANIYUtjPL5d*dc&wڅŀYņoXc,Ct2+7:ESxIۮOf_YZBj膑CgrCƝ(PRlwYyK0f>:8ߖi!s%4)99&CR^{6v _-hoԔ=/`B:ݥkl)##\Ϲ]aG7_w5 -@lLEwf^9#dfDQ<vVj%p;xAPe͒@2"!p)H1_"3+"dl y̿8.|܌⬫s׏++Oqs ];ޫ_d^8Sb7< -+"/6rj?Bh:c7h'Ï= 3Rđrn EP׉e:flЇ;8)P=8'5h^ |a#OHMdMEZߝv &pQ]QCJ̵ikH%ѥù=2ԐW+Oe,|dg cZ٨a%FJ;)956"Mryl&!]ת'3p8tsvc:()Lpj@ta:牕ڴ5hTL`op Ժ*%p(\.mW\&QϙLܡ́Byϙ$qY;u;8F{0T8>|&9P[qV*;6@C^ٹ%i rXmm-_9ٜz83QHy<\Z:r4kl̠js~[;m9 6g, mČ|Ad,aC寝A);fѭ&JḆ^Gq +9|; rQcVhMW}E'8BwrT"8W[N!U9a͆sp T[NZJdc1'3][Mwakj&x,D6eO9+é4Gd%E=0^BSeziv]eC8woT2[qaI b -]bTI(Հ)yD:!+J1q:vMBnpxIn+9R%esˁ!gfO + g3||Ra(>9XIgyr.75&FP RCyT |耜ۦ-=,O+"rf-Y)1-S{urW(rgaGcr@-ys4g.A -&53ˀ̋^t&j>F֜5I9.sk+i@U)k yIk_SjhnG=%{{nߏo|F&kk?l̘ؼ=6bxQ7klzX*+z,TiCgm[FLo^QjIi pt]X{f>=BY~OrI E]RCe]FY 2@LdS?!I>s}" .AרhB> <sL Imy|sN=_ |Iv>(YRt=ra)h3IW|J0|د"l`FV)lJQք-挱3nT`X{gEmim|k( bHo˽"P-WKv7: - hE>6"@]W}/P{IY6g5rٖWTxkR -h""@pLi620%akEމѐ]:<aUi~wQl#uATWþvu/+pR%TX˱ - Wܘt3!5DEP lteQA܍*Ix"&6Kc)@8J@[_ȃ'w!f' D`WVMmԝLdef0"& =0s!p͵cl%$N -:zPfGYkAybo\6o٨1?(bxnSDŽ\N,hͳn c f-3y:Բ)V٢>rshaJp640C6doIo-LTxͥe͊wHLiYԟT~RT)=VOHµP\? f 4u􂣄e¨2ተ> )IQsh{ U>OG| -TB2(4=bL}P0de,=Q{ӂ)y+vvoQ$(ݯnc6;A*7r!ڢʌrEHs([ QfոפQcc6T y,UZUF/*I&xz p=%W'R`]\/rtBŰ+5g"&HZZ|M6EsCFw8g eʒ'Q1->ϠBۘ3d"zѷk ]fލ~aQ%BMq Ԡ00رy5U&( 7=xq^V -5(0khB$ޚ ]o!歽) Rnr{V-9Y7W ^ꅑݛSFY#T$VToF.AJ~+< 5;a2ٳ,6BmIQbxdp\ ya|k`>P^ɑC"M7ECtӆ}dݧJ{W}W2X"Bm8IM$I -qn"5iz1_SI0?L7#,Ĵe};#|k-ws^x@L70AFT-ѣi֎f'ZB hҠhdJ5#PQHPF>BXgl)‚W:A凄ٞ-eGYmE]Ea`E+!@Fj zB0r:xh ے! -$>U*7(ڋ!K/wDY(n\Ι c!A(a}<1L&+zIHbX"[&=`L^Ogwx_Hp_^YZ>姏%ݎ ohh0,aPP N!Uk EcC~lw_ >a䢅I1+G`P*@=Z _ʆx{R3_@r}6<.dm;Օhϫe!I3|Zht{t~PA uǢf oPC q5*ȶyʈERd3=/>KQ<,m?R87#}IkOYF~3OT-0&B!!̓L%΀t݆&y|FK&b+ EuB8 nF0a,$M:*%{M 5>WlurLKW[JYϗ^&wbȷ1&pCXüE7tA >t6ͷq@7_+Xfu`fb3=CvBGb5hǿĒK -B08k,!ؽ좔lפE}k/7~>sLހjY٫ GJP"-3i#VͰsU\BVNL-4x^0GjZ(dTrmE: eD68v7(*H'4#CE.rF%UFꜢ 8E7o?t[-]3͚%Hu/%|U@'>oͽ7-0]K -0=I!<8p"¯̠S. R;rVž:kLG׉>چen._ճR/,$d>C\`љE[t6)F2UE5J"jd>8vck|Ikw3㶀ڂ &И1FRE"shZ}}} T/'w20;<C]V m|:l@/x)NeISjVL ;K]$BsPġ63* Zﴻ͛pm#YHֻόSt$׵تNyQ])kPu~WegAcp#wRN sJl!Y̶J(uE|:w܏( B 6ǰUlQpqSf'{T,-e $rtX戨3Ms 5=ƽĽ10 :X&׳a֊66 ׫]Y{7UqodCt'_ m -y:̂]KlL4**L.q(6dRӸy_ϱ?%~vvΛ yoA02:Vv"yꡂ4Y!|dAVIVy@jPu)c0NQ?R&sѸ0IJ\i3ڏډPG"A\R#8F(O o cjbv*]X^ V2ӣ+-d]dUuq]ijj7cD -M4C?ݡ {;(viqD'lA)s& n~:juWckCuo)Χy X3ƙdi=3_%R_!s^9эG<Ȫ1 XW/U}(7c;9G.iE64w̒qqVƩEY k$k[~EScϣkƫ#~oaLh%Oyط}g@EoI>:a_DJ~+ni~(0zAbW姑c+;n~XUj`hς) U&rH~$T)}FBtoV'p@"!@V'bkυ~X]5ՆGř&7w610ɖ1#WB.5nm-X.C*mQI9($;dC"p뮁Mr^7FA2 0֖[T7A=I(a{P07@OnS-r`PcQ&w7z,&(譎][a:?/cWWQtHJ({]߳nۈQ+\x4Q 0 SP+LURYuF"ېz0$Kl%PU2CCm>x-;(9 q|B9clzW=\ug> 6}j~j ȓ s|_y{=km|My]&_1$Htr|?1E &8N_:TI%KUYKoIShir(3&0JpI!{/7%@p63ē*ЅpTF" X$ow"TTS_Փ5pѺ$}}juR&!! SPY)')T`T_2-f&ǠԐ!RܗN,RHpKs?}v;e0oA6+Jգ6PImũzE9.Jx 12A>GqJ6CK75 gSs:4~D۰Um8MuTv4pV8jɊŨG^ʀ__ @D-snZIꀡ!@ٞ7\.r |uJ -Zҧ7 \Z6Z#,)G*AKv f#6r~@@YhO5Fܯ~_c~jI*h2됱*؛WY^. Vw͈]CxC#{ƴX{Pgȳ[S?Si&2{>qEӊEQA+{MOb jR1ޢX+׫]оn =Ѽ==}ftcB+^FGy$1?GW}_f f,g3 1Ň1|ŬTfPX&;-±n_fPEbN M 6]|:IzYE':g(43WghiC;8C_b ި-|ʻ1PAC<úAV8bRaL -Ы]Dsʹnh ЃB[/˯h5!y `]yŇ٣% %uoH\Y{m=[}AORxczHey#V:lQߠ28<.E3bj+1Dؒ[ZPRN}kQڝp=l&4KPnX5iC`f+lXmc\c;0o"DL]A"lea⺚6HSLIEw[rVZJw(0 -3Mp -xH/%ɲd)Cӡb"E[{=GU_#Ggz5H#+NT1g|;]-Kel`>:[BY*ܾfr(#Yxxr d[wu- XϨjcMOئVF -{,>DBň'ogD[0 e܁P*A6sst4 jwR"ىٕ٬ - -:P`2'TL }u5<8Hð-G"5.r{@zn6ܜPRu E yr~onS+dr8W2lMQZm$b_%ZZej`J+./kSj\Exa hbeXב x+Lr17 7D@ØԸ`kmn"8 "^,aա;Ft$#gn'$\QA<:j"B U!glBH v֒\[1K !ݗd󉡽~9!,~L^Ttqr:j77~Mm׻\Wθh덻XcwzY` 'c R神*3@w|R!32<<@rdp]wDj#m]MЉ7z  dom3 8+ A_ה\ds`RRDk!N9xtPFMҊ2١ݱEʵo%ӬЫd1*cIzh<>*xJ_! -HGeN}:O w^I+D]=l*`DA4K.t"PteWdoJpJXƾq=mxaK}w^83#;_vryS{9eɇPPrjaQrK:7y zq¯·]x+\̋N]bJߠ,2D~?S!kGÐ[a A pjai]i^ZUJu |X GNiYAWIux"S*CL믲N#+keuO#+(r_jSC$&o:ẺyOw»os'f*kxm5PX=]XѠBBO -AƇe7c3swD*~|zBG;^v{" Ec!a#5@Qbt -tez1I:ٓsc"@^sa6= U)H5#׵hsԶ[>m]ׂ!kf !+~1! -OvJlVAv:QEiF b{nnTNH`ۂxZ!Au.e8YE4vЅM(?e;λN9&VWq0i |<%^+(6Dc“J -*f8`9V/=™tz2W -wB3}K *f`QXe^LtI8F"<*CWsP}SJ%v,U5ڜh_ N|~DR’YfDMVx2B܏Pt Wr82 vtA;΅h-RFe_\HLvcc1PBYa;+0AS:?3bQD֤#)ۆ$s#0XGCNG/Ai0~, rN;_iŞYVhLbChQ֝e3 -1v̌c{5eJETUI>ۆcosp:e;FPz@=K[ =j-m -v,TS2Ϫeʟ>}P >>DSu@r!y2@5B2ЈX#QcYV'/=4}-(]fa#Dy4zQ(Tg'|mE&8JEO$W'4@z0gka97Ato]^Eb4eo|:[-MJqbh΢+'@yI̚o$&Yꅬ-'=}ߤ*KGlȌ|Qu ^]mN@)^ciS,A_jf#oڌg[\=$l nE\e8>$vu? t ʘ{$M6 յϹs.\y }N%JD2FPo3NreIW?PP)n -T'Ԥ;XD\XQzҋWm& e/9IEGZL8C2R>E4 [H__87[zc/P10`MT0"t B  .ʮR1b 4J$+IS0r\%E@.=+b@umB@𡄨dNC'eP2 >nOG_w -$Jj#m2"`?W -rq?q˅\'|]Hۓ%Mjc;c0o G}`æ IjʦE8*cM dAbů"ex |,5! >Kό(;hp5mD*C v>ZVzԒZ sU!yb`"gxǡ)h q9ןhA!eFE0P}7*F$| |wT`)h=#5Svֲ18%}ߪ?M7/naSǼltaM *hv[9~w)6PH(β]}%]qU`&atI| -ʛ)bSXİjQI"ƊmE ',HxwӺ#;#yQ͌_f?[Bܙ"U}c!NGXjGso| xhogԍ-{ٷ)Cgn~gCj姺𓋓m 47>`)fs9#z+x1y͔@L}Q(AA,ŅݤmoNByxF6uA~QLfQX^]߼oSm -C(l(6*MZILOR(50qR5{a-_ -5,O'.A'$%e}P gWF+xiD֎*<􎉱?` -kTCvgN@YI3>W5#B\I`)![t@NP @ P9sc` -En8ooҬebTv Ͳ[̠bSר wQ a -FDSD0"8m@_x]|P<@y2~k4sS7yFVTAҘ` kg!)_~0.5dw<ӱ㖌]CQ/X4Th-/+ήobp W~ -)l օuaIr.)srHDzpV+TnN0]B !H +锪O}x|'zƃuũKrRU݀@AGx$U ve >N>zcyS ׄeB`*/;vhK<3g:fa1$V -δO2!Oh܏$;!loag LuK7&x!e$9l97u94$V& D딺OR;HAW4d`C>y>o>Y';L!tDC|!7w8hA$/ω)17=wJDUũC°Jd"RaA!B9Q<3e@lP8>l 7oiZxHM$D^,ǰb1ƼdBb@!!wmhYf&4W_F\eoE!Wmnxr0`P64DKl([ 5A͘ -Tq t/Q?e"hѫcr1zfiVy7C 7iTI="j\H{ }X.,&jxOڗUG6ߌ# 3`oF)w1 QOl}Jx ɴ>z5 [;p _IccgӉ?wcrbipd8D\V9O!#m'\5Ra.ȩ0!'8`'OLI'aFN".;J2@rV Ѵ9k4-j0^Kbc0Ȫ3꒝Yl, 37PF--yھ DKn9Y+ty7xYnh./3Hš<|xq]n,v74,OeQxCg@VY7*ɉotPnTm~Mn9ǥh -mNR (M -.zQ(O0S;#sm̀Wu?̲Y$E |hT h5ncdު .Və=yxCzQR @paZ$S2mOZY6;Ṁ¡V2S,MA]nȻz 3?Hs6?(LT#a,E8bcvRb p74 C|ȧA4(<_N2gޢBP'Ex:\G`vG&SeMU4=vgn_Qs|p.HLjO -_p7OoU7%UY7@Y|e#2M֠c( s/H:ܻk%p4Z1려CCT'ݔOhV[ 66t/l!Ǹ>M嶳6pl@Af&؅w#J=Vk=c?~zGBFw%łU~biߘ"D4YYW05h-ѫ,JW%Hx;}(  -/+ej _mrC d>SL \EKL_0ڜ18d,>:,|r`uf?-&=N9L$C_wY IS#J#H͍ gt2jUgnWxBrg1p8lzF!V_lw)՟c^5ŀ-ji†lD}I|h5221 %{hDFX \qĪDH -xMy )V;,'N34?3V#[Dl?y{dWt[J$ -:{ڹ҄ӢuQ4*ex)KW|V(޷2Bij“ڳG҉wSvěRRPM]?.X[ 1D3P ? ׌l5 Kg*kKdد$}xepqG>O*5C!_*I燈Zq+戩?(‰eviyHYmR!%WʷYժU38:\h ԑj!cDF+^FLmH㐒8aCb5W렗QQCs@o5I2VBdM/c9e9c%ciPƢ̯Ov"J?g*V5Bab?8M'Z^xUmFTUA:4Y'Vppn&.8*g[W\F0:Ckj! Ό1Lň"$4UEW=ª93RY QIT.ca -*L0-ajU)13% /#j.p)<lhS٢A^[_ -jC{DoHt 3SE߫.{Ɇ>FW'N78UX* 7=j|T+$; |ozigxA}hWŸŦWX('0θu &WHh{'"II9<2d^! )k:M)⽩:Ӈ4%(ziBzeLpi+X L)t /,Bj_Iȅ! HtkI6}dʲU\h7>4΢1yѼU$(RK6掠 ˲_ S"RUx9; .U՝MWv(RT߈Bd[$-"٧StB␅ѬBLLB`ɟ -Ok30!1h&ID#m~t"f/Wd8P*Xᛐ^, 2!k cvi#)-$3Jb2<"d$M,D}#pE74ǧVnE&MmWW#F)JVWV!Ei%mh#(qB?O|G01y75ȅ&N# $^d£GY|&^F_﹘bw,a9}|3˭pxN^a -^NQZ0q~ u.060s1 NGUy&Ö" DhSYK2r˞@ZUU)miH-͘p Ovl8X5;P9"U&q&>'b]~1Bl)T0Dnh-%nfyPAR!N6D&f*+Z֎R6'ș]r^cp4NʖQ컣>yz][n[ N<ȗCQÅdT&sCaH^u7!O{O(E_TLK5o`2[&d$h;-ËAh*$ d$L*®&8XlV6R߲I]wHxMJF|/(xлU -#42dH&nZ-*C}Gq%32ӑ#JIw[bk MNaZk(UqbHE[OFqZ,D""]&&SOTxiKFl''5Xy?{*l[Ɋs3|&Ӊ7,nb|?׊3;EH9͉  -Ӝ|mj,bE(Ʊw_y(Bت8!OŹkPt"7gHq;Pl324/%B}M=?NYe -}Wab4|%21&©, B&u(!zr@~l "@ D \ 4(%@D(` ؠ&0@.6( 0l R , h %` ` B#@DE

j.y6D&ZN4r<4݃ףc3 C;;f<6Q,"1hO(I8y:1*"UP)eRc[2Y -uvds\.zrW3T!Bޗ8)ze%/DH)D'(Acpx7#Ú"l<"/2%'H !(=1&-AY-%OybIB-{/_j7Z83DV1PcaS(Z4ǘ>~qruPCj9[y i=BTK -(N|ZE%i'\}՝E,Y6 v%EѹVeDF&vb ]N$7q?] J7HSBwE`0(Ϋ$E.# vO>?u* p>Dȫ5R$_,WXU> c3Bo”:MÃghlQ dưuSek9<` ֓I:s ²0!GIXdWP-85N4[B7fKUm9כrh 3&>U1V"Uaa(Z.ʹWbmdR#qcV$:V6F36ۗe.sLfTC.TfǪWFCٜb1"89k X4'D: R!by%l -sEbz:ґMe9 rաbX6;բijMt6v^ 5,ƺ-i`E;("Nϼ &,+Ymh@4;YlȾN?܌>#M|1PI䑅bƱQZ|~6WѼ{jn1>ᩨi>)s1|92iYGG cfWn$=24),mTm%V8zG2y\(kTBQCfsF+rc 2 8A뙒הI5G4zUF=#ǧ4)/ykG*P.:2ERy*KYn^˫Z2)g0xQUJhB&L=N㔉@ yܥiCS*R-q*(BbYYQ}ԌJEBTfE|ex Ehq%n'"SsBKEy%lFH;$- ѣʻ( sflТqBKݒř(]-|SFM>jnRp(R@$1h"x;^:Ywv t6zw MM>>CK)1ۆ+[Jc%IVtM}%{ v "#[ ..EOD؋^-.4 >^j1nȷ{!Jn%"u>t Ǐ.c1JYA - -!Ü*;2 -%oh4tP9(y p%R,*c6\e(,R.2F-;8)6{ȏN[ƃ2]# {w$1fDz`P? FzTVpO"Gt3 -ɢdhlQLb`9s)SQP:bi %0ֵe%MuϣS᧢UAIDWxVM`X\Ʃ%o3؊H$FʊAqJ:eHan%䮱V0*h+)%wϰfKR$C7oH$1C{JH1Pj$iMc2-` QRܕTtÏp߰ FCHTSCҊ0:Y>9H5KG3(c ]K22iax^Ρ;u)_'ŏE(L) -7MGQSoӔ,S^waZHIX-Xa`& 0$dtP퀴&U<9H8xI;DLW!l mD=1FA >UCDjGSid<)y#9%l|MIjTR Q!t(zfvv.ROYhI$mO! -yb!~RV"JEVzT\(dBՠkB}y^$lrLpHB$ѩ%7͆LJшe ņɩuh] %jHtTiHdxN+.LXIU%z.QmTf\EeqQU <"2ը2 '|kF*.EB @x@lWf{jImuQyۃ3T5 #!URQ#0ii_VmQU؇('F4'z\vh/q|@kVAA1=d>#C* zu-U]R V8UPC')Jr%b$T"LBAVCQ9(EBn̆Jx[(57$1FvJc՟$jS'T*xBJp[vɶenkkL#u^A䐋l!(y rDN69dt0%"$怮w0z|u r~=ijTW٫~UD6D&*Nk$xEB$Ӭ"HL'hT 0j ՓG3@=d'Ih$:ege=Q\PC,GVj>u= 5DC+%oUKȍ,GP\P)$eGTaMh#r,d6z TF.4lPRR,!@44AA+lJb.m!/.዆*!wPc<2S,p< 7ε!*vl̷$Hω -ES{AJ{#q6Vgx՛j;RoJT31B aR%9,bzLMa!1ADf -C ʸ^U% -疰<3Mx"S A۲5Ń9BX!’$H*2kJOЇ1uB6b_Ω-1ǔ3 J#Z),U'8.!-*-(k]*'HHi xl'7*%$R'L\"O8fh>X"(hM*!ЩPv¥Vh$STbkB$7s'dITиV=i*;U)Z5ZDU>Zĕ?VoK˰C_̱ўvRXR Ԩ?"ɴ[rEV,ĸ7UPTSITMH,S#ȝZbԗ-ɄJ@X(im4Tnz=$-f)JR|R"A r!ZGL|(:ڞDQtK:e,<畨k\)P@&^*=9.,d KR5T-*jPlUȶNMKE\S0=zTʃ萪!` Tƒ޶ڃjPIVDY uH:SGimM P:MBstBT_M?L@8;=(qRCtfwA  «"ST#y`@:شzD#wdԇ)X^'͐bXWU= -G6Auijۍ>/"V?J6KӵBꆂ.$!GYK&$֐iVK'D(4!!P9n},~%4cԐȬG+ȑ*Jkmrm.˕~,*%*2ԯTCQX#CB.+PcrJFaq?J\<}Fsʜ. -{an{@UuPx36E5v|p0!LbE!PIPƊc1+H*Xm6OȈãEBS>SY"]"a:gΙz9B&[{^SƉU(1&5DT/xjCtU[ᗅǨDYX/S4j\Q嚗DUx4m^A尜BV7 ;tK M^U.-D2N2ΰ+H̪1슲C",ujiĝÌXB(DTܟj~Nb!FVrnt*=*[( ՏvlƤӘ>dL!/+e "*4Qr!S`xNR-.^`5]=E{pR!YV$<8-ZE;j"R?;Lf}e,,$x-dyl ;TFÄ)R'aʢ0Yс-~3k?p^ ldd7MI $*P嵃pn&7X<]xk܎GI}a'Anؔ&wlp#HľR#c*Cߐn%1EHDMĤbdMAe"&FDW#j3j #`/M -;i`cq\=Ӭ’EM+6hklQQ?VI bYV_%AJbRT ͘ק&H E)Ш4¦*@HhR<@ `@ 4;V<=sԔ8|j8"S.mJ"q -XJ^✷S:zH~j*{zYb͟a046(j?K>xq_|z䓜 x,`=W'efp<*ɁIcTGfy&*rEX"Y9V5.If n'luSnMiQJF෢|O}T8VÝn-UaBm:L,S'2QFvV2rerQ%U@yAM --zP3*C}CHa- iZ_P @ԧKD]b ݁.v%˂2Z/+Ij]tI֥b[O֑8[mI -'|IpUayx*rf%t@p.S;1a{j$IFfKD6$RJ#ֹ&aHg=.Bgi6[MQfŔ2w`dƆ$#*Z:):b(z}Ȥ/a(m뚧A058|u%+Y!(=di rJ7h_^@4Q.k!IX*+#ɔ7/K&PU=}z,o,ܗ pYL F?$}IW\rz#xlKsa,E5Gjjaoƒ_&(6M?xG߶q_p;ew59gGiSVȯiȏ*Y߇'q$\--ֶ*/d1-Q)EcKPva1#".E.B 1ҴeZyz{aGkh,(h볕o9N"/L76[,|دڛbCOB`RF~ka!M; b*87Li ݯ46db#AU8 *SS ʞ" %cqj⊅^0WE-# haזn@B0 -].Fg}(\RJ%84ӫdg)urWkzS$o DD}+o8.dSrz'䡻 Zh8괌?+H -yǕ0anCf*mƦ8L{y'鐋d-9GHHi5ngN'{С]h*=pW抣jv$K 2sP3,5HXᭊ^`GfvCPy8A)Lbnԭ}{z( >o^n0#j].\jJŰeT(aW. -pPNV @}h: +kHj A=Y;‰_Y԰]gaMN|:w"Y)N4EX]QEO{Y4wfb]kK3zzr/9?ЙX2nЇ#9B sE#r@o$bj1Ҧ)aWH*6~j/Yɇr5A OI/&*]ۂ\q.<` o:8<` I/0_L9*5t[f]bpDh?KlB]Ŏ< 2OlT:r?n߇X2˴;` д ˟Hw֞>Eva ЂV*B<2V%?K0`@G姓j)TvbfAY=zqyRf?JCõ/ -ܫ/UIL)n,P|;Tr^=H- P.QY-L .k}Aġ~|X[TzNvXb.6s +4H8P59#qH dzE_=0hH soONȦMYK.ipqYW0"݃SWGtgSj4.S:QzE N=]7Ў ZW(:f53t7oǓݢj`'e|m#4O1dʘ_e%j:hJIn</2l, ;?XPn&g"KcGy9N~H\ |O͊,㙏E=s '%ùېdG㜂0+}2%g3 m ѐ _+? 5fo!buw/ZNń 45 R԰V$ LJ).sAvrկ|(J!=k$Oɓ_ooEΗkil4Dޯwfx.P3ػYpMeJZ#qq"djKCV;Bp:psH h7D^"+`QZI{ch@C*#PIQLVȂ@ R 7Fͷ@<4Wz$^W\ۙ愄^DqZCuv_;̯lyZ9A1y@s(W E+j ќ/ҝ1b+~bPS=dMT5n6vk[Y ?oE~Hf UT8[%)e'lA!U=S -V>MUk@B6=0h}pٹ->qԠ;^GQL:V4V㫚8q|^Q:d -ZNhj"́1aMoX< TaxFD /Meæ&Eu!;V.7Y閤5ٮFilz^ɬ \NFLi󄛅x|/t9G} p͓7rrbK~dSJGlj\/NڽQ-b m5yy7z _`ֵaQ*[3sR-4k^z`K&5}RӂUE4]Rݟh oHHn;`2 $N 8ߎ d G2x82;A{ܖAS+ЂNnB90*Om@ۀC"&8,wa1b[0U W@[. ]mI1PNYB3[d5kT\*0Ah! -^!h:pxHlpwn e7>*LaAfTk]An]cΓ,Լ5H +ҖƬ#71JG:uoS} YYF$< ZLha -%ͩf\FMWGqT!~9ʹ IMi >j a5N;ɒ{ꎞg62*Iv!ѣ:iTh±FAL#>+pCpj C4m_JA>4GK4.H5]1ƾ8D@bȻe9EH~(hurTp4tGln'^-\E|H &C3{?̃H?idQ0!͔^7SU }+hcÝ$U`5Q;BHB@ u+**V1 ]mn! ՆglOd,>U.+ -!@~7ȩiǐxrhS  A݃ r7l+~ &QҎW~J#- J0 >Y9 y\ǡmB2(3DJƴ&@.Y$AE;H-.>0 ŅN}4wZ3i2H -' +$FHGl$ IA<فR>țY @l-3+BjXDEo'ɚ`>Y8M-$қr];YF T!YQ ^+DPpdg솸Mj;8 Uń-i"7I=c ɬ6uOseb_fT;}223 zd(?}Z)uWYY #fSXA5b{kZc>BVİtc鍌HG -}|f`r[G4֧YA Tp[ס$^+&˻&!HYd88%$t.gSKp)$.O?)Bb0e3 DvpÎiVCʆDZV֠QP@eŖ!L8fZ")A…Jk J -* - Ύ,X o --VHVpPE2B^"~iQuN;*7_]C37ٷ] w D> Gk01/9B°#9zH|&%(|;'rBԏ+b ڜ ٭nB#ifBv8.}^Jqw[`ǂzïj`> -̨B,C|@u('还E pn~yex&F) &8dQ3'`l*J%VDkJ\ct||<"MUVΐLI[!g1ܯ(_k}ܽ(=%f낅6EmzlFy@!-9=‑sWLJ4)GMPT h[$' ~5_C& 6Puun:@ S9o=LT"ՌdB_/_ޒOf:g佑G, -Κtd:Gď`qWekN`Y1&|i0xh+:lL_ÂG=O4MwYb^''SmG4 Ì`>:ZyK恭A^2JB9p`u_E - _$&j)D.)|_bĉ^:/ԟ*+O(@0eifY]|xtp*@Q(4F$hQʯ#&PKR2^Ia:t? G0n`k>bb䣼$4eMBtJ8uID2jCBNeFg&vX,WLmudYlu|IS?߲՜AEJ^4]c9|'^:-D|G]i Fl]- `6Tڔ;]Q=ǂmQOeKS!wa`r \xG^|DsE5"O Up -sy|d!$!@A܃2Elظ:䦘NC"tqW`Qclzk3兝G c31=0X+mN*7G ! 5-2MzoيKqԏA=MKRʆ MWɩOu=EkxXCc_t!$Ơ-W%]q;Iqu{QɪJJe2hYXD<(U#KAҹD mNM;g4$ D2w}=E~n? FfdY^ɑV-Cf:RgaN񂌉POop( #qXNjGhL&0/[`Vvj*fw4 R,:TjF(7+<CИUJExO57*w#^Y09g -Jя+ a !5XJy:.r2H6қOʯhKfbd TápB 16|l*{by_?sLB =^k+'tn%-nUN %5Wbb@ 0RnRi@Qǐ{ʇtfJW-"ź χϵ>4~hMdlI -b@c9)a!ʇMgb,\B5ay _ &Ý(Of)(>a5{1@hf(xCAЖtTcEuK -6*U~*]5cx -H1&ig4s%k O(r!O[/EAu+2SYjᶨyUˆ?y"4YkaO7).y~@ѢCV8 iX -xfJ0 -y ix]n JwN̸ə[Dt(7Z9C0ֹty* %@~h1q KWHzUmS'־gP=r=t˽Pl< l[GW[ !ݽ]IEӺ3=ڮf|N6C\*枍,'py6@dIFÙM< '.5oNhP1oF EޝCQ9:f_$_Ԃ,PkߞZLFXWdx+l!˨5M%U.9ՄE~fL؀,O(ZB5s) \8PpaT$=a$WAM:Zv_dYŲI.Y6fbz]o|eq2W:OUh QL5@na)F z OAb &xkҏ'8x܃?XF-WR?L6\}! Xva8GM?.@ p rB/Gzm;I7xjlLhdvGZF^!?\Sj].Z29%30B@t -7+:ꫧ_1$XqF;kY`>tB=m}ЧΪiZ> *~nuXE)\Јm7Lm'b ]+wjX`Fߏ;2fd)Ӓ!Aҧt88ݱueq ˑ[/W0XaOOeӖ*Le"Qr= ~gfβ d(o[+{I - -'oM%OZj.$*hM X@b -pTK5sm^dpaP|Cbš٘0Bo$;Jܒ]l[0\9v{K| s frOzٰ?ء%&^/w,Q@ĂTg5\m3d WI(8Qhvd`7H^>'հݰل`l8ךal3mcsAQga,S -Cy!QxڕxbDI,,Ib? ܧ -%pKby Ny]TbͲX=vzy|tav}DКuũ ؄NTKx0Pk@pE$dʼ>~ܠ3A lٮ=]nC&(A-O&@Lm7Q7\;—;y}À &&P=»( -GUA5UKR>^p,?X笠঺"A+/3W`@TExu\߲m_S< 5- g]OB*|/faTaR0`!0 .?)ATEeI=JlVɋD*5>&rA/)޻;*Fy'5xxīǝPh(GqNI,VC&Ki͐1Qd3d=V9cխ@ͤq@G'-xň~OOxktx ) -buw(_Q!gT'|tr.w 㘙RI0 -YV bͤY - -M*%ĤBvDORS$_ NKCcF 'E/B)A˾JA_^^'~{VW -ephO ٴYW4 [(>/;^30a9yl6@'~9 -i.ˏԓ@`%Jnjl"X?Ze.j}+ZsQqִq3[ri5W|`DKQp $#Dg0\P\Y"%'W"ゾ *a o.r!`q~ r}fNWE*yU3,'-"6̠%uݓ|N*'!0Nf,a0CUP}= NeX!k(, YaM6AAsNDI ǫOԞka߉q ƒU qP p` D4HWj9!v<4;2v#޳!T[|>/\'p?\[4՟[%R ºLW5,n:̻:"C B$~7 {r6F0MS1mMp"ڢޠ] 62)=(.WDOAx.|'bS~ g<bk[bm"uG ALU9mt i/yޤZUsc@SI?%82'hJP\͐ ▦{XɅ Ji 2]/i2~NJbJ7 ~ֻlDƐTUMWs1 Yth+h$:)_{1p wGJTğ&2 $vhW} 59)Jr˱"T5|\Ug-rd^]nTr;l7bm|- -,q[Udcɨ4A@u]2WJi#ziD.#,6:|rٟ@*1MOd atTLO&&e,h -3f~sŒbe=YVੱO f`50q\ n$4[4A*[䒲p?UףcOAC3jmHFZrr}9N/Y3 -X.XFY],r_PQ:^LyOL*AQШT~rk,#E%O/XT =A4nF8R}OWAȘU94`O:y< -z8L%HoHM@GSh ˎ[,%H>xqZЯ*59<کN-s=ҹ~SeF1- ͼPRzY>7Y1;>\`Y\R6aM^˾u#h+K7$GsF?h ->7ʿ)G9C3sWezU(jLf+t{Aj_ ($!SK`kY)JuA{ 2h K&ggLq~D_{!rH_WwEb< =&0Kk!Hv Vl* @ GNT~$mLAY"%Ag.ڥLR5V=_t@kZ<_Bgrq 3V)bo!LikX`GC".QhX K& \Qkab 5jƳ Z*k%0+%ʊ5{Ƭ"7h!Ϲ94uD3ǽtn0׎G@`}C\N]j`3(.Pf׌ܢSvkD[=Ǽ 8 D[<:Fasڬsc߹=9Kf-8^(^ = xn |\@? q\L\ts75!C,+!Q(*"]kS_ )b(Ǭ CrGEfF;Vv(";{kyoR1ޚ+0~+npMVhh,`\( H[;,e*SǍK)VǟCNYU;\cb_2lW 9~¿$Xkcxkw믺o ߫'Qڸ6U"k٣+b"=uZ49%Z K~# p ?~yksJ*[~53  -[{J %oO:v/5 ʖ_!y/a_x,ږ3/ 4JgaIO(S#$Qz,lگ=x.BO j\k_P4-}خOP~病|Dho&W||a}v`_}~;U9aLnj~YԃHѽ~ u -ukLA۾ntZ~ɀtaNҕP/^Iq/āvWڜ_,TL(L\ \qh$0/{SBHO 8kZsQ\u)Q:ۍB;pBύ_cJM~kq{Jw!~ZFu_lRտ!^9b}Wh+9smnTduKyz @em p 3+0I` UTNLߗw -r&p[.f8=g/kܔ_Hx)xMD> qrܕL{re\Iqey<uOƇP&xF%9\|;g[,v yZ[@̳pt82tb1w_r-R̪?CfU:Q!NB`JqI b~l)Q:ɸ?Mbgn˗f&ߘȈ ᾤ˴맾rknjxOտ%{H_OI_uz{ UGť:Џ/-ʰDF#[_"8^W^% Z٣zwU\K](<(창64[2ϲsLv;hvڷa~P/ > -}5BO-EH WP\U`brƐG -#;qʲWwЏJ8;×y}g)oxYu Ps"nvK -1J6N~$!R`\*dcYҋݘ}-^civ纷ϓ8@ (;I|kDȎ^*-WzڄcӸr]iĈH>sDgI3< s=z3C)yKGeVrW,l*HsTS&`2K5?( zm} ,'y/v/N^<}G|<񇃋% RSJEr@Pm|.gy JF*#+Ə|kl]M_SkqUA@hO!ApEd-/UK!δ$͌b%!P:z)ŭvir%"RdBOԮFxմOIX6Z*BBXX@3:;X0gR|4W٨ -- Wx2np!/XMw1^<(^0yUmF-h0CdfC+\`ybi۝#{W͏iik,LjbĢYTsrG[Ci(本$O`I0nfnO[K,ȭqrfĭw7PZ# -l[K>Q>/6m 6؟D'H6gH  -[>" 1j7po-עcsk=L X16!J?wS-!0c]{}9?͊W\%_:”b쫬b*pb9ej㎯:POcf8xRbĂXk81EPճE0nbtc8"@XG27H}f!dVP~;_ -R68aj(,='iPh~ϣ8 -\~'9i5Qa2YVIi< 4٫aP=]w1`ydMg핎2yiaJgބUTmc &&fEgyP[%Q[ (EZR~PFMR7 +E]qZlA3'U[*y5WO, "~pULm>B}{*X/a;| Eɳ(~ *&8-#e^pTnVA\]QHV&v(&1-Pa^gEõҰd2- U DV>x+/f(}Vh>fA zl> 1{jVl!3ل||} r/ =L-ZG%~-f%\XG֤ -w34 -[-1Žaۋ(އ`tVK%ۙ jydU[!motb8gB_42L oʸ|,upX%CG@,W$&"dӹmb 2 З ϠM_e}-,)Lq/k5<vnw`jY eU1&BWXv -}n`+ooXU,{@+,J,&g+/}a[B9`'Y %z0uk`dVb8MmkިҀgK>b-q^x}C?"p˚>%bR"wǞ*phl;;kXR}snsνqƮ\=M - -<*d浀W⌦σnwBwd]h̿-fJU.{kfzF!2f:r^DĠn*Z5o/QP1|{6p?A8N +.͂|iy~=m~jԑ}F@yP^ Đj7'}y쨀FOS -ׯO>u^.T|*N1I`|(Sf$^|ڤs~"irDC#EJ~0갟󉜾P1ցׯIg@;wҨ7ZSXٞHs$U8뿥_ hD MD=֊ܐb%g|{P#_riqg9@^~n.nj* xD°>[0tQo }M[^ ~`N)$qxܡ 3ȚԔjhb+;t jdʪڟGТu?17z箍(F ZPQb65rW:՝(+)ǬUNwXAkolQ<kƤ71&[e-жIfSNj9qO4{ ˵8M -+fJcەa+0Wqf"-y1W2VLPRԋu<4N--a'1S tyBZiW߹.1"T6N+9ǼWަ -M/ *7ۉϏBH1 VR]ݩL l#j1QzE$1T]h2/|y,RY1J免:8a󢒯iKM -hJKJά2X)d2[Әpj,Iy,Ò6 Qnrē3.wg/+c7F#H/q|nN#]\McN{@cciX̝#1A2bXa)=DڎGEh#:Lx9Q#^F Mi -u gG T8bŁRz - 150,Zᘹ/( =WztE9=+4-guU ~\ا{li)XOA*vq0_G'rR?>ÿ'*= [)+]zigDw -<6TAj~er0zLdP"ٞ'f1ܠE(ȍEAm=%ȮҎ_G,zHኢu2z5Ԝ\[]>hb%m'0/4gsyUnz~eI2J69MTLOޔ#yDc910HĊYL"RP,aMA߁~p uO++\QxZ8L d#őG7qU>*Y -ǂ90/k{̂x4L6Ik,ձښP˺1|~t3CnQL'YҁPo9=oL4C-^ȌA@)b <"HX&-m̕&ꘌƯ{7)3wʙzt-O%Gp#G,_W>Nǫv2qdk6wc@swC6o}՟0ۋE0yA+rY'rpL2G\P?!Hvy8˛1.{EELjDYp"Sg5ձ29B=l!6Zt& LCb,M1_. - Qs0IZJRuHa"(g!B˜XJdB P[`J;&m KHIHe:UMy -ZuDq݇b@V -/wC'4i$I صfvxS{]1a"*˞pwIƄ -vuBdC }vw̛И&P>)ݢ -JuSȃC:9"_pCΦWyoˀz'+ -Yn(Hۣ(,uQk*+:kz' k^P -YxKJjY 6XQ[A1dpL\IƔE@AJl左5\ i% M)GQ#qc4X&_.a\a+~ ۟M]r= P ۘCYwpZBLb#8th5r;Hݧ|P5/OU-Z+H:H;HGWPl/QޖQёY;P"۶,STPmKh Xr7!RZGySUۢ*VT)fKXҠw䤰!OǚFS5FN:Y&9w}W_ӚIx0Y%XfAN)S-0)fSĜ<Ԥ[S *5BRlQ*tÎ2ߪ]YZo3’$HŞaC?6K@c~MZB  :ľP NO-x닏z r)-M1ua?15aP=bՖԁ@`go-g&u)+#Y n.ɉ"v/\A-V;?[_Oɸ>UE_Ɲl1uĴ\ML8p" BL"W=4Pz$.iE ^\H߶-?Hw5XM?W'4H}b[%c9"qQnݳ_eqh'P]7`D GnESQ ^j Y9BG7tuTZXɁn0$I2%}Kܷn pw,MKrXj*٥NQ 2j`/`?hKLG0',b^SYi#5O$͐EBo`҂P3i̳POq5%v\^XH)Zk*a.M~%{b[ N4 t8|J3- p< ǏFl ^;]]%ܼLGZ /aa}TZ sHLTw?!ZuS̫(q q5"V^84CKpn>Z%߲#`TZ&F#(<'1<^bn&Z%}Xʯ>d+# H0!9:$jx%E!Vhk n_ _{_H[dz_Hx-Mb06ccy@'{|I/Dn1,&J bN=1 z $ûfY|3OT_a|FU_%j4?WT2%ͥdh\?M;|cx4߲tp?#fciSkHӿvCߣub 9w|`6#/BR퓄Ky&Y+1*J:N £L+ˬV,@)򡑽!Ƚ[yAؽ@/ڝ[R[Z$¹v@ &'sRCq%:Jö{TC:Ń g\*?gHΖa! g4&!?m}Z]Vwu-*RNLs܃֯IDu<(6u3??nEQ I[pW\}󓒍_k)%Ó(`K "OpzlI?y^ -*t怱 W hc?ׅeԃ~>v <kz7~g&?6\_OߗuE]RDҭ'LZQXO0 rnR)UER,rPU!Gv;/1~5N`AV(OO]RnJ~YүM?(t s]ƺމ♎e'H&Ae}i-¿Vpf=/0z:0yU80mq"m;|y p)$g\ tCqcH$kv\ U|Pfw$WF #Bp{,_>Zw\uG"F ڬauS;.Z6\l*3;=H'NVoH#]i˰cą~kfw]= -Ć[A8qi~ -y wNuQH!ۇ K)xU'RJᖥD -EIAAd -+)\FRpV$> 2vnRH S81~xB -m$>MF)-JT%Ɨ@1 蔾? PA,w"M--@Ⓣ3{!o6BP0<y! -Bh,gٍ-_*BalELC'1ǻVk$l*oc# O բr$PvĂ9e~YqkjZ -+}b(U5Cvc kǑ&z .d/3`--x(y!p%-S3mPB^q66R*ڇ'uB [`;2)RQYy}mvl~V T/PLZ!ƶ{§}Nb ~A}d.zĔ](ύBhJęEe 3C} oMu O^{{ ?0Ĉᯙ{"ϨGnt`R#+v&%~d1V -Jx_/A?JDє=}@[6sf**`DZptxG_Q:]y,@*&\v>iFӳE{peVTxZߏJ(kSo\X{TRRLle?ة;ngIRPln/ns >c*sV1FJW#gҟY[{+Zr•8Mm0L`8doa-TJqi -+" 0< g{bG$י0Q} -+5/ -6\? PO4㭝 ,XuH6E8Kf*EaOJUPetъ1HDnK^p!bpaEmQb1Gp^'>stream -ժ΀_' g^t(K-#Vߨq [io/s -~L1KMY/wJ$LX)g''Ȧ[Ism "5#8abz3KlW3oW͆Bg2Ĝ6tı@. XМy(ə) }̟ kjմh]9Ε*V } YT`Kfb㉀  ~9*@6xWgiR.iӝ>Dߒ6|6qA\'~i QV&Kx7n@*M^vyC^gN Y$F,xu;b'"Dt h3E)U&Pb]17$\[ >ef ¤&6@*zTV51P}U3.Dy! =FXXF2 -g$O-)D^}3 2!R ! -ϟjTXa\c#J?$~ d>b|4ˊ7"/8{\QơjI#MB*\x|s}%(>Ts?Ca[җ &/nB^2Ο!"jJpPb84L75p~ , 1:j⢁پx: i N(| =H+FjH$y 2v mvM}Wv,]dcT RFȫ==X_N{J>zOħ7/emRAMʛ& W"ȧf[u,=Z*=/.UUN @AֶZ1?x Sڎ_H2\(.;j X]l*!+I5V]ZFauVC\(>`Ի 'U܅EI`P8lr2+qV7 f.t#|KQ]R0A='(Z|ՇR; 0ľθ?]V LkB-,H]d<ڏY߻jϷ0԰]󺁇F(hU\b;ȅYPZ'?V 릧N v0 />QB7o2bѫ!n628aRj Z8;LW| / Q¨^zh$OI!]!P*DS^v>C 9}|t#˺,,wpY>u> VAȸ0mukAϾо_\-ba23Q*2k -'!W 5k⡆Ϙp36888viS֯ Y:6:#ɒ"]&$SDxH5Y9X4# Mpy> -! -K¥LQw7IJMI-zږT㹳q)5!Znjd{{7yk\?l~6fON &wRb T&d2б9&KXbl0t&Ap-;}=<Y5.# Sً54y0n%Uc`@o#e`?P5"r+ -Y;-h&c-)3_-} -{7`E^@i Hf9D{:j -NN.$NuW^x_^HxC? QjP'?k߃Io^IwOZ5݇L ʿ@/dq*ɪo(gơ$Lz- 2SK)Uwzpk#M_Y\:dD꒩qE>wХDMT7"Ģ0X~OF:7,FN*H藝.^2t%)~Pj~MXGAӾUKx|ҺOom,D շaJ;gNvI~W.\_,Zџ8Fpo˼ir'̭Ӧ)S( ҭ(jΏKȋo&>bM-1e-V QfK4QDYd-hnʞ%+v/oT8 u*NpC)XŁZYޢګ,'ڡ=e/<- YWEij֨TJRSuLWȉǥ::[TO\QQ=V02",-C)Qgץ'꜓@9zVwW[M$@2` %kV?dxy7,\g4l<"~r= -CaNyJoFaʳn'ac`Dt7cHg>y5/*Lu ':!O ->J-!kUdyQ~]coGė57pXPkҡGڂ!;zZ#Zpc1/+>z!f|Y -_h 8@q@$)L)g/Zwy} s:$J}4!mh+g(LBHې$"&lG 2$I \lb_y:U={)D.%s9 iDlxIKst;\(9UgӸ}܏"bs8}4KID%STK#YE_bKC -MCE2ܢbDHs -+dd Y(BDԖ}gnX%T) -kQ+Ԓܻa9Ti҈,?S%nꎨӽGKӿUhɩ4::-gJ4'>jTa o?jm~L]j⫮xU+J88B!q -Ew'RJĸz/͸}ҽ.TX#Nn:wq'uq Ŕ*UDg&F~zeSzӨVyTnXI5)y"J/_p1W9~{*)|~hq_̍ΡkƘ#>1gqz)Aw(~#ߢ/HO,yb1HQuA')fR$ bH+P!TWܽVGCge/ NQD%?ڋP:1&bGKJl%GC:}.r'Ni؇Z<#umFw%ҔR qjR!h'yjƧ)ƣ**NNoT]G*nUwOƣJ3>ժKnOLXySG4Ҋ>Gt3/턟#'*O=iHB|!ǴBZɉk~C S){(I8|)=")d|\C'4sJ%!O(hJt DAOtXĒmwmwvNxhvh5ͶZDzTKk/;T_0cYS)}!25ƲENk -D+rׂ_}M~ȸ~Um&5'F   'dA>??z2ba*}G{R4gs0 @(``BSXd6^#WItfbG;_y ^f-2fP,_rŋ:hU;2#%o! -iUl3-z=Î+zj%ASJ4C;hkCc3B Z|jrWʊ`C P/.H0ه<u3l$ Ĥ*fOD"Tr9DrN  7[UIEM=(e:))9G.tE*S -9 f -(VV5fYh5w;LQˆE4QBTGXDNUo5TTI!Fݲ鋙љRHY*E ~A;rW!b{  p@pHVSZ&La̓yup|_HK-UjmKD8 K+QD!,'$ OQ\eD&rh\:Au)r_Cm8 nfrofr"ֹ:ɂ(n">Os Oj.""&rLp=Ff4 f$,O1)_/rr0F YJNS -_$&8E V3&Db_@$^ 2 -E$j熠|ugZij Y&&' )#3=ڙ֮8hG(#N2%ѓ!CBPP#cMx!s*EYĩ -?tg:a"i>lH'#cD& 1zI̠x.mdJbxpd({IL͢|$ ց \{`=p2Pa u!ð 0\08H P@mJN2"b| -TqվbEi#(MU(RLM׉6Q23Ҋ#Cb9H✓8J2$-l۷L^hd֩l SZ{jg#FDfXk4};-h-֝֯36Wzwcbq2*Eܣ23cQgI54!s+H|=Xڃ%SFѳў\Q;ZZYL+vsk~o)LgJ<4=^kwC}.=Hj~U,<4r!NhQsawd(C5&)ҜX3ʡQKDf~UoXIX\hÛ/[y2Oș>$3yx*/,QZĉAD社Lb>~5^"/$QFc3]#~$9R46*HR'5Z[%!Q#R' gLh:B$ieGΡubD5r<9`C\!kKֈxJ% j&'"_ A*~̠'R܋_EWpU%Uf"jjKL:vp1sX<[:+y  pe_zKDūLunqjW%8fHaίL֘hd/`y:/liGj<O&T&ma}ŋ:B'˫LQE2+%8VL?+%R2 -BZfJL2O%.EUV23ni*N;QΆ.!fCE9gGJ.Kc%Fq_QuhkUi15vpe/-ݝTѸ+N>$ȵٶxBetI!bNrQcCf6))/XGuBmI;_ć#,w^3?18R=*RH[88FycK\dD9XrQDj Q g<{pų)(1H辆ӏJG4~.kt"\kC4aK44v)YRtbsTM]e袗YeDߪ Grfb7o:n5 -}~tfHS9rrE0*3$_ iO!ЬQzrOPhYԪԡS ns15͞Ḥ D9IDlNP8uiVNUŴ6Gd&,dQ*9KզFMԛTqRֵYUe5F^ِ9oSr: -ɐH,֬$Ri-ܸGF Ř6#4-|H^w|Gͺ#gD?BIEh|I0a";@[H14_C!^vo\ --z@?DSLNX." - Mi!`{"$#Y)Y iSBUhT#SK."dT8ca'7!GNR2"Uf%bd>NLA8ä M^pS|%vjyRf4h{ :+ZOfϤWLz hD)E4a"!Q$&q=S8ZLf/AfgqLD}IcbW,I cqL יX'oPµ6lᐹM!ڋ>چ㲝ݹxHψBanFi. G.q:2A%^E%$q/>l}3s/-r-V#Lo.2~7^CNKLCQ_Ơ<ʥVe,i0-"$*j&e3U}|#K̎b5{sJGUz Vu<2Ca"gBs#>?CW.KIHjff$5j)DfzilI(:&!SRZ.uoGc -fĈbLeϗCMapƪ0#QD(ϛU10]]Aa AWLba0X[Jaj5_6RX 0$kXQR~8&DQhQPÊ*ƎLP!U*ڜFtJ )xXq+*濄1 -$HvX-41摃#bߎ9D3]R(>͆b Myra63j -E )* 2AfR04yMNAr ׶hW:9($% - I' -T?&ol4 EMz*!'ǃ|E^C^C\􌒧)GQ1c YCYϙey#f)?]"d\U%*B|SW(lعiHE&8Q\,!C<'9&"WZ(NI7Qr8Y3!\  -BhЦ52wi=?V̅ U3 @h&tf=j,f"j/5܃Aj°uhcS'I7)cT+Lz+6 ҕ5NI5}M" M>5EgN->|*Ntc>}u)9"eV%hDCiI ]:6Dz \9u79f)8[+ uwf<%Rq&Y $5kˌ8c4B -I~AYem2W=.lc)k?n Z3Y[LZo-Jx5΢p$M'Lܿ7k&5qq(Ϧ†ǠZPպ;yt6b-v cN+hҊV}óo2+<^謱Uƫ~IB2d|ɾMQRS%5ET+!k/hk8ETk3SR,I`IdYȆE\ɢS -g$).jsCឺ Z?jB%}YH|š%+pE>`𭎐(uR?7֣FVJ}>jfslH9aʋ+z~(a z֬A Z~[$r.r3B鰢RQjE+: hEPv(5LU$wD<:ՉFMd?!;ImO"ͅE7_#`h _Q -NttESIF9_'Qgxưeg(WZkl7m9ΕV :98$j^E9x+AsDEzw.DD#Gʮvi CGDWO$=SDRduYVrsn<eEj7Ô*iPd,AF0)mqXJ*bp YzT(9k= J'b xYvT,Kc7]>OZFQhÎGxPm~+(8NW^ݑūIfY v^bө)UlM%CD*Ұ蝨HX1|i$*d>Qyjd:Ԥ('jȫSkJӉx2.Q%Ai_T݊,E*VDZRQQ}4{Tl(h:PȔASՆwN8{s%cKk]g $9A#V4bohR v\-KhkbRi傍 Gjdz:8a&,NJD rh_QdZ.N:tsݴLg+V9Q;ċ h}n&pX UI$$9R ߑSYtfٶgs -iHU{HWJ-EE`%:AF29:Cѫ&ݓH5|Y :b$r&}Tp@/iP k٪ I`!A_679>B%*vo0Bn~k.8]#NX(~Ϭ -N\:&@MtV$ >r3LoG5^.o2l#f9-9_Bp^If.&DBGVk,0ܚbZ񛴪{/P~7D`S6oY/@zmUh5HN(T.&1QhByqS`'ktX!of(H8g~E3r,;#-aa)|%8WC4W^?%BIsaH\X`p%F1[봄,Ei`Z~W<^`9E'mC L#/J2haiVc/ oW4qӀSXh҆ZU2)x0 {sY-GWp4b.AGb׈of;Sf? ] HS7DXì?o$S:@5{B.Ռ| q_75U{kU.# y]/5 z$ASee=V%\b,u+Ar,gǓЄZB(R: iwa}8Fd#wN35.]K_  ʸtXHl>'cܰ80b.'7<'W0c D WB3VI(XokۓbwofS)4 6$zMڙV6bތΈr2M% %Y+~\#zf?M?DgAb RJn -(Hr5͐J (6I؜](@Y(h26\Eaxop2F7uHB67PֽJd˵ u nzsP3^P}v.|D?4a^m`R'lQė0RdR/:4Ç'Ӧ3chsʘZm7 wpD׼K71J KJk -|pLW" 1D@@a7v*k br93 $QJ| ~tt n-k4ѩITRS 6*]??pӃ؈[__#_# Pr(JnveEH3EMEM{El?V4X8ѝ&SMB` -ώih}A tN[:%V n[1G]@?Xɯtn$3j@Lor,#RD 7/Phqg5Ś 6< 7ʜOçce克7'Y6 $BNoȸ)cI !(⏨C4=^L2֭R -?bĉifɴ VJqeqwUoqE&_]g]+Ҡz;Q֏WJluj=n]m0~jOrQb"`0~ož#Hk!$ۄ9F`>W{V%~f!~PR)*II 6Svj~֓4h3Ϥl\Xkd%UE=r'sn?@?"mˀ' 0$Odv<آF@Yx|Ӎx&Y_t".<& ;lҚ'Kzr_oaOG"Lo5J٠Ԛs(Ln`Yֻ=k\vH0ݾEKOBrnL5?. R19 5՛K k~џ Ayjg1rF97º{-XgyFBZB$K. 5JױwX -O5c|4 -Mz1]*CN{]Mjqkb'2]RJ+ HOyK]XvߢSt$_Z%GdW)i2&-CM“S1˧W)"JeJidҗәv1"q63:2ewӮotytD RʓC >+c-hM𘕁Xj[H*"8HHؕyYr6a ݝC!?Ę1$3 >wk?YU,a`d""Y /xd9ƏF&C@(?'5ߎ%Z,j"~}8N> $;eB7Rg.h54yJ0T8ᷤ0CR?UWX%?{&x|~b @D Ч_l L;??)3i*AfmpSh(/_sDW()ԡ|-G=-@!n52s{NM0E1Ufp <> 6_=m+ @N*2=+C&'7C!B }S.n=x";|;8FO¿xVq$>{&5RZp7+!dfD32}~%L~uF6Vb{p_I A~O+ңp>FXdO>fEAo ; -}\KD/ٟ*]$ZeʾJ+kTN(#LWBZ\aSY7EDH#Lŵ+ͯ ʟc5B7vn!ӑo!R[jrͪ^|xPbaSq^2 IA*哣uhP/d80-m4_|Flj|*ԅ 7C!%/Ys`A(~(I{PmDh&7| rD/Xɿ_}CS[4sOK0樰A&mVM3\hNa --{bX"(9=מQ;pRi 켢tǏQ{j`IrIJڰԺ$#G\ּ4> ڔI$^5L/*_j5qhp \#k7X|cD9n(ko]Yh'iJOZ#ߐ_fN|Y=~P(OJ'>J|!O| [GeJ^Y@?,.pC6?3ű>'$+_" -6.z2(ڢ={_* -w[/LݝK $Hџar?9~4)?Irp_eV%q5(([>rENE˩{8h檞##-VK9hrȤim}whl -#jLT},D(N_nLf/b}-T3x8Oiej]s2 Ň/ Pho+K[xoR(lbIqK3 -g? Q<;ER7UDO¸>7ߐSwa.Y"eG.|xs<"R)2y6Oה}D7љ"1@&Èoփʃ[@K_uz⫧l8^X ! 4|bp-\Y"_(IG:[6K mNӵ{}?ud$[|~Wa2螂x> @t|2tPo=pLu(xPZ#f@ ~,i+ Ǣj s`acuS&Tg.et3{f }t\߫o D-v, 7#=[ԛ{'ƥ9-kv9-r0}SVfuDL$aWp72\;cTeM :x<{ |oPYEYIHB]uMQ %!ڢ`A]?Лa\7n-)~>C<7 RO w<ʎQX1,`Àz-|h0ݩ60=p|u^hh\~*"˕]Re^b5J2//{>vx޷ ^wnrpɎ0" vnKO|;e|0t,Xf.sOݪz|ki1Ogs龌AQ T VZܗHCcqj=P]RX=9V)qg4Ux뺟`t=j8g!w;a|c^AP$I>R,^-$X>T_uL xU-(rO^J<7Nq{8l}]'ͧy_k"*xoZ~) -B1{.:'å`#|tä9n$6Ws{KQ f;[{4mь Op4)sF`Thye - ݨm?I>W,.> rd{'UQvVGS}&vO:d.KkuF0m.1zKl9dK>nޮ!r=^4rڐNj{d~f{ C"zOQi]htvjUfXgO! forRTk,5$i"Eu.SrV/- &~LcCCF?9]!=~{`l!(X}㝪E)z諈 rJa)p'0,mn?Lez4t,CMj zⴼy:Nt+H`,FZ}~d:k& a ZQ>n1{v0Ne%0X`)1{;rs}pzc/]_D>R|\XIk$eNn$2Cܕ b )1}n\׷5zE_E}1 O՗KXYU|Uu0iwu Hڻ+e8leI?(ɿ,~}&j=S[Z|Äg׷?ز޲z*owuJ5`(d<|RBUT^)^m\YFT W{S}!y+G#-&{PqQ=vT;|YM -y0cjj~R(YQ~ۀnzFmz(ADe`eO,DrQRzpmKoGj8l8BO<ҭM*Ï_ /jQcϕ~ 䔞k/a8* ^I)$Jӌ -,C _(}@62^s_P @'.0Z3zA9X~0-G tS|l.\ƿؼy!z0`\v}-ȃj 1߃^%鍷yA`7WQ9HxE & ::|ph%{~nQ|.^) -/X<APX[La rlE y}VY<TDsRV$H 0?p8Uӡy䬡k$VՖt9BЎw2ze~D9`|.XJyBF{`E'U:AShcc>K|Y~C) k>{T<<|Weʍj&pR76> z_1Q@6*S00Zº(FA<,('I3\pW&C BS*O@H +xG& C^&:>AWpb}ص @PLdbd\zYG6-x E[𸣳 -2)dAAԇS Z!q ^.d_ g傿`6ef; \C#.S_<+cX)xSe4_2"%ڹzưQEn["\Ƞڪ۴"><W- ν5C©=fp\ߕ,h24 =92~*4'2:㥞&T-I.3)CX׎M#LFg LFoeϦ HBdM"eР f(Tz-e6uvm2zglpPS E4kgܫu @%8J]3F#6דB' "6 6O4tOʥDm$XFad_8{u:ŽqaaEqHgA3x,-F 1*]83 g޽p>bQs8_[ ڌq3J2<^pUe̠2s) dp7:mɫ -tcsxbCgxKc_!\ ח <"TD^!xKZD5[lA"E< -59hֲ)zٞn4֗s,cD1KiW1&ΩruvڈY`oü~V\ rCgD#tmĝtƣC)Ϲ:oP=UJHST~~Np`"WS9ι1amD: ; Aqț%KxF$َ:2 g SQG/N&-x-&;U{yҎGqҸAϏE/t-3tPwT娯 J R{yI -)8A$Ec⍴iNÒd1S!+8]Hx&N> x]8%ti/%m#iI>Wi -I<|y}WD1^i;Ye?2Q$;KXH}οCᕭ&%2a1_ke[G/ί$ԘZ\#wEGhfN!?/@s&g7F BM)֖{I?QQ qpch_rU~? %Ae!z- bT7v|0.$(%1yAGZ8su;X%ƱG߳@ArYZM&;ݥB>K -ΈsO -8)C{3KI Ƀ[[+`u{>MbT&>I[z:$=<HQk4 }j;AB$| ,{U>fT%lsn3>ϭg<}&eg|n"8q@*&dSn.|7He>]ss]B}O jx}ލR*$xt0`3ɫP_X'}I΀/N.L _쉕id׬c5 4,>S -V w"4u}ƲxwM-ng_M|LrG>m DavfI8#zHmE$݄o4ft -?z{?nç֧ҞH]r}+Zq(q$lq.D5ϫ;C[;mϊ:? -fŅ[8N@pC6w )6$ڗ3/ nR~\c']k;~jh}Bni3 b8r\qFRpDۚK Mjj,;6:LtO:n1df >Yj2b(j'rl .R.y9͍#}N j`ٚ$ j֝> m jr:bI"Hnl4nkIm܉R}7-̲E)KFr \#w ?%~"y/$ gfdI$ Ǎ#ր^7/oe䇞"IU#R_o4 ]피Ǐ*Uh?!<Fq mI~G56IpR2 -Fnꃊ+8'>QN|B؆ b@@c#0pqP+)4_㧳$[í$JF>Izɡ"}s`58(n[vjPK3IBi@9aۀtf^`~&;78ϩ/'3bnjT ?q<~tcV%?n"HGk$Xy|!?Esv)T"H,~}fc399'1os9 x{X(1[!?րȏo'lΑ'Ѡ"[?\Z߇CCPꚟ.gT\YIdX<ke6AؚRk:){LG{s([+yD}hTPr'UBݣP쟜(&(( [ eQP";vxG[FȟwDdA ^$D78󓸾uy>)%xh::ᓞ[öF@IФg7qOGz/&sc|6--sOL>I%{y{X C2?:{߄4eFsһ$+3?mKPySV 6;(Ï phig?_{!#? -1pvvHL@[z,C~L]fv؀܄ p%l$̝$ Znmr*-C>wH첨UwJ[w^ >2 ,O"PWܸVd9?!PyVx;5zN)j ?~$Ggf$ tJt KA~3eKlB~Ǟ8o{@~<l?ZpSawJ2? )"27qQ âue[z̏H~m6FU yK>~;5Xy0U`WNsQxN@=~D?^8“Iym;bMNJͭp:_?* c#>N:#?yMf_K6``:,m46~LuYAFau$VՉ -' md$*Y0[nNZ\q'*R';,I~."hO몴Q&^q>ǹ60Ï^uP,A:)ݡr#{lӸ?VXCM 9I>u4&~;,Vt -\<2!B+~AJ3MO ?=u STsfϮF~j^:Ůt-,/$&+W;p(+cxtrJq$7+xjI ->AtL:ۓz_B ¡&Ƙ3ܡ* !KF4.U&ȤB1HjZԸgYL֒h$hD]'|h\&'IIC%5; B}N4ͱaWDmGQ㚳 QU?Nd)hz/Mw4(Z$a#5E/FiE^T/z( #QH-FeOjy.XU@GɦC3 9M4oKl ڦ\-\Qj4Nvpهz& T^۔hg^^#o$UF:ZjmlYd{c.3Eۄ}3m!q,&VWhĺ;YmBhEE8Ѧ6m6Dh+)ŠU +FtUH8wPS#3'<.T-򳗕9M~j }Zgi#{h|:`S9Ϻ 8 nZsM - DYb!lZܯDc^g:'ʦu֛!;:'a;Ωߴ%ea 6U iH -'}NwL2o$%Ud` IL5?A|N#&okI-q -AI,=Z:3ݗfl.3t!I xHt}22ҩ#~: Lԛ%B+9ubLKyd +~K=[鲺ӠNs Ʉl&/YqпtJ<xBńg_BN`d vmQfB_X)9J'qHؚv5!-I/5rtRߪON:$U:m4 MOy&͑LGNʚt[5ʕ(>W0 ɨ,.E-$CPi_o?V%jNPBu|1H)t}E^߅5j\©tp/p0*H5ɽ`h_RV-Hinqx~NfzýY!!l!="[lCSbuBx}QVH|M{hj{9D`UJ<:ARK9c2] fyz ј3):\= D*6pRmt FOLU?Ʉ!p)\hP$Xt,a(Sh~vJ~lq1ԯ^5 ZOfFSS WLCL4'~t?U<]X}|LGJJJlyֻJ=ȦE1J{U +ORTE k翰U-[9u2@JQB` ,dB wȹb<MoB+9A-\b,U%39KׯZɘ,@=Ao-X,QV0ϏTXq$Pr/ P'V_,]=VKQaFXsv%KKOXg PKrn(,Y¶4aI1B5]% աK0+P|Cɑv92+C JQK \@on -f~+"V*n.I=s&ӲE fy!)ugqRI2U -_):tWI~%m=zfC7PO|sVquT(0{WWjQj -U9Y¸U -#ʟ9,ix+u[~w&*"_N`IyAKv yvըkŚ/Yt.1ʶ ?mO܄ҪT KLC-Uq"G#BVzɲO 'ڦQXYoJD0TjY \l dg:GꔋIUikBR Ӂ |۩S%`TI&rVRo -9$Xmր%UG>@1VagRmci44k),HrH<@V?<ȥ -3D*P&]jY˿x=]J`/eZR{w]S FB;"}@Gds<%F}9<3NjaǙQ]A(tP]T\%QB/PkP,h828II70LgaeXԡt;x`db5w2vN2UZS"Ӈ7:\>"ӪDw[cު-F8qi e!< ?#$ai>{LJ;m.Ss$o(2梁k._VAsm7k{/T2is|nIVIniux]9ǴQ?o|4 e6BxIX,ϤB`DɲLz]0@؀dmhD`C0jE؝#eRH#r^YeiMpIˋϾ8%TPjY}L;WH0 0N؋2ɆIad!UeT}MyCռJX&:'KLڱ415`,iWJ0P6ІLB6)7,4jLL˶̐,ZӕOlul2%`JL66 -Øo~hܗ6oFo3\/!Vwna:IGՏ&B^r`(^  8nEgR 2MJJdbM/蟆@~-|934V"ӇTRGP#xūGEq,7Ρڎ4{f&_oc%31,eo̧]Ɲ4]!RD)D{k - JQh`C. i24Fz袔S}Q-`ɆQ/)oSpz2~,јv+K1󩋡D >[w]&ԅ8^wYo(b7yKQm`RVTnS@s)2N[V48,_SH!f8Q`6QR8^<xw*rSP`$ǜt_"H4eRPf^GT@Pɚ/Ιb`8G$.J_T'E+]18'E@W <4D  tF\94F= [-WރN]zTi<[f:|FQm˘*jJ0)C N9RѤThr;,è -EX˘YHW' @nXb${3tg}m[ -s-0̊-u&AYG/C#f~t|) wꅵ)L㳹MlfW#f2? \KXU/oyAͨ@!|wY]4K \8'w%j3}4QA:0OoJlTQjL$e*>"pTб? -ʅ3%5yL|j*g03>`Z: iB,*%FZ'=G.UEznQ= >٣2x`>x eUExO`q*]hUzM5X~YGxG̵#Jc_f Ce \AA[ϣ`wT D_%0sTBQƹ)A%::í6Udh0OF2:!I NQ&D&` E's.9*b2YZtĨG/G~4g{mF]!q -ՎGtg@\@:jpj)_Zw z#/GlP]caQ9*(8VSNG`TYkc QMBL7K4vkiv3d7">$c@ԍ4;\uJ%FU7DQE;KDFU%MoT^v0U܋p)B4q!僣*e'arJOypTf/FFs9Q1_ճ+SMrB? 0&6R!neLqmJ_ OllTG3D[_#ƫőy:%GStLMmV9HeL,QQFݙrSDB_1QTJ$ʷ6*67snf[RrtmTyʎAr.ۨصWN5e\*,s4)4*F >Z4 վ:W]*F+> -e4twXʜ=|i9팊D 'xʅ^OaS$TVQzjtHY.5U2bKFy'^GXBʿvXT֨Өz*UB|BU?Sc>/IJr0\Q;ٛԃ@>z?LQu}ϨTi8u?wW倸 -O5*ED {I*'Nնd=Ѩ -)PJʽvԙ{ҢMQudMƨʖ#ꡔ,>ŨNGՋQVf%a1<*IZW们Q5b^ -;B۟}DS.> -Ĩ>42>u`_m~'4ҐScpCQ F[;-M>s{Kekj+ĂڗTQmڐpe/t%jR֞EPCEņu]X1ͺU$*/R -~Vz$Q΄NThCC¨*Ε 4Ϸ?xqTV.JJPJKt/\%zv!b`K9-a10*2AaTBpnF5F\ӲLB;]]:řW`T N!C!/|RW4HD_**-zQƬao8.^a+:CtLaTTpvM|O'ɲxE,8Nb`TN -!ߨʨ2JN&vNvpQfAs2. 5}taTy#t}kl0* -0HcT~hT+P?Oͮ( XR}$U~.]¤QchTʏ[٩ 7Q_5*{(9i~%jȆ,ըPʛOҗU!DCe{Tb,QѠ1 -QɴAB*P5.WF!R+Q)IiT Xܟ^#J()Fu(OS=G&X7JlT5tTzQU61=;r 7t3mT3.H9j=N ;FURJ2֠&mT5By.ȍ*R 0ףEb 'PQHud0 -bONqTZ,gm!=ұs&Y~g Gj+}]u1\%QZsꋓ(R!Jཚo(Nt1!r*YOАJGTFU&"R bS۩$ oִ|+SDDJnv=te2eK3T"uZ'T?TةΪH5Pǘ[7  RY^`}Duq2=#R6J"#aa`pfYk.~=`y H . -#ղ3XZL!3,4E[!ŽT=_FLZHHQ<6RPⴎ2R&lhl0lkPxB6~O fP*hKX7kR2GHGHԜT=VO]~CI+``{R1K~IťS ~ -O -n>m?U@O6eI -Tfr֞K>6{EIU @h -QD'Յ-'I%ŕ|0gЁl'k,KOi)'ո^#vIxRcemfT5Sk T<p'LNT H BRkӻWOT&*wNnŻHsVAV8=k`]`ToO>3{WC>R'F6L¶RϡXpfJU=J[xnNQ(˕ي ^r [[JEF;h,W+F4yC~Z uW_'7 h+ɕʭ}3VJD7kGKG%W*.B:]\lR͞h30JfP$w(gW١NeJUӷ),ym)>lX*@^3KK5$[,U@OkvX*u^~d^C:&BK&7y⍋G+)Lޕ*Jy,G̲\4/~uAdžQkF sҕ*W3JmU泖 W*=/W/5dtPT5IG'SFc"-[hogW(7\J?~aJE5I@g{ kRVX+p!RՓ`0-Nt5MJv -ɒ^$6a[q9Jh$@j \SLu0S]= -E*6T6**)j#+{U2U콫 -"`j?.ckfX\\MLEROTV,a1uB ]wE^6*rNI/e7 -Q4֤UL: %*? L`".-a=딉1TDq&kh{S%O]YVa*FqY..Ɗ`mF~<:88TQf -J(6"TI$"*B<v3}BA*s[&Lu 3+R|,yTS y}S6a(,JG{M檢[C`MKKjn֑̅NNOJ{y|Pј6jd2&n.T?$S?s4#Sg`B|SaJ|+!2UFFySjuR3EDT*2zL87 od*<]b2%>xCA.MsŝLeq[J(DYY[CŽd$e݂61\}}B`#S vI2ʔHTVu]ºL%__@F,S5gOe*e@HȐ( Yʎ6)YEw^LEi'&;[4L@L%BS=Ú6."X76SV$S M9sɺC0*_+mw!S)7R%h-$S!"o7ߐ ivŒH8 SϠ&f̈Sl d*l^X4e*pB(m -T*{ާz{1&]yߧ{N򩨣Vc)3ȧ2,mYS5 g [Te6.A -F -u"f6r Чb3slKg}0:rOU -n~X*#cwS/<&B4WTg J`5Y ,D!%_{? ON <HZ/# P OBöɑҔSԶ`6T`Tp}*mjth#P^? a^ʥowW\;Ɓ*"7J#Q@M2,'iz -ToH<*UBiJ˹;[Pe(_6KURjʔ=js%ӬcztTuhU,]+X*A__|o w8QN^AJK΍:#JA٠o2KGOaa|XB\80ۛg0"w|§ǃ*Ȫ;mJ4%4 -2rCp&rAeXQPUɿzq%QCCf厨1LWa yѿT5&gu^z硬FKx'%x`VP 㭆ʥ)հ U q͎pP65KTsd!PhEIqPYF) C/Sz+~ U{˿PUF/{B*s`5Fh7gⅩtiCQ R|CU_[Q>Gsy6]; yJlS0 w?PDe */DTR1C/UO=K)h$ɂDU?=!VT`%3:T; JPˇK"D CU5׋ ҡz~eo:ӎCUl]! ވڀqv5\  ٫)*4DTuɯm0g{ lc -Hc L1*SB @Tm:Z$Ń|r BT Pb|EoBp}&hӁFφ~vUT%qQՍی­㹗U(J4G !WŰ ċ KEcEU>U?aV屙y:[;E-DUE1DkM-X*dC#5U,P{'-mUn꿇s*+2x+&~ -P5Q)qA%cD 2JG8˩1v1+#ˠ):Rb`CTDx~=~_DW[En %q -;cS]l EнpX2N&䍪ĥKTUL s - p^)9T)-,MyC,l**h>Utj$*I̋%Q aEh?E^WWS5S Ii0e`KD[W$}[ATqmPXء ʋr?ƵÄ2з&|U/}hɍމ1KOTg.HTeL-;rIՏFˌ-%IXzFR$S**%Ļs֜_VY^N &GQ -5lF>S{*y$NUMIYyi%vQ*-FNG]R -L/Ȧ*XD -XbsÆB1o<"Ŭ1vT;9f]ZX쐊 -R]̩AlT(y-"RE7_ ڶBiI#է` ~;ըxY_8T݇jPhT%篐K>S"F3ި"Q>6i -.rTVP2qrGՉSwKkTA+9**] g ]UTxרJy ->f cFFUN E Nu<Kvx2ֶ܊PKKTM,׉_CiG,|N`(ְqN?EW 7͟*bӲ%SW*G`s[©0ʍbL;EeF`é?eV͈EP*&d5=?kQ[E72<DŽ26n3kIl#} /mU/0(Cp @X{ӊ\P]»kjU -F>jݨ2RƁMy*s0y.`!|(-X*5["cPrDn)VUlVuZ)҆XPsX9K$Yf.G٤!_F0d&}1ج,ymxdTkD~Fw7<DbGC﯂ ݆ď ??8c+P : /;[6D3gkT9F`8ejQ$B5J91wi;2-ttBZ@]<*NL blVҢ-<؇*eέ/.Cv#p+Fgj9 $F|z6(nl}&րVFo猪uB FU@3MhT1hTDMT&Bۨ2 -{xQMu nT!/ojcH iרr7?Ԧ5€(Y܉ 1O> iTUW?& E -xm}0"C F[$FUn˙4JIPjB6v&O؞ aQE#S=;՞[{=Y UT;uƢ!w__BUq/s7s  VΠy.\j=BUQ*6̈́*{\8k0YPU/!$Taafi@Z{hD#tB2 U=@ ഀM*ٟ4'T)߽~ata=$k.6rk-Bo^F%Ta]P$Hr@hJaP6`}P3Yi.:X U^S(:U]~n3"B 2P:/gȢK<5QVԗY$Ne:= -lЪrS#{x}ņ -h PK^3~[ߵ%s% aIdt`2DYrz9 YTxf>rRWW/BVC0B+]%<3E)1 T5РWI]2X::U/'|1 83:8o)P̨rO/ LlX85/,SN/ɂϝaA_ot{M[E5Ǹ쳓.sddxȤjɢ1 5lSL_T2.AzC jR)N.}MB3AO\^xL/zUkV -!wIwIͱj H3+qIz4Nf|^ֳUEZ`hmI H6e^ -YHChFCKRSC!oJY(VZKVv$1Gy7 az W!OcnϫyLX!s -`fEc #TyaPJCa(W泭wBs$W(/ ?:N2L!([Bq L`~h`tB)0ٰ7]aYn5\WL1\_.*t-AbG%Yw}' xrG4Ziuzl*c"̅EĴqSlMh ᥂(mB2 T=m8 !D-ܬB?z29)G8"Kt"'$ |ǫIWR9#!a"!'2,qxOٮ!VLLDl!Ab8"kMlD&"B= l -X6d}")&gQys C W(}bsIJ yaĈ!ZV ōfѼd!y##e;AFB4fiHJavʧv_ʦY1Mf|o\&:t&80BC'/ V!DhJ1BM8wtBY94lW8ÿZBGZC}9_SN2&2!= >H%QԜ0Fqqr_t٣|}L_d(e(/CSN"7X! r؂فSŠh, :'!l.? %\qW.< Ce!aX\wU[8b}YB>{Oa k1.фBA0GHnB&2HQMɇ'aT!ӄwXB =jF5keNVd)6A;]q,% wJl9Hyv.LqhNaYϙ_?p>o EbJ(_UV9-ے/#)lcל0삦JKMI b'/-X=,KH'hsGRqҊ?n#P#0\Q} l?{oN[؎yr VJt_:p)4?9~EfNeB411Ä"+4Fq11ęGߒ\Pe_cs3ERH0`9'/&a>H(5\=8!fYDFi|% CPjvJ/i\i] RL=_8LR|TTE=QDTcaqʼn|_L A c04י'C$ -JJm~\t/Ƿ -fTG`E5 . 3 `\zoT2vC'::@G" Z;ӼIck¦+gh># \oh}oap AvJ?f+*,a5)E;05IhVmqU?b .?A*y 댸 jXTy2(VcPNQV@Zl .( dBW`'pb950\$ ~GY\[B ."EJm-U㩐ŽЅHtpV?LWA /eU^^z[pO^bٙz+ ..kB1UE -Ba dZeVȣ/eKG"o@*Rx0G/w} z0ĊSV/ .8%A .){\ bIEHT]pF)F?T蹩~cLFF&|(xv-cJE\%琾73.,\_Pcr^˄@6 .`]ZQPѕecpTTXZj@[,\p!C(̑ -ne{2%D .ʗ7eq4>1u -%ȬA8)G*D "&SHܩZw8Kvi:G*P nռ\`ySq>S -h:^@1 s6q"Gs?C=jTF5>p3x?!=pz\&0`".0剩`3rayG\EGNŭ$z7TH{o;prVoU\c)*GQt'\@$GGA7(ɍ |b{eZTpP *@N.ib~q 0I3Z -\IFgTЊo5FVaN#dllu5)oq{5*v8o.nd.BS7\ֳQATzn$89.=Pqn6*t8UKLu! D\,2Fŧ5QLȤU E-ب y^|R p -@] \,ĺ g.PNXPs1q!t {ڨ`[=] \v]POnTSm{%pѧG (ۃ`pE'(*9 !pޣN7*h.Hq&W-p١m!%*{{-q'k;7p9=|tH1M+/p1$kP*pU "\PC1Bɗ`"[.>UBOr:&|J ~.Rp֊6pad#KrXi:Trひ)-\YBRZ5Y\9 \p`KV~sLa,.j1z$6<]Y]4Q\8EF>v"`g;66IgtmT>W ڼ|ȥ1 ߩ|bd( ) \)'8.i'v]A-BSHS"|l8ZP\rSJA{ q.Z<:pA`p.3 k h3T{\ʟnr$.d53oϹK2s) PYnJ2L\]]KC} R 7V]/3bW79r(;gs6Grv F?.6E"Z sBʵCB7؃^E?ۍ%hEhwF,GM@yȺbBiC6nBހ{rT.sC4g^nҍ~?Ժ0 (h(5srR槎㊚p!Wer,QD - \6Qb#@x, \0=/5z;8n"c4_QP -~&ř%UQߦڸ`VP$J hϚGe_ nx \XS.]\a,ʵe3Ԑ; ۾-!9ʨ ;Nb\SLhZn,Z/$gN A\3uLNM;d)*Lp}hoA  /iDm"lS&G_)dɾ;d[BK3e : \ҺLE<.|xvud`qT~ ڂH pJ ɰE鍶#F[^lMh^ IA=eΫM ddCo1 1T1"t+SDYs_'=\kb_|s .9_h0xŜډ|Y+-s{6Xq, ik 9&|KB6A4́pYWBp!=Dp!:%@T_اC 3L&o3f\Uk.wyr \( ΦA8yٻKtvyeKcs 5Gm0sE%(=Ľ \4Pr!NDPA\>30\xa ^žWjs )c'T0Vs *ʫswZ-%LFK:Y˭sE6fp )F9>ZJJjndŇB1+A -N`eֈ5KOUQXp`O0`%zOp}Udؕx.] 4h Lӑ%mХʉȣ% V33%KX?h Xi]b%h S.?W(@p#ctnahU=&pADL҇pQj ( @hv&5W.H}$K@V)mD?ԕ ַE;㰕0Ȝc%$-zE߂I `?K+!ORE^J@wesz3'+rh䰱S:qt 6TyGhX֞KwR-dT=\Vᄱeg>o!6w0m !hʱR_ sY஠Ղ;z]\ۓ39A '/}j2LNN KȸrD,"Uh?§Sdf-.  nQMD*r6`(1v}^Xһa;bPv"vů#R 5\~ %I8k+S4%,gꪠQƉ)>+>(W_vArÂ: 9m,  =Fl U }ʓcԌ{:x$k[^"[tAPV=EЌyv_|v2I8!ϓVޒ΅fm["ſEpdo  HlI+%ϹXvyz, 0S p(yY ֈ N׻S!Sm1hOVMOUB+)GGhpGQw"B;Lb/F/,U*1Q?};qE[JSpQ7 P%.b}丷jv>Ϫğ &bՃQBj恧1XJ.I\nȨB4Gmf9;L ", 0p"!-3SfM>! ij3ell\76!l{Y$ V}Vm?])tōަźUKK@fۂA-zok @-mK3o=6H-ځݙe~ ,8]|EoѠ1(o}8h|aˬ"8ƞ斔s߂^pk!PnѥmVo$wh2ɲÓ}H/YNʂcHDhX$fa1oW?` -RZeuTE ._t[ [RDz"g,G9v zP^ -ePCI/w7&4j[ixsRx}X 틄ʵ -{9ֿ[LY< VlJ̷ȁ݋@~Ҷz Ou"-4/B_O/[|>So ie<3kޥL`U!P8Ct&:PdZ |Db|1rףoD1o V#pcqvзe6ߡoah 6&_ ,אJ߂At-VY#( QmrI[ˈݠ3A0N{毻f p+.א3Olߩo>"}ԛp 4y poARo_6` s[@Fd\U`r;YUY 0p/~i JXҎc%*Œeߧot»<  ܤhΞ3&-jhk$5q8tu}?}sHKnT[o 11KƎ{T-p//jזK -ѱnQ܎$ CTJ$IB2݀ |kE[4-NPWnE@wRUD˾(J`T6#LOVoZSN4[D$[I%&> Nߢ{4hI;kl(qWT9,Dƛ]3ɚ߂Dw50:b,7ެ r1D ү>"*I hAg8r1>p~K#-w#hoמu s->duC{JNuFKXσ)m{ -C}t'Uc{p%RmȜv}\i[DNG;DgTEcF#$py0fdW`o@ bc[iy uJy<[<-ulU?j-(w5Zm$Ddhyp.,j-22jnyhyP2&jS( --RM0D[0o:7xgywHbo G\,^(rO3°n`Oa[foAa,eQqF:-Iq[@Qf߯;' F(L oq7{dgyqdUv-pΟ_J r(''!5"ۧPZϬX=83A uLuB4ϑ_Xf{%z8Eu*>#;ښc=gDvye^2-(eD)&o"m%Z7inAG\-YP`Q`DEn8g r}9^CBſoI oA71%ʃ~APiFU j$J[,~.z 3M[SE2Ƣ[8(G w;BG3]A{WBϴ+6% &lxE6L[=vGŁ[/ؙoWUogx@n` &g@o"mzELڂv-&-$!^UjiZԵ 3`+a16-)ja0?-VIZ 6Zxe0E Ȝ0(6agQ. &M9gэfQ~5 3 0_8e15 -qb+ -eP85xvB" =pcCc1Ћ #[h05r¼ЌB ѩ 4BJҙ!`bZ S p+죰_XaL_&^4B"P -z -6æŸ&VO]Ɨ+ `B(HU3k&kgz+VVpߔ_+JՊL+VVVTg0fErt -d=V0bEP{L6,j -SUTU˯P|ȲfQ\XxVQ­a-*6iW=2S,)ͬ="3`H3GBК56tu3]fPL 鉒ЙQTg6;waLg])yc)H@0ETa`Y(Ղ)gAy kGg3Dt\P%g'AG~iyaK;fg;h,_r`2 aJ #asUw+Gg; -ISlbk}m=L1d X;ZۥHY")| -g^,fؠRR8퓢SbaI1e$Y#pD -!e? -E=ol=;EQ(`Cm(j(ugBg(V?3RM}VJr" -Hޡ{CXb E -;,oPR }BL[JEcɂg -43.bvB\u֟hg?arD5 -A |O`=LO4ҳ= %h>wBN# \P ''аs'mj'; h ˀ֫tB^tBsʉCNM ?83mdp°DKo"𺉃@M6Ah?$kk!,r\'}jMlhhVmFFMtp&z3ш4ёfE4[C3?}h:]{hD-3?yL Xv3 MLtPѺ%O\K~i6B.yfAF$hoF%ԓB7hPϗI JQĦPr%/F/V`r^By,ox%hHgrg-e>P? Kl}%86gg?b%bJ4؊Ub+@&4 -|~V lo@ 0G-wTW -{9R@7,raD "+hOЦG hvĉL%bMܟ?+S d4JTVu ?8>4|*12QМhvP%cS meJ> 44'hYLO)Qhc+%V=s]Zm;4(%&"\Es& (w?FIќDG$ ͕1Ҡ^$'+5Riɯ$. dJ«9×]@!L۔$k]$IA :呸4G[6H0?j]$H )*]bwԾ I͝C"_jĩS qjHv $xHȭ5V#|kt"{ ڪG GZ\V#[Ŏju9=GtXfd5ypYz#7]ǵly?84ͮ)ӈXgDߟXfDgA]+*#r5VQ,{_ [0Ŧ؀~;9P]\Qnmq.b[E8.+ִ"gEܚl**Ll~ر :Nl"r&8&ln-w/a>]I" !<[э@v&B$ܴ"!BLMBm?G!<Ѷk: -IhɔCpX65n7[jn>a(nWmtOw Q߭MorcdsC4aj=ߠ4P,0 zY1i!rqCDuߤ憐)| CM7nvHr7훵Po~-7V@z憨4p7Ĵ\Wp֧~#\'r: gNB\ qM}8-kr< b!tAD"[,$/#'3xDy '  6I6:AJu>qA!'.\ENy$)U `St% .P-~Bi B B0՛Z \31?)qMVD|. qO 81K=-aKC6eQ1)DpA@;q' --.Np;S? FrTd99_^^*%.9} ?9rZ%+<8]d95mr}˽BY^AvH,3sĬhNjN4ӛ /! 4>YX^uΉ(?exAqgi~w^4$pm Vɢs*%8G =Һ+:2x)IAе#KP-bdK[bEIV[A:I)r~f [GIEV : usA@å˶d>Կ }Bb8x4!_ ;סse5Ah's -DA2sp-s -˸ -DcΉWK@y s 3;?B]ʀ3,D_cm=tz;9Ap9!  - lJ7 !¥+A􇦛tCO~h:[EX}MGuƪCW1]^ $=|j2) aCP`Ie@-!'|PKWP|'Xvzh:Z_!m$ P=L^NV+zBØaoyX<֓#}&?U#YVne3;$(~Xpl:Eji]uHCBfA,`]wvnG˺Y::Mʧ:Ayl;MypXH|QB`-3}|խ{uq#%I -T؞w L:W7 (x -` ;o+|vz(Qq EN>E+|v|A]re}AV|.Aoa3O #˰ќ 1?'>c2Pŗ)C,.G W/XeXH216) RdX:MJF2JjPE hn",+ )~ Wc8`)hSV3BbgݪwU :Q }G#Ф})O!a*D. S) Q% tA8yB}o}U0Уo`83Cw I} J{/{ b/ 1L/|}:/Y)/Do.^h'xw%܅.ݾx]8ZuPW r&c2O$N..; zKU\P\Tf .ŷ[knAVo-nkzۇ -V7MVp+VXM/ɫt\5Z/_h - -jUmܝ -Bܘ}80Km7N1T> -9beC24~wj1fsl- !ܾ5$Q̢ξVvبS2T@[IŵWz:bs -\*(ȡ-Rx¢77Nt|7KlCL}P|wSX*k&- *#~ډ*QdksĚPqh/cR 4}ᠶP!? y -oPQU?hy -8i_: ][[:k -)SRxҾ, T)LB)`l}%C -<VHaCj~$s@`(‡EAjg}FhEmG -]Bt7 ((k(O{ >@[['LEpf}}X)Kua k/` Mk87s N؄/]}jBN5M  tK G.% }2ADa!&Kپx ,.@x۾Y-aYB4,] lWT } 륄 ,%\(!F(A'_N&MBL+ ' rMI(pX-#0P:Drߊ!A'Fi?HR A'U';a#} ᾍ0m(<%#Թ/Nٰb<"އ]EEL W̋@b~&m/BR`)"Y-Ȫ;.gE}e"Rx  "$TRP>;!OMyO^7|(aMwQ"$#aol!йL/@AH@@=} v<|B]}!L~O5rmry$ϖIC/P>xᄡE/ y16J.ޗE**޷A)>Bi ၄sji{>{2ާxn5̓5"[ZkVkʛ!p `v!\Bp&pcA'7!+,߇=ɊsGd/  s N$4<'@@<@[XZ+$O~sy B*f85|$4>M|Hn=B7A > A T^swy<8rǏq`Bqp0Y8P[߀opzkxA7 Zm4 &2fkD } 5\k5nTI,8i0~aO~Là֯=?jXIwcǏg@ H#?Ā ̌N#$IC T`%1ۈsr"=s_K~DJ~2LɏW!g18iTaIJ_ (ZsI~Pf/K~fM~4{!IV -5H# 0@dO>` Q, -'+8SȰKWcşpQj ~` |A+(?2^0UHMa|gRiv/Jp/890[H,Y4 F ` ?] 炮rAS~SA-fm+&kc-P~ӂN+Z`6Agfо-~3Ƃ&.8, -°‚X*WbH ]N^R6U%ެ`SA`T .T* ^IL)VR`J -ThI -HFJS9 }kDMz'8h$O`>dڟ?><['x3iNp@/V7lұ 5gW*#3ufV`z 2% $3O #RGTGn{sH1)~nڠC$$AR@8{k#@dFFEpir%nB>GTB.ORA69~h0?_,+Nxa։ -AQA Ј@1˯cN|7&yaR- 3@SBՁ Dʏ9Oj)4^B@7[~7p]7g$ >yl_,˛FC&1h1%Z97E=D Cw|4X,~aB94+bOv"bW7J."c8:T,.(׹>|ĂVJ\VЕb0l -qF@ γXA -;iaxNlEJ+8{H y'H[(\Lx!LE]É8g|8 8tezZrk{W.hG@Drt2 -|6dO0BęD\A$, F)ʯܥxHr-'415ᬗ(D3~kT ^&>@M -2/kR?23%5-y4wzF7ٰ=; ctl TBZ{ Bm{ L-V%:<_&'j\r`]Lܲ`+;gx 6H(I,(zaZ >)ԟAtP^#~%!/$~QFIg|(AiuiGEY>\'kܚ)t4'Nf(@tPD]Sxq1̊m\hvNo@Hҗ)hC7']d8= Yt/KI~Zଡ@ȭC7e`(Om$s¢9b` -V ~8LGn/,LKbҭ⏡h}{PjEh2\ -рjnn_< z@7ELg,͹4]]5^.쳗]+Vfu|zG47#u<82w!izfꅴz+Yk2tYWѪ<+"VǾ?se>%vL]Y}J:ݘ[R [.ߙtgH&s%UY%olxs"OcŶX35͙eŲ~6iNԤV԰5ᰆf36% +C nsB$͆19,c;iHsͽ^8fq&B#FQQf2h”kgwHN V%Bӑ9>iאMJQ6c4表6&8 -%DNUccbEuj՚5ӧ qdq (`(uBlnďָP@gVL ($1 C ( -8,p P@j@`൪_Ix:b,jHͺ]dRCSM;Ԍ C~3yENUM*D"Rny) Ӝ3|ܩf<9&MMu۩3GGr\F:c-:shΐV̏wCv7f7"&ȞxWcی# KeeY^1eFF>m!׬n!k_8I\ݰ 30`#RT]Yz EilD[H^)VT1W3sEQ> =jKURӚT1'kΣ1B(DH <x&faQ jMa\¾k S]XRݏJFRAIkP֢XBg)!H CjŒ2H'b_ endstream endobj 20 0 obj <>stream -^ꝽxqUq.K,ŕ/!gX*nl@HF"K=qЧ`(/>(jĬ4%\p0Ht"q+Y;8~[b;3!mF* 2jsAܺ]`oz%nmj(~&QaT/3?%V2  AC5_Iۻ5f - 5\u4Љ?ӃHf%AtΚXv}ʠTr-Du㺚p} FI,bФ;VMd&B(D"⨆ buPApY*T|<Ս,u&)(vGƉ,aFq  |u(~tV{xy"ƆrЃe.5"샬8xW Yj'"S7PMģ/LЦLsgxC1qh~41f^9(xKHIچҦIxD@tbB_*R@eAB/K/̸*Qez&&eGuK^B x _Ę>l 4 S{BjJsH,v, Ч9W;B.">$k !^̚BQMI2 -Ko8aZ̰WQa)?i$rӯ*%ؐ }=VOklK ƿcaJiW~u$lܗP~͠" Y$;hIR͎4>&(f31\ KlysH *-ƅ4b^Y\p}ਔDZeq+o jOxx{8yHG\4 -[dOnEc3D (c|2m "(E# f -@fܠD ʇ,9㩍 )1Gō3~\,xD-&z]AoXO (mIf`q b2A#g"X2doC4EC\o,[J' -\q\W)mݨ1yB!âlQE mDum0{H<0~{vVYt`qmVR:} (!6"f֖ -#t[墸)g"6O&΢ۉx-bW Q歀uH )2IXLnsf2l)챉1xxu6'5jݨpUr@#sD8Zp]7I`|f.巒ۑugr5S -μ֜ wOvnSBNuùXe'xH6Ǯ|7v,2Tn1] <|`q_^J3`b,UR1fHraaTmo(z>*CÛ^TlgoocyoD0OiqK63)g(45ěߡ~Bgr"p@g&thOSM bnFec6}Eޭ>6FxWyBb;&!@$6zXB|"u|9UO7XnK*Ai`[8'4aWSb4aҾ]e\/T-aӁ]GK0@v7'%U I0 9U힖Rr[gJTk ƩyQ(VC%FF{r!啢~$/j4脴2,r(L6'nBSy4CŻrlϟO+ N 3-!p` gwO`B:\VkUۊa{it]>qO(RTsۙ^"@`ҍ=/8O`T8F7MasȵXm{8)jI=l%;f_'WE_|ـf0N >'%8RR6+z{rE3cXQ u($@".mpƈp^݄l2'RBTŮ hTrS8ZVbOs0=IJg섬_=Bd8@RPDN0O )#rvN&QpոҴI4k5adZ4/\``<*km^&QY8g_t]FZe1 i;R]'_!4Os%c/Ih HAa1z+݉ĺz -frIT5UԊnW a|hC8kZ"83Rn0RN_iE2Z.u&}SeA,< ooLtJDMehv\PΥ2(K94ae7)3= -xp1`6p꜋ mŧ -׏9zjPT!qkVR$R9|ömc:*B>#Dz~7ɠ)ȡop(%^=.Lt>4$`"# a8pk=(ܱSh NlZb0O聂?*sp擐ɸָݵPC멤0] 0r& -G3ԭCDQJ!7)deh'uDo R 9.Я$L»5nICk]K |\.캲Ah{|ϩ6((i\R4U7^S^<29yos\-B8ⳃIKbiq_\rl]5) lEC&]MoSob1_u5}h.7xUq1X"i)З$p9@Kw7(I#|ח lxK($Fw+ߑ<&IA;\ʅ$6@>I oF w[n>90j1OSF][_NrU@vYq{a9 U">$w^>7_ӣKrFb2Vlg<9"[*?>8.YAz).SCwa)[FF#[LqF7J vy>aߡe0PYF0z@װvXjDMjt}lLB6Kf,܆ /U𙯲)ڿ>a/2LSd:1y%͛ 梏uljJ -^;jAӮ3J<` RA#uT[7l܎gR&: GV&F'h-eubΩBΘ~7@/6g{"Jу|?DNa8 txO DD0' T #W2MV/lA}醬A2e g Z$8MOL[odLVy2dLƃ: zNB3VoBmbБ -=XDx|lҎ%9OVfTC?pHm$=%` ๆ+0=$ v^c+a+<\Q֔Ny3X7 & aѣauQA9XJ;m0nzѶĽ hJ}&S0G)P}U˖$(?qZ+وޅp2w1=ζThw;-2+D@r/wd(LOfu* >TlFiG,͟{/ 7Sk3a%Hw4Iluo_DK7FNCa}?Us{y%JDOl+>1Ӧ%h'%8, -v$!M"bZaR&9G' * -/x `KxYy_m*&$ѣ_Q̏*n !$BK\烨lj6eJ4ѐS!1.4n=yO<`ٵ{#*,@z2z .f B ;GZ-첂2{߻shlK1J)+UOA V&"P5T#BW<⋩;Cu3 - `:ac_U;=9BDY P~b|߭,^Z﫼4?1Bp4~3HxjI!p>cxm֡Pz}.Eo{q|-(CyO\G/m`}$4aT; - E -C {ChOvM0lcb  #|b /0 c/3DmYa&=qȩT|_Uw!XO%hJEq!Eq?` h43հm0aȶ|BۢOjƇa;S 0YN K Eakk bkcΈmpcTUƃ.JckX @(-5L} ذa4 {Oo-iFK۵0H8+_` -X [0.ХsB^;"囡qE g\Zxa2DbͰg d> #4.|#fθB 4Lj4.N02a̙>ahJamyj}v7+)0raJgl|~ؙ bbXbĸ?$[%Lb{8ńuj8Nr{ָPbظEl̩nL~c3g83&oEyc v:VXjLÍ p;o 2clLcqAkdgX)z$c %`@2}K'ӴOPVqeEC3e@ToXea  ]],q! -=tYYFk.ko^tBLsee5YmV[ЙL3,DžЪ7q\ٌcҭ738s.9DTF k:n\:;wN t3OϜ{m[eg׸8.,Z q9+To4|P@6,@s?Ϳq?>ς َ")XC3H5li/rmWܳ2-}*䦱v*pr@y }6 @!lq4{e\h -x,rĚJM^v 4Pƅ5%+θNFh9|ĥq1+"4B ]eoQgmAۣq`~YQ5z-ai!/@дR?3 - )N|- ЪZw\hkdB;ٸ?}вd',U2ShB5.$GTRU>U+24М'*^zg44]q1xES^ƅ 6`bF qRDCx37.xD?[hoqqDI$Y|2SA植 HaN24"> ޸`eU ږ6.VaކЎrl6.C#Ը(JVLj\1&N CBNh -ٸ81"#oyBc -Kڸ5n)4BUWh~Th ]#5MWhnnڴ -hqRTԄUh -`C۷Co?4mhȘ`\`,Z¨&i^KDhRVh.vbچ6..{Zlhj?4D _\(J-%`\6ZlvDH$M4GiIVQ--ҢL[A~ 9 diDiƍPQ^;R;C -HMM}}jԍjTFVVmW{:CX1cMVyp5|9֘A1.>khZlݚfG/uk1Et)|Mc (ņθIKFU[6d6VEqmlیGҸxl[l͸(df3#FfK3f{c\[4hVϦqAmu!;VjK=TmXۀbmmHx#6Zҷ5pg:B=n0)F2.n]u~m͸fe\Lz7y[7Mzrܛɷ`}Ÿ/DCiY~bc ˟pņ`\ݚ71o [Bk}BC } :(E ͝ (.C87ExTt]8J6Á{ 7N BCrn Z,c!_q1lW'.q@&Ac'ΰvj)q :qOB Swz..f1vǭ..W\)^q[SQp]\{Nqᄌ)nŅ58c\ V8nq,)[ZũFиȆǸAX\Cxb(E3 qL/C߈'j e }Iα1[\jE}>TY\DpJ"˲ħ3!Vs.g[l,.("E..bX) yq,.ŽOƅv%D-]-CHg88xbEŵj(ilw - -P̊rir^ chqf^/`Ņ|vś+[[ @-.bqqr$K^ 99ΕkcmgN&:?'@saSS8=LDW~j=G E׸b)]ĹE\Q,:viѱEH/:k%:e%n"_Ņ"ueDWѵVR\pG:BtkQs.x N -xnB3EԅpEɈ -DR\̢qTa أ_ w8>ފ9]d`:] ]g߂?" -m,:jt>:y3kV\Y5H2s:>> uQK:u`ե(.c[C[{œt E9V'!:EuxHVHHq1:tt뀣 -dhgt&t*mY\\PuIe#0DX\HJ0[<4 t{{ p)$Sq0iWny]oQ$(.EM\U* %NݢD\4) мy^wuNcBlՑ)(..$pbi|?Hx2Oz9]#`=pɮS8\p{Rr0 c{u -Ի̹ÅI{xT4N.ⰃP1t gz jn`>\d\cVp\W -O`'awDqĎ\j>0=>OG;]PY;ٶ,So~;w s?\rܙG\N|-dH\mww ;o_Km;w!J؏).FqiOkFH -Bq~羈`J<<'/xyo?q@D!'P\,'^ě'.OQ ^$`C xy{>"f3dZ<}=qqu]@^ڈSVz ({;).!wjDf/Nq!#>gW󛏏ɑ%TMn>$DIBQ_n곿և. -N\xAڷ-} 9I)Vߢ!Oȉܑɑ5-c#߂O gU"}ֹ-j_>?0i;[t8ԿjzcGilH;t4L42} A9G w-Duop& :KC[=[}>/>svG} vj.X3 HV|#^)yOgdĿ}l. -|}&x㶏ܾO .6+O AzٔJ}XFDzsga\R z~pߧӝ9$_I˘0}AU+cg,qF>4{\$!   /Ffd}gS fkB>>B \@{k<~E, 6|3ypщ%TԲϵOlbݚJW~p)}'(RGj_0Nj8V1u+/o\Djy BiX*<:nu\]RkېefRt.h=*wieR&Sm)L[pQ}7""%E=1[T\h}z0$ Ѵo:b -<3eG/5 .Z3|ߵo͟G/'߂ 6}k~芦 ׬]2Ռ6\9 Wءmߴ>~\Jer G4>; Ra2?'I.-j.(\Ht \D-2\ٚץ/q T4R33v 6صW=&aKnJ6 '2? / .vg?ϳI>L?\`MEr B\X]pN9=ϐ0HQ ^M \ .lV\op} -  6!Y/O2#y_yHEӼh!j{~=\`\xm%dUеࢰG!tﻷ}ZĻq@@,!}{_If|P>N}K)Q^oP8}eY©/Z)~omPQ -./êd\98vN`_+NoLG3CgK1< ~w%p O\V:)@ .^`s z!bzE,CER㿒b9 -.vD~9"!ܙ@ŏ,\bFpCDK 7.z,R .~#)p{ D6N.45 E޳ɔ0pA3R~ eߺ^\BA \`R쁋.d#1n-N ؈-R إDaD.XG:pRFN0oـ .rZ p!8S.6,{~?hEw9 \05 ?/,27[9w%  fw9x˫ .\R'p[P?Ҁ pmW\^ ?/'pR HEb2S.feb.ZJF.>~"WFv* >[,#? - .5sBH߀ o(I̒b;(P` . P '.'+-䗨qlK~ _S6P]'?BR |_V׼  ČGpQfU~ńo pTt(s!-D4eVn[/>)0| pЪࢅY*?C%xAQOMxY~D~V~ pE 8L8B.npR-/ tyۦrcYUREdrR~zH"pV͠6 IhЀlrxH+?*lZgWpa÷ 3?O>!D~%d~-E!-48oV"{hѾp -E޷ȎzH[=0>SU0!3`־Uf}<g49K[{γ@ mE(JoQY)0/mOtַ]Xt} Ѭoqod i} /-} q.?Q"{-KO\~m"ameg["{f]-rGĈ"v hf= [\( J#"QE;ɯ@+uD-ZϠ[ T.Cor2(BZ[x~jp'& 斡4񁀇[n 1\-8ISK-g8Y#{wov`[C nTDά0B:YIeҿ1@q^-X~%aB}s~[MDxiUB߁jV[]Á2lp*T" mQ.(I&m[D ]p >aobAbV [ C26RB "d jF.S~=X[͗^:>CGQ_ڿ_C;)Mq3X9$zpA"ScPd|o3KSJ̮o[{B@oҍ,+kSNߢc>Ћ'T{7uKw ~[>Š ` yn̿WB;"-_JвZ\ı!:/J7Nhj)-їwcԿENq'_IY[쎖O ̞^?ʹ\-eS95Y A-%LQoqDK*JJa'ԣ5@ F7XKE~M軰I-"[$!) FHo~ Β#%m~0IbF8WmZKJH&ӎ/Y/]ߡhB -fH pzzo~qsJ Tе +s Lx`<})\"\ #x/ai*E0K}A Ic"(!?fk4̻:x}QM}Uf p4d Lʓ\M!EYv|rJP5C!>\7m@Az7|o$n&Fc\dʷP>;( ඀б9<8݄(][qKSH{Q#U>k.xXZ@%+ghVTk&+!=\*W^mpulb.PC圹+9WW;ݡ @ 3f0XSKhA40A 3^r!!C50B vj+lգ# \L!*[!`QAE f 7 a+J=W^m\DO+h>0࢘k}-8P -ޚ TWp -%Tfй9 9h #d?tvA!ң&,Ep6"ߚj> -a]!vU(.gt.4_\Q..kڪm0mzo -." -ҥ"y t}T{\}OZ hD!όX0Xpi=\4W5h[pq +o/]k{ b^-4 z5 z)G]|޳UVd[%Hgj .~WBڲ"bܧZp&UwYҗ.T-.Te]y,++0_#Q_W_09b̠}a1 ҅ aJze¾D_p-ȤVӝyĻrP.][ -0?d,]Ћ9kZ1L3&$F=+X҅yiqnykԻĀeıewҗ -xlpfA@ op1}BHNtR.\Bg\.E鹰ZBI+T1k5I .g}@2KEd8= OkzЦ!zgoA \ER#ӄeψf8x>[7KfF ͶY1upA0kntAiԤV@Jw.}`,i2++ {&\Ǘ2W3E̹tK@Xߛ-Ђ .ɞEָAˮʧ^ ۖy p.%-K JtcHsLK!Gl \9VfCYIRCqptA/\>w}ѱ>- +?ck93t.Y? Cys! -Ѭ/!QWpAp~+o#D/:* X a:L +D7҅s#-2lYht.Yj؂PZEe-+{2BL+!ޅAgv\ b۴Eq5:2uvbJ zlp ., .2BIH>œ%qbk9Iݔz )ԥ(.IdEQqpWmL/:HιPX͓i3W (jzw9(:* :mB -.v 86༾,h|O/W-B09C\zP vW\(gJ"6y#* v2b̹ĉH:@1%Tf5I?S!=sąYs!GN@d?N IBkO&VDp]?#`޸>z%\H3ݨ[s/^BE /{!z "`R6!FqT٭K|c@R1=}B+b# .u,)>;VHpӤ@~ @Ka7@^L24\p78RXSExT!J3|FM}z^Du\;8VۂRU$TVZn;Z*xr[J[[(``ycJU}JA!\$fȮ`[p1arfC\ |PϏ\-fhl]]FY߼1fӂ  ^M6@FM-Z5:U^m`q͂  ga#!`n{xN -$<Ӑ34}5܁.6Q <<:~t'IwҝtC-b"K؏(o38c8)>u)Z0 -Oh^B>!c"-[9M%+|NGhNJ)RTTMKt1\V"ѰKf#… -àDP+DV'Ur|U2ˊԂe,8e!+`SU)T"hduH<9eW VJ -zc"RyL>C, fIڛ&kw0q1FGOO:@ AAL -*u1J`V?IRHIg+Q XFɫ )Eí{8`(xbN*Gos_^e#d5SU 䦙%^˸D*P^# ] -F -8)Ujyy4bx X)/1TFLĎ:f`bh Dt 8 -J3``bC%͊*Xv9y}\7!t "*1Ռj峳x8ҋ'%eD< ƿ_|G -IlN[:8`R&jy iAŐAaB3US,"$IPtK/XVL"];n/Kң6JZ-!JTDCU|%EE˄IZ{AdEDÊ>T&WAV7 u0+DРb+TZL,%h -!ю -F -J,eM*J{-}fa&Nau,a[zO|g9)_eoK -o#DuryT<>~]5-El(=+^WIvIʚݓ>=wr2]aN{l$oow?nX-<*>JjMռŏ?z . -ަcb[iqu5z}4 g^:˦GevHwAKKjN {O e,Kj:J wNĿ.F-o9 i٣dH5IVs9`G{u<;m%HbPzܵU˱( nOl>5N=\=fIZёjTSu_`i})'{e)~0;CfIBT^=J(nvD S-)ݟc#tt,EE稓 ^_HU%%]Yt e"]EhWN'=]YO)(WSنQRS0M_6X`*~cB (uC1MӚVE˧ -vU/{jUzRK18nRR=Ch9JM Cp6NpC0.~]]Q=?{6s=ߧfӌN8p$a surٟw zi8uY{ycu! -i2ty9/>52t 7-Ao$󯓷Av@Rn\ubiɾ 'L;9bw R|:7  -3i7Tux\C3mD٬۶fqƵv]qe'@@̌󧪻uNGPNħÉa,t䮛92MֲԌC(8 47flFG/GVZ-25w^u&<1 =A=e9XP#xy!iIw[7' mv9:&L`W~͝v[n1(uv[Vw z$v5ueEME[GZ-E0/0$;J#/^wqҌ#09 w!r8]wm+Sn6fƉ9.A`fQ3祝e(" s[qnնVh" -t`9n88t9Z6MAOr^qnGk9YxD r8݉ƁIJf}# -VC)74,cպ ͕5Bg:*DZ6aiʦ=mq=$fYi޶?Kg:BUdo{,lE{JnXi;(X.O{$_sg>1DZee,#%$=$b)'洑w:5gj< o{,$1%XytDZ':bk/~-xeoiUReEE:MMyt :/8Pz.1; /tt9 6նsfW䎫?Op&?|7 ִi,vXM[;H6ٰVcƭ D"DqTHRMaQ,QP;ެ3syƩ7'NdAA?M{8ֽv2dj וeO{m4n[qiKqM{m(H{٘Yj}בVEVm9tHGpFg/5\'fԣw]AkJ]-*!؏uDhu0\ lŒ nfSr:D6[v6j#`eԃ Lcn;N<kC ,:Vb -pc_r6%mZAy$`D(i7y/?5KJr60Ƚjy餈 e2ةXW 6 nMWu֑=ǿ^W7y9j\ٌ@(Ou2[2xЬsf"'&nP1mnθل(Pe2vf,k[;7֌nYunR;dnGv0d5mB4Iݶz (?u -qt'4mSlD"pO9Y:tfmK;ns;?_tdM=:(״"0R 2]f[{_h=W]d ֲá=rǡZuĮ8ක?NI ǏMUvZP/>$?~'5K< vazIrZmaY0+ƞnm5(I]Byj-NSÕx.:M}(^80}N|Mm}aj8(Nb+yE2lXm8vDΆCq޴)7 7bB4-#9 Dž/D_k83]חf -.8oyeޗO׳^7ej,}r/:S,倴YglZ-VgA1 9w>nԟw]/7fv6vնo:~c5t:'#l םb"1MHs[iQ5ةbהw;nŭ(%MkNpJrsTDjUU RO$]OCmKjeNrժ,ޏ nryd_Gق^" -V7GsD+UK9|EqAáE7UFZUi^gl Hٸ[z8B gk5Mtm{2a9,c;)9si;^m[ ~9[JpI>`L/H:~A'ɂ]TYH2EȩvTeInsz_ey1d+ NN'=Lt4jSTA͈`J4,Ћ?N%ϔPZ0I3J=wy%5uT'o1ь嫭Ea2 Q[B͞y1K2ղ{ O'C5ace&gj> _"_eq囹NN٨Y6n@,s3ͲWj5ͲV\M t>I֠1ɟCg)Qeǝ;N -v:獛 un6ڬjmyNy'u MM+들y,ZFr@Ԍ{gII:Kׇ:-rYikes$?O6- "~"ROUۜ%j|Nj5?J~]@!V+USnkbאIW*ƪ_Zf,JEaҚ^'BMԚ6VE+f]2[rS]ㆊ)ct)Gj~вEdzx4>mSiB$k mk)|a?-{SH5Kxyea2Ip$uQDlŨ:Of I`4QbSO)c#mv8($m3AP (JCXbmA8Y9)9Fj$uUd)=].1[ZfESfx(Nuf?/6Xb-[96뼛6{ݪii#sq:3t|-2I54pajECb$vCش8A; #Un~yZG][7-d"yv{>ibou4M-UA"}ޮ Vۮ*D~ -POb˟A.4rR,7ulm=d{m׃(5eMbDv]k -vQ;nĢ.Mn%K0?C)R"C$] #o6)x ~RIMM* -J;hEI{AkgV$kQlWUTAP`K ?Ñ; dU,F܀e sHJqw-s3٠U ĻDrDy$ -kvȋ#}w_7w[mp o/~!mc:\I*m3ɛV{[IEqcl9Aw]moa;y|A0tL7޸sÑNÏIh` ~}9%f7\YϤ18J)H=r?cnki切_%vun{[v6z9\6~tq -yFS4lN!/-]EAMYc(BKԚ\ɜ zƏO\+.\'E'<)GZE)x~[yݺeSvp"(BEiIIQ"Ȣc$ seZU|9`YQ/1o/A$i41CvDIʝС+J,PSr..Ǖ .8"X*A_vRculjG],l4q˽4"pݶ}t׵Z.Yf!uF%[tR$d1M`K+meR=pPQ9I;ܗNr:l͝g ~vs֡ %5]OG6hѫL}Ql܀O[j\ IڏU)9:V̚ksQWP,I'l,vU&*X#!,S=fx99,Q$'@ȓ z-| #~4cZQ4'E=xB9&ϚNw `xrYɰ)-I7GU ߢn]Y6L{r8h I_{Y`W5yni om-J n't2;J(ur'5a頝y-djO ֟gwqpU0l4mP,9]jZEPŶ+%}! "'T#~coe[ -)3TVn@մsA9\G=kmC,S 6h8jq8:~?{$(5O:h3{^ ~ǥi3bxu24})][8Ai5U.LN<~x:8(b|9$QO,gЋ=:0Nj)5rAo:fУA=]Jh.~RҗcNz$r|7KP2tj (rmX3ժ(6P{B+ڢi<Spgf{M!Gۍ=[N+?d*,UK"GY v:]wf;@9{]mz!lГ=nݲqrv:t(7{^o{iڢjuPL?Q[ZC0?wK?iRE^ s :$i=M陃 ~^r6黎4E|S~vV{5Q-KZU;J; 2Bxr-),Ek%I=?( vyQE<٧]w. g-v-'?kߎ#wm>z?*$:&r=ަbzeͭI~^WŸMVϤ%o!:IUxbOe8]T=!5Y -ޕGMLMC7=׻բ)7e/Ioj-Y樗"zud(bSSb?q %MMh$'=1C7IRPL5Y7$"Itmf,$FT̸ء4 Bd8dF.~1"k۶=Y~<~Ӽ-x<\s]s\u;{}{;me]^ie}o=Zko]my{\>==skQ4{,s$/<}1/MOL+V>MoFģ yu49+~p8Dk-b @#Bϣ=Old9Nv:&w= }TFJP`2lJtSue&]UmcG]X_[/ 3HFX:M1%_H -Z93 |>+=cW4ÕRc=67N<֜6wv1aaqwi[O[7X-sn7MnVaE 4-xA#Ce&-?=TtN:Mc,YԶ698zώ>IzLsA] ΋v CR"vH 7ZDH4219YOCvAnm+ǵ^7{{ $!]Q]H8݇bM>)!3tzٔ  9)hq !y;A{^ӠD1EZB/ u׹9hr8( 0iU$~kr۽5uAwݶHݸjq,.SMCFȉvwO/9 ?msi)j9Ïl:`4wafy2詈!dPylKMz&n8zhrQĺ;Yʞw ~יfeۿiҥ_J0DaN( e]\\Ih\2)3ZBPV 'O{y4Z10cXM(ZFߓ eaeKp| ~{+"O+Oh4pӟ~ $7j]0Qy8`nex͘e8ؖ5ϬFIoLJ VU#Ńx uMs/(N?3eԄ;O8 zq@zbwF5R"v8%ny-̱ -hTz!H'E.Ïw03T4!D-&2(裚>j| -nQF=9ɟ{PRU. - -uiЪ\$}>ߵ8bܭ{9&=G+frCxBoh5<3&~ Ѣ&4D>X71B٧ʳ- '$(:n/J5-1ïu4BfŇF~`ȧ sӦ؅y+Z|Ĭ8.Fbq^OM#9ZEx^Cr2n@άCb28(QӻvjkQDoUe@z 5íR2yTUUECjz y'@L3i?ogf̎Y~|%uj:Nإ9J駉r8wy0^בX4_o.KfGE䯘D0TLhgYW4/,[ˇMlގ2I -B9vs'jk[u> XnjPHcv9E?Mz35Р# -h/!} (Czؠ2>Ee{0jH)WɯizYXv`\%9Ve)P'C;*,$2Lb4J`$q1+pydLdcP|Ic"%iv@&8%̆QBJOybL#\q\R.] /in\zab" V *,=IکGQE'zGjCC,Mvq,u :NDfJJU7]b&Zڎu<>Uo=7OV6/TӌA6{iVTEOC$r(ޢ%ùܖjy&>_IPa2>Xb5FT(]7I+낢^'=b/CT\ s)# 1cKql 2^ O)O)H| #>$G̀bNrG*ӫܦhb$Uw c a`فJOoct/ZTvon7n@\{1i1Kv!vrٗO?e02ZPhR$\Q^PP]1*I 80$_Q|7YL> C)bH"'i2}~ZpIBF$P?vu#>e:j<0b)!UEL"5Rٳ]H2RVX84+Js<]id!XzLj[ۦf I)}bP%`B +,3Q -U%4t=)-.*0|hgy$=ha--ׁ6ԺN-(M?)ʢ%CދT)H eU0˒[GÏZêo(u%yq7)]7cqxt)Ul]ܮlzSE1=?"O:IZvyuᡇrUQ&yNn{"W4T1UdE:f/.>XWt+@Aƅ%Ի_gn 7reeF HJSVqm*)HE z",r!65 -#!>*Lb%O'OqxD%-KeT'-RKUʜ~-";|<$|zϊf_DDLFʄa:S8ytYFERyH;#iu~TDFt|[6%~8)0TTBJ/I|;*#u\@>m?I59]q8]~ru)Y&ㆣC=+nOQےVĶh'/7M{$IB*; !Ii'IH;(e/G? 7!EnQ,ypP-IԶG̴;M]z߰iN+|n/iEYav4;xREjy^,YnZnU5BL2(+4eNX }T*Dve(m/ kIE2%~z'yۛ1-~n. EԫlzfZ")\.??-,Y vt yE=fB/>NRǥ4u5̓/`,dXbմju4KBA f@C۔ܶh^rP Ypu2WTmy$9=xBrzUӲ'"e4ű*Ȏ,"OQl&Ob?$cS:*!˞rݸ4eσnbJ#G.Sr:lץg_Q5^If:$U8y4?a?4-K)D_ˊ`1kuG,e -%^G, Q2I|5=.EMpۢW=7lU,m&g#8nZ%=5)]^(\VQ,>'uՍ+3Dp f?l&]ӌO7OyfE\SӶ&oe995ͳ79iɳ -W-z_^5E2˞U>(ېtZE!%gvVU3H=?)RU\G5>Qz~qX~L@=Xx%pZ>.[֮C`O4倜֙,޴>US9Y6t>(,ALrl-]16r9;|uY+kYy9T)ZcY u2B,J!I"{ X 4}G+;Z[ڞwzΌtxL31=zeʹf}HdPl8PXWǫrUwR?N3r"9I53N k-.Ǖv'ɷPmKC2܀&c蓣mh7zۘO],I쪒eMyP8s`2"RUE_B>̖C.q"$k?obvmQ+Z׺4cr1cw40M3Բ|)jci-|ޱ&IJ^KӦIfv8N44ᴚvikc)5GoCۂ0|^fĢי[OMfYn6+9>:qm;iy[jkYH%]j?5Cng]oĨ]Qm7խԶ VQ&DfGbՑʐ>7F\+V(^U7xc]wnf'A:a(zWX{ŗWw#cq↣ric{lMpCIG2,"ʝjnof9bٞ=-j(N 8an 5RJPt(Pߗi67QrRDXL.N?o:]&M]aWX̴dӷ7,aV0]9Zznj[~%8hyJvLfyN̴pq=O۞=,}yPnj&TϲiǗ"uj->޷r880SNYO}\8v6SdQմ:m}-u8== x` |H?` -\I> тƨjR_=U粄1w[4I `"` &l,( b@*hb$a"tBKKImgٸl~0^FKpP, GBL@L %H2c$f`\BDgfamSo]uUZq#l@+Ȑ$,0A n@E )VV8z^mk&ɯk,-22cF"@&80@( j0 T ZBP  0A?(1q iVDbH6trmh}=ۢv=,/+=*0p'P -Sb0a rQ$Ht#7xo h"kkqQ!@""?x8a!c4HJRH\%+tUPfuMe]:G+ G@?` +hNXVNU+ijE%kx!D(h&8! MHB5A CHV /x Z0zx)96BLpQ2=aE@@2`'0J@P/A d8`)`A WCp.hE X@^XR|QsHD$2@&0 VЄ- _p*$ H003a NH bj̰QZ^%yKsE^OS*``ZB 1Ch1pa l@)p -FP ءGL LL||V~j_Ֆ -\J1, -QH02! MPB d 2 xAwc۲@/}ӵWW@3@'`! Q., -PAxЄ& -X`H,q7v?TT.E6mbP-|A fP-@A -Mp3a -W@/A8+`ph;NVdo,f@"^ .pP2@ pP#F@< 8 `p&@C  -};d( IX`DI /0 +T! dC 0@~(=tEˈJ­8@ T / -p1 mЃ ]@x@?vx911)qqXgOڶv:w8M+d`4! QB+a gC H@pCGU ϵiߗ#&RC Z0! M+\A Uh"` -Tp@@ p@7b(9V9jY$p6ZV'RX- mCp,L -ThB'8 4 P`` h -#G ߟJ_P&"n؁ f-d! VP2 MpB#3 @X(%ڣ -W))T!P7 [0)( H Xpt+ -`|`J(D 3Z`т %ٵwB -, IB4 s010A Cl&A ZBЃ B-, U$"K}ׅCqGS  -HL`6Єh H"~1D-H^*"'MgI$!C&G$MjHDA60! @00$xac$dĵF.gTMn{5%x&I]n0!(Q$`3h 0b2XbՈ党A ab|iNB"?]q?qEK - <`&4a Ȁx1 3,.+#2VxA#"|܆Bs; )A:hp`" - B#(% `xpg~]}o~MIZ#5A l@`@Q4ADP @@A 2+*2%"*-ȉ5:* sm["2(#a ^Ђ`,T ->Rt@"vĀ!fF$uK<(Ebul3v@Lv(i^wdZb@@6.(mENƭ~T $2)^~DBDnnZu˧>Kr:^EGIUuQ5q|٥QïՒ 9OL;bBMxҧD_s\_-ytGO,+;P|x 7׈135*!:ZGYxϑ]GjW"+aH]S-Gp -cO>>YbWej1P9áA0(]tv/^h\P^"êt?O̮ \qs1|}E:3`5>zj$##b"ힺ[2,'-?/"qfT&/u?9tO@yF~hE#FFQ"0Pw],+d v!-}X|B(>t!#EJ,%Ĵ"rZ"5ˑ=\T_MEmfG{$#t@Ѷuj,, ݲ,훊eDj_CEd-*"?sIb(]dzY)G/'>TBP<8z)`=%xg#oi2)ӿ,&pZF>.q+\FYƠ7ە?Fpzd[b+[q'jr,}M]":>}N:MoR3X}&a]?~Uy5IR/|F|B~ G -btaE.HB e[w&zTr5bLJjlK4CEGL ׵9<*N!Od7LK5cl>ϕ^˸L[ypX*1>a=WѻyYTG_??XfI[U.~<*"K]GHvM2AuDZ۶j -ʼn$cHOom2`b:4Gz;m6wZ64$)XޗԲ#v]r -sI/nKS"ŠF(Yc"q7pH2 I^{NUsS3%M"~M*r#j)%j fQ52`6G9r*UR#(MYH ēgv:ƩhZ?Mrs8 -VOIG]Ս~ozi FɯI0Kif9o$E'`NW#~vIe"%aFDEq'I^Miqe$zqMYPhĮ -h;gmEEY` $v8 J20VsEUBs -tإ yHa!4\ZѾ;ծ -Kįq|`A=CfK& 6US0krU v6']}Φ/=e$ "*MKz&CI~Hk #$U&tHjg`x&ve Fzު:{ VYLGXQc -G%+?|`L|HyABѱ15\^b2{zHYWMbUBjM[9юJ˪ 0qʴxI}vĜPI裟e^,L$j^a-#ȏXq0\kO\$%Tr˭7u+~CpZĢ1D l!‚!/#jU"m3H(./$/BT+V G"PG"7D q $b8>Hk,%>A r̸L8VBZN?W#8 w!K1+ F%"y3$↊#k4㕂RrpI!8 !ҊIB5mTUE1""R/ܶ7GϚxY!RpX@*Z# {g ׈FdbSЊ(00)nÌx:4*GRf/e*<iM]O?|hѢwH±*qH5EiW)P4Y2i`J$?bP^P3.se`؁E*# G4.3($hSBϞ9D{H1!H4(!CD1CRČZD%6m=%eD -Ҏ+1pA@L fy^NXvgS*!)F:R-;ff[leN&v`† -ShEZ%ēvmȼЂx4?ZDTD)Y2/0NRT~ 0cC@B Ԋ ƈu,DR)j@y)q/ 1i#`x!œ B%(bJxD16^/'O+VA9"FňOd V J'*$ǬF..SLԫ<'I#($+0S([7ͳ1ѣBh`Dsd)XNv ѯSdOmAO| G#%)A*dY8% ({ V))>R`-{Fԯ@\UiE#/{r[binش2V!T`HrK]<ѰKKrč;b30..^)"X~{x%ZB|hT-n*Z8/ETCvD 1$ԛhAH/| B}!%KZT -AkSČ( Mq%qݵ=_IRE܎V䪱KPē(yB!9"9eЋYR1Z*[.z~RG-Uri sѱg/m)&Ͳ~ sҜD!m1axi~N)ĦW-+BOcKQIpGp&ħ`ӥV5h'O2'W _j릡6FNR:}$"wmތi$!}NG,Y<.}RGOV uX5PNq fK*v ÞWu*B˓~Tu/Khp.󃒤]ҎLӟu^yč:XXb9]$;vAmʂEa"|ܔO dМJ1q!*K2dXrcղݗ>Q iC`bT,V%o2^zt]AYrW[Ve@%n'S -x6+^_œlYGKAQ/Oݨx2WL"SʿjQћ**ElXpR)'_3T'I4Qh-'@f]/}/g"v4S<^6$Gzr[9QIl:1ǵNP?C[< -Ԟ} agjSu%=Y̪&XSkZFjUS%Ͳ<^or -vIcUh7I'#mݬUW+jUr<ɳnMp!Մnlv]J*V&˖[= +Ekmۦ zz9~CMCn8"<.äĵ>j䪞T=m\u*p< -^QocOߔng ZLPl1*4U"&~>5{E/?kҊ)bUV=*nUi2tXJB1+kjҲ$!$9ڨxc]iһ72VH~p!eˆzn'I(Q]pMkQ|I򧹛chESkxV~EˠU4U$s Rzv5ՠ7%I?M4OۚO^r:˟N"VMq{ \v5)1[n:(ؽ|jVucP+l=nK+䙁Br)FdYSp${v>u{Sͳkپ'{f -M:7b]DEN}x?,A㗶N#Ǧm[z߯~z(Pآxcb_]?,e 8žtK7CnQT\OɵDq0Sƕuމ7H.'E?*Z8/?~H2ÿJ#Q3u:zQaeWo5bF0@ 8j$#U - T:mm!grm(rG(zic酇o"H$_ -{T;_ymg֭tpرDg7! +w\cռn|)P%Q(EYc;Ix4]DSn{'Z>(!tY#ck5YnɮqDMzM]Q -| 9-Ƣ:I0`@J]|U+Yj?dO -vxU1Nf)/RI% #E3D)3vvLYotWْ>SLsR"S_r|?~+Kid̢shlC7W/OWnu&չ MP-=Nd !r"20^ɞX`2-i>qIfV0h <20!V ,! hBZD~!xnEK$i$ սI3kd/@ `B3(36P∏ )u$G "[*+9J-!A^|xb*dϋWj]?EmH%y6e}gacP~+ETpbÈ P -W~$@DZVapJ@y$G@|ҒaD !H X5 -`CI+s#inR+,r4K@ 8P4P0Yb# ]-!Zzl?c)%zῶ%|OԄկY-L0S0h@'`9 | Br 0`A )>J+<~׊8_=k$r}T"2K-^!J7ёMv 1!*pZ9atRĂyzN${$gs=1OݙSdB.<@Z  -D `RL/H@IPAbА/⢭G̋^n~X t -^`@8aK&Na&]3'a}y/Vx*f#&^GX@`!l C -P#d:5P0@Œ@+PXVɬ8S[(~8$;D@D/с$#`Ahg`?)k=.R٘>W^mK]JDcP!h`T(XX!@@cFɜv -? '=ieUG(3L|zpLc`  ԀXʱ;ǚIr6ȮCqܢ&xh.(t '|`<F )&i$oC7IGxZ P#lH Є` @rc;$WZF&+B^()ij' - .=@rPcC!Q`bQ8$dE z4 C-!,T; Nvg':JD vPAp-@A\dAXB|HZX.20^)(B pSzP[2y}|%) kFG, - J@/ bt.M c0%co2\bwKG-۾Sd &01'D XA)lPc2 8!EVAPPFSbub-_wDQBL1с`\0>#v0%/H @C ,P `!.X;Jq-Z~:1|ӿ%$@%Q$T@ ]@ƀXAxb+ @ chQz9ݞekׯM&SˌP$n$|a 8n\8.0#>d7g]k\&CB@!H2 !̏}IEZ̶ w(x+Hv ( -phG -Ha F ^`.DIz4⡀!&ZAZq~LLzv)E7ezq¡K )( [@t`-PA0Q! B0XQ1a,OZ5tK.A|= -< 0tJ@/$`KPaB2l0Ѐ@PPxJ'Ag_*h -@l.`H,GxDx|LO( bЉLT 3;(6a橂ׁ,&Fp dIhXʊAO/ -jxLeCd+ʰ -?\`Z@ ( D,M@ -2 A)G3ˏٛ荖m7 ycʫF4сh TXr$!"c؍!L.~^@BdфTb' 0Ve2CC2 -r$`8h~ -tH %?x(JXϨȪ9rd,'}`,72{wf\ZGn8ֽ vqL_Z|L->p`4A,=1#43:QZ➥Dj]u9~;.d;lz!(p"DaL #$x9(Jxbx#1 -%_ +klmuُT$Srȼ x P!F*2l҈(֢*Ff?"Opkímm1ǟfIEӑӢ%&':|pZq}9zH*%7(8d'+HÝ'n:c`X@.K14IpO TB","BK#̃'1[ h'[2$:4Ǐ(tku힖=uq=\e=mg3]9ozuG<),VﶟYNy~㨊v:wBZG=頙ZW{=(FNֆ|20R:$2hV.Cok\w?󱣩flvsEE/3z'W)&kl}{L2g?1|leZm㶹 (2.'?tξ4Y^ B`]@5 -\7,M;IPL JJzq֝cW>;PD<,ӭ9Z2X-}Ow߳끧օ_|{ pә?s1弱W*ȝWo$p(6ikw]b7:Q $i] khY;{$Ppʬ9>|(F'bI5/:!SCRΓ+syXf\LB q(VX'@DSuH'v:t~D9)$M{zʰLٲ ǭcő>יD׍=/E]=q ixrݶm*kn^6QH7K>Nz4lA@:}%ݾ(,V - =zGc]X~ᝪ['}~Go3։Gne0N`$"ӝ}ؑSU$R -lvalLmsőV@1)Ajue֮K7tͦ;"M4W?XVf[)8]]OՏbis)&5H)hŸ(q FGuNz_~,x"6NA[mWpUR1Y'Y[Dm$TR}uv)KᏚZffusaYvXj+)%SuØ=dUBR(ra_7{Dl8fi28~ zfzs9i&Aejz]\_ۺDQ YK_#(æ]7⇏+bl>^EOwBk󚶶| -i}j꺯H?K޾"|9C>/t7hJ+J3+DxR59/q]WUQ`6dl.(V/oځ%'7^eu%;yښp}T!u]7MiN>EMt]queI5OR $-8~f{L6.eT~;& -J2(b-\g/d=>\m]l 'MU6Wٜ}[059Ңn1%MrrIJt!B40!QtEa2r1P+Ut!O1um7NͶ4`KAn?{${5tGI)bb^#OѹhuA詒/GmtC lKMS>,OkSL!!jhҿj~OYX%ϒ4NǓ< p)~]vM0/ |`w&%CH$^7?]]c!O(5\=Gl@8>`(RU%?vn@lr@$@+ݧoPZv0D3\`bF[>/ U+a*((_ 8xIzivMu^x"?R -F eI~a#YI)rS -!8'"P(ѤKsW j."Hq<ȶKMR(yxIQL"&#RP Oʫ)Emkc66ꊛgɅsT7 }w6&ɳϮ%d4}+b -It. -}H?=NKaR&4]L87I&9nIyyP%2*)o?Ml:mpH~)9 =b` aAV>UK-ۛdUCmڂ` -=n<"q5ᤸwArUM!CPQCDŪd롗Q>U+h 'hMS=H1?Q7(:(<EaCGmn2ˡTDZ6un3!($&z1?F -Qa@;lvQ5` !8Ѷ*bdR( P4:)9D遐a@8H`.ݶM"d)b!2!+\#>4]D`@ -bT c/'w7&#v*pxbD^I!q,;JT/\C 0|>BY %l!y^2a5ju!}{\B#KR&ƌV麊IË(  -W $2[$ej9 a9ir>T#%7yh]_[~MIkbQSn>~'ponhX'IS_*@Z3,+1|.,FV!d?̶ )1imMKqc' EWr_<sLͱ ׌ty҈tۮn"``L"S-ꆟvG~:Jo!yJ~?ǴỸfcr:ƹjuX-s-Ϫ`a7mϚnZ$"yDm"څמLm hq҈d(zv!:iP|O7͓O/('<̬nwTϡV\;~QҊʖA+i%.)$@H!Ce;`a2Pzޠn z-LD`PM;nkfG2TH>0hl0a Ue> mX*vIێSΏ0!@b+`3/H`q"V@v`b *dBG"` ($CUP"\iA+ƕKqdYQXz4E*V!rY@;{`sO˖DBaPP$*``_t4%$|8 %":.2)yMtDdrem祈D* -MK.=ou}rJ'S>Hs>*J[|zQܚWѝ _NS:>K ~-ǹǣ-=zU>sK*erCj[ .=mHC1mᑼS|t'KٮKU:Ymyt(j)N׍_Q?nTo!h\Pd[X&;nvq_ϣH*jWTyIّ2Oyz=38PFbyaBzʶiRN~m!}xAy!6=9)@8ZTLsݢ&h?PÅr 0' -4 8&@|a(p08fVh̼R%"0B4j=b4njS[@g=@ LL(7!3"d!ŊK)d{Z~&ĕGhH1PDp)B`b kO,~`ikɠYYz$[7.մmn7M{ G<9&EJ5s:s ?(F2DV4TFfbԩi$[o<{me\wӶ"9SVGUBbcppt6P(rߘZ7y*Qݺ ~wu7XJx`b$=xs(YK0*-k#Ꞛx18ZPF@)v}Ogיn2dW_\7DEl{ޚeuV57MP, jnMk~[=fur F>Òq$AkOw'{R|1JEUӤU/dH׭9^qK< p%h1a,#CTIqrbE 8^#hb(ſI- vxjYp@2h !Z<1cOsL0 ⅌42b V '0@BdxA!  +`J>'e}\n.M}Ip|cPt| -JvYJ UK4TqŊثYP'!5XJjZʢ3,vw4ݶޕM>ЇDn|@EIJ$Hoښ^%TMö4HFd|) (4:HeIJy@&*-ݎ7mt8Wך$c}21@ܗecP3+L fykg]˖fo~U=OlCdX,+vioTI-'/f"X;ji*cIr[T$ZtF(TragiR%85bK>CD2-?B *Z&bP1ۂܷŻM]W-b6D[lY''7KFeF(mrOlBWN!~Nz1S0T>+@j;pzOOYIf -\x^ѴNr蕐sZ.dV"vAH8 ($ $|ؑEGK UfI H+G1̣Ʌ?s1ש&wʨTfTe sN9Z Cn亮b%bF J4K> 0 HMzߺ 虓dm-`*&%viY_K!r8 C -F ]]{d] Epq:%z]B#0؊ɄK"e-HF7Z@q2aٕǣ4 -i|p3ZwKaYdC.ԗ_yahb^!Z;aP˪fwzxM_wJ2"0!\BUQdz50bfXzPaA슏`mIzbQ)b60&IZב[+I5.UtWM-0*Z`?hR\\\@ !rL … @̤TMQjU_U_Λ&(=Yۏ܁ƙΦxP{E :]yXBxA۫ -aV(cL aZ+iQ^we1DX~=/G/o˾v:t\KeQ!K -gZ67K-,4"$!5aI` JO\nS;0='~(?H4.BPz5>xFLD @H".&+V"Q_]ub("XN&II2MI]GjUw૎I<JB@x1#ĎO)ZɥzaBE/[PתEx(~]Cw8ds嵊HEr=s7$r$5{IagjQs b QcB8BG #r iD.ߪM=u^tZd --u V,Śa  A$Bq""Z !#1?dNXR-2’"pCn!<)fwL -key$EᐜN]FA@|ٺZX}|OUHG b\7da4fx"x"F --hRPBf*@ 4DV:&˞1Tgٓ}Fg\Fꉣ,$ -Yxx>-ep!4^`\Ot?QDzq:pKIuہƜwGMEJrוnkCedUM@<zP@9D#lB" -xZ<6YG:9QWWKPۆXOS$=%".2NF$@#l|Xe"mZ,}i(! b8 I˾kOS5&]eԫ>0_Űx@@KHT~WSWEcdeoEd"=Nm2* IJ}s uCɬL;Vja?O"t:WK4/;ZpaTHW^\IFv@HB>2`%5Db)?K׎t8a#Ed@J+u-"P43=^ZZ@u}.CY7Ct%rxgGGCF ՊI3E/Ų -%_z)O;bU˖?bVL5-V!2zXa9N̳ﶺϊGtџhl,]'IԺƹਟknnz(ہ.OJgU=):ZW}$M4Ժ{i+B4A#//%" -QֽͣG:,}Uu?CuGO]Lճ0gH?_5K<:~9<~t}dpf:.8 Hy)vURL󌖔(%ad9NBRB0[QEʬv\i6}顈 +![w&}b+yE}Z9X 1/++aG0h~ i@1 <䷄=(ImĦ?ju寳C_,1u6Mu{Z5 s |zOk1UJ#++"*H?qv{l8z;r^&r:܆9q&hX=0Uwg - a3Ӣ2ѰH-%?Mi7)p%J> I{^q瑛ÉTLo&߶%[˴&O լ3;}!GGIۮG1V#uvJ)`+B٘Q5QŊǕ]P XgUjSGz$SS=ZI-kAk|$'z"#EԪm/hEc1QTqQb2Â}VGwQAߋهYW ղ -%jAKώc?=rD4u,9Noeytvo69^gȍ^"e+#1(/,Cv e EtU"d7N3cB?>-6xs z|9ܴؕԌQQDQ{ R0!kfZa6$7`"\Z,&,J`%]5ǿyT*hA?)IC%sy"*ի- 8d6i#)qt(~6N7}O %-" 0V-U}ٳʿնH 4X^N'ys>9nTA2BbX;LX?`J-($'nGH,T<Ҫ`dU~!m!&/KPc}W#m=z`MLXϸX6TLL<|+"2ZX%pa00"t8)6Edz:L bv8!p"Mw8Bf}2wܫe8~1 _++X2ieb"CCfDE#,ddH^TИq1d&[{U.C ->{&IB6L22&4 +BLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM uV,e03#q M6G -1HEmu8ᓢ("3R&՚ʰ6.dam_O#7"3,oD@F%i0ա2'qJ<#jq<)mUzeWXbn z9~2O)sr: ruly-}7咛hyrۻew%z]-쓢O|( ZS$ȇh_<;S5ݣk]wo-䦻p RG4v5-t-g\ I2"ij`5=C?3 EqD;3Р(i4T2W<)w;:&3rh mʖa8nz|$cnˑyL6J!zdrM_[:#bKj~N Lep[,)Axsm-uמQl*5K)A^ǎ.M0b|jJDE*VBxr<]Q-r:pYUpHeǽEa;}_B$X@!q[o1<{% -5w$XrהgsHMX7E2rǓ~u ~(gv84TĮ3M ~"5u.g7]+jy܉떅J:m%ɗb>w`o;=bR^bz,zV-)ip=Mr,ͱW|eG;wƣ=-;:9&:]bOG~$eK9r“e\VNIԢԴG =CtzIDOI{msC4\[2 #{HQzT'Ve~K`CYe>~3#ZFw5~DaqqgswhUI. R;S{(I0/QkKrĮ*Mq'gc.z׹,ִQ% oy8(a)Œ-HjʂߏIMi4}M/EHlz$OtjOes}v)KM=,Sm+Jw~h]q/EY ?nYe{ة\'EQF|Ūx=YF,9ö/qbBz$YOƟ9͒{s"-ֻz2$ã.]"۔ݎo(-/:.2Dٓale>볧Id)w\u2&{]γiԱ~Ğ#nYTN5zYh.^eWkr1M*]uM:^Njr3Nǐ:VFSʋFԛS7A:Vֱ?n(Ů?zgyH]wEO]R.);NC+whi]CtJ$#a4R|,sqt#tղ<ytղW s =a0LIg߇rו[~0CV3S":;|K;J<)ZF i}Pl;ðĞ1< XM{y!,=y$,E'Қ8c %_sl۩V-G[v$ir$[~d~OQі,Vu)ƈbN|IIHz<ص%"RJY+WOTˆ̱=2'YNYeFkI^G࿮!Xf;Np-#%^P ATKϪ5.5_ˊ]Y=QoYI"q -]kRQڟu3%<#Ur:tة'r 1PJ(Di6\_%;-$<#RѲy|`!;%?kffYu$ m+7 ׍t o󄠫]a2Lb"slZUN?j$qQ(bz]*UJ/EbJz'PRʒR陓y8Ξv8V6ղ0e=lOV-klHgJ?̆^ԲG=]Fb&Ea׎Kѓv=Y,R5Ѓŭ -e1(ыMs=! ьU2OĪ.9(5M.Ͼݘ&,`76EjJޘTVMAo&"SpQL91^[i(5IijЊ'iqƟeMfd׽Z'޲YUvd~Ij9ž tqlo -C -yγݲn%*5K')E0VS(F}I~Ty1ECdIx̬<(Pmi7Ð{0=UΦ+>B>nAO&'nG< Qz=u[f|fP!Λv:#oivr:n&abmC;4wesBxbL.z0EGn{bi R| -bs<[#qh]Q ٟdl_{IWv8Ա -#VTs gYd]@{Q=J0}bJ",Y3zߑg% _O3 -V8nвe[j$~I B4o:Vf2*]~X?͜{Rf+X^LӬAo$A*'.z9 ^L_a_=#BIֻ䶤~[u^s{I-MX&ĻJmЃ LjjJϟ]Q4"%7c%_8gYz߽帢g%#9V Bhb"c`)ђ$($L)_PmK7 Ӡ8E!=ѧ%ǭaXZUŢ(6]0#ϊ2$I{DSJˑd(rۛcRſc@<=( -{ U޶:Jbe}Y uK/\N("[۟m}SGQTܢܴub{M4qQOS}w~]FMu2KfQ. zwB(tZJba72-䏚(a藤 v_z?)刏 Djuai1i(]*͔FU92VN@Q(hF 0ddB|O-~5N'Զ0& Eawrq4nun شYvvO#fez9zLŪ/{G:Vn:`wNZnq"V4dH2uaӻUs7)zвFHkFR5XNG'^5ȽnR_!hGEqCժ#43#Ouץ1mњܶA\C)9Tm7&_MUsf~|ꭻkȍtW=Vt1#_EK2}ZĮخE/G?5ySE/ϚzT45OhN ~ggay=zHJ^-Ytlj[ Ş*U fRTefamY5c$mOKREq:  endstream endobj 21 0 obj <>stream -œ?u՝o -S(y2?OUO8q+"ŖjYuq^^òi&n=/'/ -Goij`Wi|z]0$sW=2,X-4ZTaUXrPoZ0ne4(_i*]s~;lB*1YOI^PԴAzܔ[<-e#|BIҚH- (=F-#v5-e2(eȮt?S4I /,fGj'Ő)fXF:U֠WaT $w!ǙIsE."v34^%M﮻N (ނ:zJ?K$AlZ_aB1';xt P4t$ yYIJo_%ɖQ mO笚O&9 Uö&$f)Eo=/M kZyBzPrZJV.[74Tjf%U?MG,u2b({)a{~_ :YNyN:Lo`q'knnyviH2JR`C;{ _H+ ^V6{Up9KxRlok?驛$kؓY"hwۊnvXKL'7߹\'5M/"hKV8?Z\VAfԛsva2 bӺ,E+aMS?ޟwbX-̱m龜bul*ڛiyԔ=g Fjeh]H%W0TgsmwnxeE(?|Ւ7EYV%O9] rӖ^6&9[PO*y˺P&Qp?mfn[\r6q -hej)DpLgG3=Yz)xYV;)?$W2̗$o&u01Q6KX G`Pq_Wb;&i1 -J'IPz8jM[ ~'wmɅC;5g"LL2aFE /`!SÅ}aXԊG i@y…Jdo|v -֩T׻YtWFLb,Q0(E+Į8d.I>0q:}R4_ESv驟% ~?+ۏLH/E*dXLk5g^ )PRȅ-ߖNzeyM5KhHvWV>bC -5ThvC _(!%FLY3<]Qtu,UKjqfbS=A@VM%u2(MoLw. f7"xܸ@驂Y˒3߫Z֓4Qe^qAf:LY:>f4i".~<ة\-[au2@Z<]=f9{Y@~9m8 >Y~eUR8TF`w[^v-EwBtVUa`P{9zPreY[hY1.~3RE(:IOOu*[iRHcY{^)1 8l\4]-ZX`q-G&WNn9ۦ<nG+VnXHMie1~&EJ43sKv,*K~yR1~a<Z5&z]#"yYH)=4J𧹐x2&0HZ*I10ՋIdZ`#%f"U@|̦Ok՞+چ(qVŏdW7I - o4}eCk9I:Ur&jmȗ劇o]9w{mER"\fI]_"_9Ǔ-;B"pY,hF]qQʲf`mW<:H>``)ɑEZ>EmZzR~ԴL~OJC?KwYb ז̢ -^1EP=*uTJ6`RI3WJ+owj?Oؔ'A-i41d^/: #W{[7-<(-{.tN'4'=$ _OonmMxE[ۛ#MK/+/-VM -DKjţh89dz-&&^J3^=MCh^h5WB,?/GCC.\aM5=I2ʎS>Mx'#,X^y3 iJ #ЊȥǑ5-"=[r cQW4yz71sP+`Hv;2G9 p{zl -nQmʊ]њY_ȃPH%`!bLrVB+g-hJ2 bSЊ6j]-Č - jߓ^eDZN3YA@b5̂Sx;Ni=UۄB_"Q0RZ'Eϊ^E!)ZS*T#"9eP)`EG ^R`9x`AIQ̶_PrQ=ᢲ]2EtZe~L9~!C&cQH>׉ÿvگ+ K0T@8AKF0Je`b^sA$Q3kD3I$4,5N`0I2 gM2%v 2`)qHyX fϺ)JXNnuFAxq /MjzUR6%䧄<=j91 L*f_KPh 6`zĊQPJf$ H204b+UlJ?΀$(+яU]yP#E}y) 4s4]=OLSJAxߚ~{py5/ȍ|zɄۭ;V .)QKbiY>ϬN0(Ȏp?VKϢ!=ËbP" 4+C`ɱ"Bc(12N~x==L`9L`#WOTԨUϠ66 BD:zǔ@&=~?-QITt&ICi>}I-в/fT;,as|*ɱ_4Wc%%xrWIFȩHi-!F?=]mwO~'yWF1U  m\QCOiR1b|^B`Q7d\ĿK@I -f`J2 ȧAlTH*+ FAgCDEDTT֨ZҨD/`R֓AҚY\^R˚jOP:3 .G -0\`RcݺdvĢt!fEqq"шxNiTe 4^B#^@=R\,L_*XTh1\+eH/Zvٯ%=Y:6LZHQb ~h1ʞqpi -E>rpIY:(y}t'*ժߔ%*_i`=ɀnPBxpO"ÅDI -QF>4X C -N4\R晅x`FW Z?ZxЊR 9#Ȃ[dU˞7 un0 =]re.9@g* Eˈ)y\F,S[w#cCJ*Hhٱ'Mw,  F%%Gȏ'Ģ}z $ac(~K+M #b1&M6`D+Nz&CP?#rPb%1yP@; !$WWT…ah\.1_e˰R+c -є!Gx"MrٖHj,V- .j3t1Ig8b;2//LHTX! !RHH)rA=C!XļhX@=YR!pQ\EDH)/>52b)_"6܊W>r5JZ3i\+"6PB^XDHp2lv7XTG Nb+FԻP&ۛ^)?C` -<…&ZUնm:x~Ba[r՗̪7 -_my>^RZH%ϣAj*Ŝ>)}AY }t`tLZWÌ~ObS-O@ т5*F,ɞs/3ˏv_9pR?^Rvp19) -U:H\ bR'/i'ȮT/qc&X XB//:qk,ڝa ,r6`1 jW- GIHJ O.c!3nϔ<;LZ+mzS8nzDq"}f=iYSj1(>܈D׳.Tb&h<2$ *:Rb&nې|$p".#~sj؄Q~]{VtFJH"-;mϬ5ɯ\/U̾#!+>(^v;aR#%/!,.ӉGݰ,VzTSq;bWҚ8L*ZSiгEEJE(CQz~NC9jZ rBG&q.v3y;N8$W5$}4" *F"$(ulSN.Xe\6R $8@iAO͗>Ȯ''aBb$OwkA ,|K'!C' -q(iW.ӆk'CZ[oߡR2DUK!tJt@dME~ sM>'tv"ɕ'-xrGh'?N3&2g!OnBB?' oޡ };O4/o' ~Iзcr'Wy?!}v6aτ?ys& 6 9 sm|.;O<9\pM[O~0lM;|BΓC\݄&~ O>Cv&'-hr_hO'6opO~BfB7l°'  };Mlrr<o& 6\wyr&W{=8W?ǣSB@4 LK" a46B:4o"0%wDM6QiUKƟh/*+ .ZZeÆPXeCJV@REelTDtqJ 4*2E@ ^ԅvܽhj+gq4b.8@L~If!ȝG1PWEl(?A},E6+VW9%,ҬɲYza(!#Bu(EUٹ%Uz^!ZDݗ\z°s5S]H SD9PT2{9} X8g9^n6M,3m&}P/EߗCuaEɎ܇:U7#klO◮~to)%1;2:DLaHuxõ7s`@Xihjf\:mu?"J@`- $>7a/w߶2EK -+`g* 9+%F,]B ^,_8˝WreaI%f,6ݛT!39۞v ےL.=ۚE*ph'#ʹMg;x.Es>6*%WW-( '%Çń+a`ˏꡁ! ҤQ<O߳Zu18K1H!TrltJDFQ?Q0>L꬈rV,JZ#$jO ->)SIoc_63:X:jmEa[7-(o β: XFQPW% AK*HZ/qf7}jj>Zc>faNE G,O"ijAa#p1Cצ8TF HI\ {T9eӗArG2\IyHo~vsNY;À:}>9-QZZvY\ajH_ыFל(߉+ yM %3m@e#C .bQԣ9Y=cc8ЙEFDS86]A)ΥAe*lpu}GNY !O5Js{n]9n镒f~[6?Dr,ڥwlQYE-c2Ư,ti7ĚddF(?U)?F1db!vT2kN{oࢉG \v]A{/`jyjCYv֘.$NzdW -VmԐ@T߁g( ܯ~,m[ˌO6GfezJrɡ ?޾̡A K0z5Z`7N lǞ/Ұ4P>R_Aq= E7b ry>mUNRyUgڌ_1\0*5+lG=pvPlÝD+Sv$ahf%;\WX -KP[fb{ Oʋ(AG)/k|jҜoǗ.3|ww%JlYf~!΄hX!J_sz?E#jQq̓5Jh^QO`Ve>+p6E2+!7ΔDOgk"絇$աj+:5t9¤6gY4WvƥlWxrlhƄ0*5+h-{Tb-6HI971\ WcP) 4^;3IcIj",q6DI5ZkVE +}*~_6ɫX70 A^*1HחHk "r*Ce3&;&kg8aĈNr'EG_PX -q#bluɩOZx]y'9v>C B+HPr8_{T߭b&dzIWpq5ap'=\ -:})BMUU'Wbzm8!z+`+֪6._o3pGڑtno/?>G5'.bبm@HF# %%B.ypV ,绐f6;Ls126. 풵{pf+4}H{F'_[TV%+!af/*\T/޲bE-sA/l]5&]B||vJvf}愄 KFIԋ|`}kTWnwp?j9`RB.>alY~hB+;Dl|CEfll4t)pc}YS%#jC!00`!t"{TFqU9پJp:Tͩ9۰|&D.8Q@":%WP!&̽1ۡqr{R~(n\`4 %>tҺ͝CGW;@F{)8gzGas8BJ侸](#;lsl* ΦE.gf2 C:o+s9#33(GKx-Z\Vx xv@2\ HÐ*cc@2&k$ji"43H7nD4YzNKR[i.3CyXqQΆDMkHV*Iu3x䖸D+hEd,%"ʲY4q`z2{\E(FP1*L/X^d~0rw˴cۥh CʑPq3j` 9/;:UJz7xdDv%)H'tMħvWDtJM̈1VPf$:[gm+Z"|ryWg0D& f*'_&SJY G Nl:NlWr=V|b Xw(G6QF6SC'N8HUD5 -Qu -BcQ_e:iik_Y9JHa`u?f$b[F,rzD0iEONd0jzre l걌5,v\:Q>mр÷wLO\n5GYÐef²Q#~l -p(,q*uYZs+"Am{ xtuJB]ElPow[nX-ܔ_)8RZ PC DǭtcVen3uA<bfO=8ضOlj]/tˀJ,9\'31 Dr8$ - "Z;c7ǣ4tyNߠ,嘸كHhSJnR@ 1KK:M+0j9|Rb>>~*(:mq_L)[oTm؀6E$pqL)m$EA/CDݑN^l4PI=G93p0@ H`kЋQT1Kt^5qp},ti~3K~WG P|Jzze|[) Y20ə(*ng3-6CY-8G(R:E[eЇ4y^y? JTؔ;<.2@@ocx4O{,S3 -NW|3;2*xS)fhzfk㺞c~ " AJ tOA'&@>%Z> 3'\O# $%SA dD @nT .wVRB $:-)Vc9].z?i o^BFmedpXiq!) ~0ri?T-Fpy 6cc2,4f829c9b-34ad-43ea-ad46-33ba3a5582efe993486d-d27d-4033-b997-99a8db324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulence;childrenbaseFrequency(0.02attribute; ,numOctavesresultturbstitchTilnoS,feCompositinSourceGraphicinopeinwidth100%objecthxxyyidAI__1id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-20000z-5xy1ystyll-color:whsurfacespecOusConstant(Exponekk1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.diladnbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(77spli(1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre110001122nred6884Y5##h -as4TP (aa `a`Bj NҥmZQVEQWcB1N7 epmΞQk˝ɜX9B$!,8*hHk} nS>Πr~ՈePVG#VV,×wԭ8ҕxmM,Eqt.A?%ILS1 sA0gpE҂E(dr* Gh"*R"@ʣ臌Ҟ~&cjxꂴU^ȣ yx8`Ԗ"W$D3hw@E*2%ijX^ 2DBN`TgXR[i<㐍qUtvЕfJbiUJ<]+Eb@k[O|3T@$4 > LMe誈ɇ<ň H]} T0s?A֪In$^._ЙO#2KlZp, P9vuoγbo˳?$~gb.s&IOD_C.%@{<3*T%&fPbiv~<[:4pGS4#̗5@֝t- aWq" -tq/G6-eHGY@~K׈4#"q`#U1`o./g-&e0g/ہ($W E73f8 UT sٖײթuixG#%=`͛ vfPzdr!I/J9$F3~A45VUǍ!+ {%؊C}Vl,%[e+@GC] rkpOlgSCkPUz&s'-W+B76,}(`@{5¦J@*d3:u- e5(-O-:7n- F6>Xډ|\3SI@#VdG'k\Vu|ًZב/o6jQDVAPfDbY8;: k`18b1 bFpzGu2qZߡ MFdžkCY -C>p1~Fa;8ݡߋw&7[ f\&Mx\JwL7GjԈ>`vЮ.d𖨵 ,pC|Gq8lȗb~hI?Ł%l8(bE >tL"T.xЂMSe֟p*5FfL*pNXFn@[Cͽ/G Hv"'opӥ^NPY v^'UPMm##au1LCؖZļ0WuD0v)jgSQU`_7m a#ܡ PcȖ7.oAo" ӜׁnWʨ~k ^R@.g#3793<ҳt?#}Y?tϸp5W\H 8Xuڎ(øp;p2Ofrf7<"UZp #5#, k|qÑ8@ Q~R1?. Մ)âYo5bD9xtsʑ`"+%VC{%E5.T3Qb:*Ց?bDնz\1>!C $Kvy^H;DT' -2HZAOYq8#!rNIqe9k 7͈eӈA pAF̤/j&x ȗ.G%b*;r= iS)^9`au@wrffHu;/sKڈ]2GCKШe/EmiKe-s(GAQ(?L.+-S>HWMp`#H }nv3ʪ6㠴:Yr'UQw)c(~#73uiGfDK7sx5siBdHxljA)ml7Ѵ+쒼HŚ{鳻L@!us>Fꨧ!v:DAq0{urZ|Ȧ-ZI-Z9鑐Wю3:vSFeKJqSFGrV#;d?b<}6|_55կ FLT0A003L(u4 -P@(0 @ -"D%K2p 8 *0΀ -44 A᐀TxjB @ PDx0(4D@ -I 7B(3Eёf+R%:kF{`jvGm(/d#fw&eŗ ,b:DpeeQ>@ڎ~5tC&D} tILg 56Q$Virmn D3Ϛr$k;gVW߾􊽦dQbQ4"[Ca(|^QϜQn(npERIs@Q 8,7Q&H (<{٣Ba4 -Eܦ 78=;"øp9;ؙ>=$>fVdJRb]K -KZR&tsUE,z rsSIf,bT[ڤ\jRNu\hlCK)wHYNPTux,7txJ 'GؔR59ԦeQj.UsQ{#;\^V ^1.F1qAX$S^^6⡞v;g%A_jl;ruSYU!uDD#d\>t-Ln}׈8Ffdd$F$d$\FFFCaFkTnFKnlFBlV:UeaM{㻳#f{OQ׻4l@E%4e+cj_W!0 7t .vS -sk_gC_qٞޞYϲnownGZo+{WePWjk 1gdܺE<-$dFF==5S#dlL3Bp;97ٰt,Th穀Hݑ Jn5-cs=ύs>1wiВ ۖV8K;Jvy{V%kR_[ݻ'j(m+Kngwf?i*նA3&Ukm\0H@($4@0-X  DHBBH@~ `!B̦¶%[ry|=%˳sTxٖlP&눝l6ja%<⴩Q)MȥkLz1&sWx#H+7K +}oyɈNv\u<[#!؜[GvtňķLy-?ؔҋiW-Yߙ?nxxVE{5ٯ{$<͑M^m WedE;=S춂ZK[4Vm #\jӷt6v7\E=v'|Jg'EQɟmgE_nĴ6īr37!R4VE̤G\J:;9\-cF⑐FO>>]=ޚ/o}m.f*LT~X YGT:}8dÜc3ynE=~xg5kGkqh[;}gZӞ[fs`@,#'?o8RH݌ -ȽxwVwFbT;Q%PWjP:7VmNmzܸW+zlXORi'݈."Rb& -)etiSsel+R֪<4fNQqLi[DñFkn'ȿ;d;M;JF+'d`\/GTSrG-g!G99NěMwo 85W9T#`(kںڪ9z-#sx0q :{{o33zSen-+ -lߎNqHu)GRg9YyI@PaH  p -$Tx $  d(󭛪y1+YװRꪎ1X{QމQ8ʁLCAn>UUgu]TTkMWxUE5ß/uJWUf_xv`Fv]^̻S!a SMyNi\K{]~z])/Y^귆J֯MKKC3KK3333C333C333C34KK4K44K3KKKKCUҾZCC66۳f;ڽ[;BD޳D^H/kJCqSԁJ^,kS(07){63H?<@,b4QϠrpUNΣ-Eʇ:F&|' hT5F>Dn/}|KXzc"jdAOlMΠhLY替%Hak{o0-<!.[P((O. |}КU8B~(.$ǘxxMChaZQr) :+b܎Ҽ2,a3&UJ78ؿ. -Bz1 U =.7ݗ hs~r{%@Uc\0`ހIbeڨx%NkXS|%5eli$yMǨF'(_1uP -^*r]wsoUgݗeѦcB/PghAXk]]RcgXyviӈ$GHh^@4$Ȅ& >0~^-x2RSځf+̲{RUyqbq(dш_aВ[qz7PA^{3\cy@X UwVI+H@B5ĵv"N8 - -=^{ܬ8{ZެZR2޶N@#2yyڎJܺ8hIu/BM:h`ip,pqR6"K }o57EhI2 `OTB=Kcr\h5 9mGHjFbcqPg5 ִٕ(Pf9l~#H݆(˵=s -{UGOh \Np'c1.S#QASr\o:zb#U,l:L^ԐIe w7O7JvZVc9So1> C7g*A>%W6DM$"s`دn^n,1Eux]4K2atJd׶갱U-8m~i|eyox*(j84ϸbxOP|c;09wm_*unec c t6Tz;wSC2sP 'f][\߅SI y2VrtAO&B_vrp@c[!&yB&19 -%r}A; gۥ@`"`n\݅I:bkL TZ*ZX o\?)a}*Khՙ -5:v/z@bq 6|pV|o. ayz$ԍrpv8:HWac'Eh/!0Dg((q|Ki87U}I!CE9âTD =SsD?)#LjXߝ0W-j@(и!G mJKԕn \m,AaO-@xAⴼ~L7.{7([CMAGJyLE|S#Jipͳn !јcM.ڏFGRaMey`S⣹<'H" nFtqzl62 L}AL5T_WJ&n|aԩ(4Wă ^JLG[;V]hG|%9}kCu#c \hzBRsrS'`,]skYIz(3REqTephq>&"}(aݕfS0%.(na k;j:Wqt9IV]I-Ke̔,ϪO eK.TD YEl_Jm96vE4U g:AV0$Y m[D‡baһ+11LԼNxSo  NBoAfG:wv0f3} -n&Nc\ȣj{;:`vܥl: \Lí2Q3eW kW"p+UkkL6=6=JM'1w^w!H<`Z\WmH'(wf>@tԀ53jD'Pψ^ "F;3y<@uU ̢OǾu$?9%dLaJW>_o?yq?A>)DMR[ڰStDܙݯC\ c dF9$@/Q C0|^LDjO~zA ?5,4y; )#xm(c.,.!G/vsKǯ/V}::L,;0ñ̀|  '+-B76bmʡTFI<\u$C èϪ+H0RV@Iǀ{KuK9[3k+iμQyH -1V:1[P@_ٲ_"@{aCyOm$ݷ-C"3cX >Duy\J2iQO@]3&K3SLrpMU*?7!1( [[lF5x5vlUҷqm귬nejk`tʀ?UDkre[5LaKۼX9 v8 -y MNLu? \ENb/e:ʇ$n!eZmbBD\SC~ >>tꝷ)S;=ՓkjZ/'5d7;<<0z} -fFقr#N\xuD_=MRsk7bDom S'}P΁s_i%xu19JiO~G#FYg;߲#-_92aSg } $'%rwV@ŚI\Qcr3UtmS' |[Jm ;BbO?B i'uWJK3RoYS4p%JΪ -YU.k -bBin#X:&>T[#!8XKU2EScAN~ϳhΖ7݈Ԋ+1qcO`Rj` @1P$~D*CR'/3NQgq1g0 BL2)%ZqH"8D -[`k#1PeqI湰 >YP(AuyM2 f@; 7v@Ƿ{<"wRPsP *#JiC4ϊ;ѿ-$(Ք ho(," z̃癝?/-EaiW[7qAy5 WfL{4 6O:I dгgVK.&Mp2`6j5Y-B)0lW :Žј L~2MrVyN X>f n_WFhBhL8>2B^+= -fm%\6_4Jl)6X"xyHN&[O S񒒬haVoߤ9ܴ@b3S[a6ұ́)U9".K%KUUxIB=pkdg 4.1y@}c"=T<}3fNxjwL(,DKou&Ě O(+<%vV>?!p\xخ4NKÅ? qAo_K1Mx;Ԫ"U(Uq"z(# J?!v 6/¹!gБNĠ'g=7GD }6Dmo[dBX*y)eu?k%|D OC\X`k幍!+; 32]A(J }T_gڜGyۂd iċy iQ36DvV]XxcgClݓN*΃{ TSAiWafZyri+F"Ch=>#s]cFn -hW2n57OzbAŇ̉Th fեD$,|8QVhPIp'@7hy?TxbD}n%4 Iw52acEW#>($aGur%@G%B7KU86WoG~I`ehqd$J,@~^KhWNs>0bIL),phx<[@zұd$|8UOranpKPcr h*@zq3 -Alܩl}9PpQ WK:E-| ջY)l-5;B!r@Tg1QTHz'E|%B(mTa(uW}cnNj7m9ʈUo9'KƧ`s>f{u&uQ'mGX ɭ/c!ߓg//7K)mO\4=4̘%0V 08*#1P-GV@Pt xU -$PqQ4t (,P4޲r!Lg͌t)IVUU*$oX 1zSc |$Fړtku -fJ0r3GZmJzH B? ,вȌľje!w("7rf84zՌO;+TeiqCT&Rs.ϟjՈg_P!-[elpV*b{v2\ں*(zex쌢[z1zte-(䈉 00sx\gYGS7'<\n=Pʢ$Seg8] {t` ! ,cbK)]'=J2%f8K2:v8[ ):+9=I$eJx-6#Mv5H"iց+^.i ɷ'Q_"#YI̘1G2RTXЬ"R2L d'RG[``>}V,_Sl2d=@iuJQ|ɡVfֱ/{RpY=HM$s4ʫ5]VăinNtcÓ l `9Q#2Rk7" !(Q? O\JɨY(Y/z``qnkFa^c?zᱪ(;Jw#y.$ M IE2½Z Ŧ%U$V^$'y+B14`VeաI2u4͐$C/̰OlPd -7tI^܋4$9L䝀R:SLo.ݴ짒(ṲukM]u<~_NbhP`|DQXW`a0irl@ P-bX^ ƹ5JK^l.nZoTk%t#R0|w|Tħ_*.Tg],(Pq4M `J7".Jy{ 'Xr J]KӾ1ebaQW71!-`hK(6|j_&.N @y}GFYȋ+P%LΏ~a1t)fVl=x% -v۞2Ԃ(+cԋ߭&3$Fݘr˕ʥSz{ N>TVc܎Vrh)d69om!U* x ~iRޠzCbnj@u1W3iFO*^{CZeߕs06 K:c;Ax*~`u+"5NMǝF'k"BՓ ^۾Oi\߷Hq&Zp@ab}: >[ﺋT ͿfgLB%Ms<i 2Ex>a/50=d -BΤQ՞9{_IS6 wSG @c)H2\g28p< dG[ܾH*sFmw[Nqj3dzN)ORJ*,Ғ.tvƫDUmJ_ ʽ_G ;fwU#ƪƹWwK0`+Τ!=i,-f L^ 37i&衸jn+#Z j( |EX!٢d+ z7t7`(=n}AM0(~MΗy[tKnGpaL̻IhSvuXS i -ld$maZlyca7pI chJC #x܄MK^XnBzO\Phq#͔th){P t^&t5boieѭ]b'vv#o!sꖧg T9*~[-;UFd}(^=촍#0?QZH&48;;1y).IoK`L -ژ;M!w 5V&`;kk }o'5y9GfriU%_n ޻m]%rs-ٛ,0<0=kZbΜa!l#ICmd.@_RGaD2I)Ɖ&(rTVq}cE+eg׶ nD8@g4CMl #OQɗ%G1О.TYD{ܴH viwnOl8ce&G!)N7a!W̯&#=\M}p1N%'uշlxȡ9 -A7:3g}sίl">=9c!ȏ↾+~v͐X$Z!P8M@vxR7 A}w\!J5%@s\φCp~iGe~^FGJ#L|Nx~ sLQ~VXEIم6>RYm֏ICۓ`VQLɂkOʆ4](޲/*7 ^ZƻL#DW-y8 WL:R ` k~?ӟ;`@Kx3 -٦$̙?.[g%pZfʢvdL`IPnG>2o2%ْp-b͖M,ӆ@8m>3 -ä_'̌ۻ(!d^+Z(L2f` 'Zau*>b"Ҝ\2էϞ!{=~ -/Zbuy?raQ:Zm@J= MM}IϒZLd\U3Vn_~-I聯jZq5Awmn?NP&VfTng8VKT[ dM2@Y{āDȹ̘Zr#z[ 1f{is -MHx51H" -*4Q`E('RN폏rasғG)zchlx R&jŰIߑ84ͻ4j%Ƴ~- K:N^vimb]k">tހF&)fI/7O/ bSX{q痕n禨!'{zH8urI3|yJqǵu#\XFKJwb`f.vs#{K[P,JLNLĒ e"t|GS޼M<))$O~ -Xjm*v>/I@P>U8 -Ȋ9y C2%= \qګpJycܝk(x*h-U7:]@RßUR10jPU8(,yD|4Щ|sOO%kF:*uE6 =J{eL2AQDs'ʦa4ushN NȏKLP -ug Q -x5LB@K3p"an]Hy_\?QduhQpQ2RV˧ -Jj/9us)މp#Ɇ.7k9('"q3WyցC :I?;-4KjE]lh7ixBzD J(2&sǀa>p©4[C -mj%{C<p:lphqzfjlpŭǪ+?K`$UQ_Ő!;BPj( mjNBWDTOqC9erh:i+-)5en}Aa$Cb&d&+64le tKHxo(a2P -A0(3Y-ħpO><#ɲ|M^i!XNzSiܕ;iwSJ[|af٤XvI)9yRJ чa`Gg7!Ttf0T}jpVbW#a{ -4EwwMh?B:$BPz(~0| M?Bu%7;" YmtlxB$FEodZv&wG\cevkp#Q/|c|c~ -(XhL^+d87g{ń -GIT^]gwRXN s$w6BWT!NHA@Xs{rXÿri~@ gw yҬNHx3*?ۈ` `*)>^崦P&o[Ke)Kk VX R&WPL2>jgj;L_fR̘I)֍} dB-詅}:'ܚcMV˶a{,L 1$4N% 8^:jp.s Y}6ӈk%+a~T77la2jV` c;Wٖ"S.:Qg;,琼0Ҋwē aA8{$gСH9`[3Ajȥ)Ab)eviB'7hJ:I@%ˋ %!w,˄ >|au !3Thy;Tfg='ލhӑ+'~dVj2xԻH{*t6dd}G%aD-jaV0<v/Qčp)?WA!$=&%EĘsVΞgk$!A8ڿhs{՟W V43c?2tE@}s -J090ks;t-ͷ -Dږ2h!&@A}6QVip?3$Y0IBOL -*9W$eNd0Hj&_Pи2?s w1h"vRUŵ4+҇Vv-{Ȁߛ|cbόaʐ ADo ^NLMXwrm`\ICkųjYrEq#i^.C9RJ7-EIbLumhGdl!\?hDv&weCthMH&0lġ@7':3=Rc&b(CLM,hLF2Ů܀CfBOnjYz('UD#C"&= аaKdV@y fؖ.:f% D8*;mk -4jPOKSG{Μjqio⏗yoOܭ>@JKfW9<}1 mP(PuK 'vN!'c4@JWOcY]8`ώwjp;-0Q -60: wm|fֺk&-0$ ^׏4l O[>ۜDk]0jd*ck`)#5.M'nJv$lDt LM,(a1T0CF*I`'~9%"Ц.9kxXb2`rRdPn(_\LufoJmsJ Y 2bKxaU!Ue< rnWӬ>Xܸ֢7V,I&1J"?, @gQØ, zOtyu>F -|=DxnPBfc3;yeȑO=XCa䛪?l'A&Q4iQuL_!AIP=&DѳՎ=.Dd.K&ԆVU{Q F/N2M"y2tRT#:F21n) Z pB0m0 -ѩT@PbL T$iCPR̙@ZNPb7.cueO )Y, h$Q1HITi`|9#cupEX"oRq0ĂҰFG&@3xP|SRUڔaS#.r3`׃pM5L] 2dW֩ƈzDoЫ&Ќ'_ȟ-Jb!Y3d"80| ۖrTTM)*yi'ѝ{R(Ѳ15jqh\\f'lqI!{WZUTJ,~l4YgQw}"(Ut/ =B!9!{"|49"t9I[Z=Sk߱ j}`m7PjElec\'r-oy2EWJF\ƌ΢r:F>`8{A - -K&]۸_/55;e2-8Y~gi&-&#E+g ` -idZNVbtҪXGQiXL7Zxi DP*rȱnb !  MUw3=7ɒa$.c%3!6F ZEǸc&W90r5E@MXJ&/ 5ګY7*Oӏs ;%PkLg{eɴ+;x*Ŏ%d+]ehd1[cnDI) @$[DEd 2HFqnQOZzwS|oX9--=of.a oȸ i#3&OxAC "ay]'1JsĬȃG)L,hGs -+57Հ"$Yij$LȜSᇔ58W7CO)3q83hp$(էKɯ@Fh&,adH4iLrZ}j%S0QɌ^d(5\%RT1'i(dh3пXuѪ)[4$blRp%BaEj~eq}ZFS3y5[&C7|<@^ׂ AW@ AlZ8]j(t{gJI ս*!?0\РpIh0mpMɝ4r^$r#zRψCg ~tX LB$PX]pƻ$.Kl0\_8^aw歽G 10, -'|ײx1{ւ(됐0a|`*۸Q">qc=yƃN"l4BY0>R(58q_j('y] C/POG\c+֩9@a嘱j<^<ӻaRJqod6W gE[ @R XDL ~_tm[L+Td%2J\ cӚ7N Ե-` $D/yOF#DrͽWA mjp2Z -&5gQJ')bPQEOHgh씳ъ$9Xhot5^` 'Lx]E-Ҝ,|xPA3j`_xIL) pE)Tdk@? z*iKtCbZ18 d{+JlB]7UxHN%}:^fg:?<+☴(ӻY?=Ī<*"9{`b vYc@w2m7tG˟Aujv9U/4٭FƸz7Gy<E235;*qHb/$p(%8%UFdZekĞycJ`l"3 -8+]l+VniBF~{y/3;PZZ7rp%LN_G+N$ؤq,f_2shYH4x> \#n@ӟgAG ->Yu'BV0D;XgV9a!*MZg65UC%jd_IE!dOemx'Zy)[aġF^"ҪO͔aM3Av=]F\,h%W :~=Q]-iN& y|nHXTZ𕅠e ؘ2x8EIYe_8Q@~F:06FAVA Vg7f-'q;EZl$֙.ӝ~ 6#d{;־ -ODF 04e^h3E0!J6Lq墨LDM\=FD|6w 3x#VZYcG&.a8S~zH*̌ `;M pD0S`^SPl/O$׉}Fp -b#V&f_@&`n{zg,%XA -. -^gĚ8ѰpP^CػYm7i_m6EqgЇPbѿ8 S+DN۰c ׆u/ĝJ_7y(m ˀ Dnw\%jab>?@`m׿^ڂj6*e>mʘ:rZ)Ph҄zDY74!O/6Y $(hݐxu&Y]yd!ϭDH_z01@ d<|a,9ƥ&n"w˘MUxp;蜘]>S%TI KF&3 ͬwې7xю\w{LD;c̠&5YT~49@fw8>XOtЍޞ[[n?l\W\:t4sEQxaLk@v.&-"UZiIBWvr4yF2(效BCZV{W,f5UaP3XQ0<ɩ"|Qa-ݱab-s7Pj[r}¡0}EbZސĴU)aa]EUYGKR 1fwLݟa%& -BjHNX;YI {K'h W̒ 5Mv b, 3_Ȗ 8;Hfr:ucd˾r8Ӫѣw9b%J hQ?s9f/8άgM݄\q#)OFLUtc+I`j C!,qsfTt13&R0ޞDcYMVxnQ,Qbs -O -"~PUX ۅٳ*Y _U< L,M3_T&a邷(L1}L}6 -p PHakxۂ -C2H"NbR*!,he >ؘTSVA\X  6 -G< 0=Z+G̱-l@z̉-T]8JiR d1G*RO7rһS(^ƴEu[h 3+0c=!zګcGG=k&/v^8Gc3zŞ|;832ؾl "sa#0V.5%$LrrI#8_p]D-+)n@V?Vy2*6:CYE2ӹ8(%o^^ Xݎ~֔} 3B.V ~+֛:sx#^Y: W2 aP7etG+"ݰjgubzxl`D z~bӴ,"*>q@7`*z%CGÍ"v hGb05q6ԬVR&, ~q ;YK^ gv:z%=+U7P*Ixfs"f7,Ťz$ne"Y`PKV4~帹nrPž~.%oή -ì=|p7ru) QK+V݄:jK, )+5>0ʝ%4^V5gVRQpF(X]ɸ[Ä)G_~zuv{)#C`DZ$.8?4gӾJf9ϵR#8R݃Ea7H\LClG-cM.7mi4~cn;^F4uǰ' л‚ -N^}H#oLTG@DO -O > H}_iYବEZvhc5ip57&W}X,i3[i5\í;"l~uS׋"-)OSX\mCP{񹅱3Zeְ;cY&0+3lGY1\XAtXF}[Cn:t| u&DnX:uq}t1j},Ӣ+hee]}i{t72+whfߘvMw0wu^p;r^"㮮ws/CҴvsnV3ni:2/wX]cfAt Ǖ]wkVje♽Ygu(t;˵Xnkz.ZjCVha,9[o -hfI)"|V-?;QSRZMja԰;s ӵ2&YMŮWv\VDh["AwҾ.VX˾b =m _^f-o; vк$q9:j"틭ԱVCu:j9$HqV޷UY0w^=˺(f~P/{t2؅DXe;ٲvws부}][0JWЊ68DB4fUNcֶm*btk5cgo_jC3 zfXНQkbpZlNW"uj_l,Xl>XK_@O~+}o Gc}ܹEo b}]Yfэ%%CheմxJrDQ$۟~oKg%S4K$yy%i{7QqII䨹Od}~nvO(澓s}7'}Oҋ쟣Oݛeyn$Mn&$Jwg}OOre4?hG˾=Iܞ4yy$Pews/p|56~non5ɓ'/=?K^rңe4Rf?In%/M;'}YNc}9;7i%Yz_&~qߗf%/w/??7ұ6ɒ|o?'Izq~wl7/7.=ڷ.vO$ܻOޡw{5?˒?In$4w'EǩK<$<$~$}I~%ymrߥODIM~}S]}~%I~4Q^)O7wl:TN$Y|D˾9''jYn~%in4)n"yG;&Q4/~~wwYzs{4ҟvl"Q{_;';7;y$Yѽ?MnoD7'I{[DOѽDQӑ8uul-=Ygܛ(ߛ;2Fnot;Tpw(ɓ4M^ +@v^OeNWrl |y8nuLa_T{ccs ϱڕeKs$;%K9~վ;<ݕDQw*]بnB+Wv7=i(iyS-8} }Gf> ŶK FYR[i8qĵ 7E#25XiLօX"8Kᆠx '*3)J cf*$Ԅ{tY@f*|@ j!Y;Y;Ȩj`8 Nc@4 ?)A+i :d 0 bVc@s'2\a0{a P >rzdJ #&KB, v"R=$ 7cIiEuUET4C ֐ -R! SY |6 f Z -F(( $F"7 ,=Q{b'lEͳͫxiRX#&\^Z^~-< YA=⦷$J(|ݼGkM{Om{W6zK()GZD =AxqrPֽ0x;sq&P^M⌸ *$T<:Eμ[(k#T(-1z4M_! e -I8`EbS&rKlc/͈j&2#mH*1ۉj0D(\^7/9 %4_k6paq*)ΥҨdq-b`0`= ؂&i)Ɋ0N•M&7`9)N?] xX\yf |+<#x 4Dlt qaZG'0`Z{"L_&} "e&EvP*mE:f]QXЖ(mn -+<ϣ qQD*<yLeFDy3<~̐y7CMZ0`Y 96!d! .͞ax` IV3N|<Ao>.ѵNy-:X܉g5+d ޴;+,r-g+{۴ؐZW&c2RG[}sk]`pvv_Z%]L-mf7s51oVYW<"yΫv^Z<^1oDnñz19R -  +Y֡.,5w 2t~0b:ڍ]Kߺ'n}e[,};]\w[,`.+n;} hizԉf;׍u0`7Kwp;@G`[Yݵ3۵t;Vzd-Krf+\" 2p~t(}rM_^bM4;8_\1Ft˶26n DW<@%4t52IKJD<:X v\eYlelgƯ5,oMg,˰̥[\]eU+ha.ί={~^E L"l~2m gϲ,oMV.]u`}uc\{0xӴr$$2ځvEVxߣNEƻEh0][#VCOZ_ak08HE]6qwQV{9q -T)+ -e%'Nq9 KB[# !ﭒ9Xxbx`9Wbp6k5A)ŕkh"of=U@؍G"V)b7ó(a9O4 3DU_Dz DtLNCTQ xRQe! 6Xһ:< VSOLvkJD&h816D4d7?72ILQi2 ]+Zi*w$}՘BTc$"pά\f֚eKuSx̖*J% \Ux,!|O+R^wR *4AIF4:1iMG# F{U۪*(8m}ͳ!S2-V?bۭ m`ȡ=YdBYdX~sgx) OۘZo7cj &HC 2hU+'D}8T>n@]< -xk^X"hUWQي!NÏ)W4?B$GLnc ֳْgiCk<L@i+ <4\X~\I0]i('pЮ5]k?ө_!CaG LK@+,Ƴ$ ֲ-) ?nbb-phl؎IkR -\8!jXȬ?(N J" OYhMX/) -JT8 pc]PZpǏO~>˲B˲=MW) 'oFIX 8aI|4 ?p'M@9M, `[E(pUS[T%9eepڞ6)ToP#z8F3l HJ:5%g|:ZNjgzP(BIB$Bl>P'p"Q< ʏ7B[" px h>7#rңh8 3]J@5^,& OM^80KxY;#Խ= eFs#.9@FyqyyqƊ 2˖›r (D iS.Z!x3acraX:<)$*ᣘଂD4 xL$4ULtSe$[fH ܉A" eBQRhn@^ojX"fPfAsƎ4T\^ޫy^ͳaH`јRt9Wvk4aD"%olL5x_6XQ(YԪbg9Ge`q;Ǎ"Ι",`jsd%`~8ۢۯ)!s4Oe=1"V'ǁ&b3,;ddڏ.hr#p@h/#!]ԀFJx ɀjRÊ/(f#&Uow]DDr՘~cQ2 u^VjqCB6ыfZ -lPgd!Hvs - >n׶) ʏøqe&Ckid*u"Mm0(Q -Uxx6@'TLZ*B!DV3K3jA*& ?t|WaodR&u1@`ݭH$$@&UĮlӉܐb~.R94kw`8@2[ЌWp;M5 oƋg%ěL[ qg75h<Ӛ -? WAjʣՖe7Rn⑎Su-C("7_O< g7|bǕ49t, ɓcܲiYv P -1CӒfc-%bz <4iVvq'25f$ţx\X9X^{&?sPg2y/*5T$c"0A7բ!G(UB-EӲ:L]vbDHq &ϫ?s- d9nӎMXh`hl"EŧAM8n_ =Hl4ZgkvhaW.KtHWnP@rQC']1X}z5!s+zoq/+F%oĵh&b_p( 0WZ5=?4͌LH4[@iL)>Π.j1CtH3c?b&cBw/-v3:c C%J{/C#՜r!f#<\nl`K$ȃM.UV-BZb(!Lw:Aɒ+*M3R -S+p?5TZP+Ϡt4JM ^$Dl!sYO(5RMN&^Îi@e)M46)PdǑ!ɡ4@)Ht!qh <@BE% H/e) -SO$: 4QCz' dh{Ft(>|qb*Sjz\<v=IN߫IQوIQpAQg&3Cǐ l;mTnHaв|ܭ|R=F iN 1*aZ}Ŭ@i<ȎxCX3C"3$醄#?n?ICY66OCWZ"255(0`4"ZULnW`2iP"Y~]$$r7).0PpGNTJYIÉHiI\wt?4)CuNS% )oFp -34#Vu4*#ѪRkLO{ "q0:K'!x!'4 o۹Kt# .h}}\ba?@1*U>&S 1 sir3HB$%} xj$C&29 e.ķrHI ӹ5!X?5v(>L[<‘lyC䓖 -|d}%e%,ONy8{&A7uZ{~Z SNojF2!qd#;RF;lKjQRxM'E#v` =4X{U_Q'lY6bв>,{wq︁s~l4> G+?MMM U"T LÝiUW`+hUtEБ6#;iCzx A"ኵ/'TS6Cl,? v5XjOC vϧ -+>"'LjK}`= ϲ0*.iT,.ԐwL4'Ā<]!i NA˲AOC?>? kOܡxq&.L‹'>? P|9秡(,|C.HYG+aU9Y[T0$5q-XAVJD`idԁUi5him9 =\qǐ?n@^,[1U0igƎ;f7j(p7YWm,V~XKLBpвl$F@p|4JK# DX:E2H4 BIJDž||( jb,<6c%~ ayŴ{A5h;f$yXq8#RF/8ӁtnDž -<Vֶ6iϺ5n\ٓOʖ,^FH$ -O30Kx4 V .lbdL)oi iA.8 ~zd- ojȈS<P([~ȃr}Ut3T(׍y*[T6!&d)$6v\P\AO0<8%8% ?ɲ࣍MwAˀD y$>J&{h I\5ߛŌhl)~u>,606啒mq̲%6PSUi3=)^[8h;(x--’ rƏU -3n4 -ޢ(8²{~zkKPM7T%hC3.g:rj(媀Ǽl5UmXfyD:T -DZn y֚YӐv,[E˲Ue*mw}N>Yd>G>#g>,o063151ROCX6ZuIY&EƲXyiq^+H48NF !0xApSLPh9:vЁ8\0,KEr=/ʺH#*{*t"eD }e Ty O~o]eTbU$ Dp9AAI3>+ぱ^!<B+R+& 32>5^ -hUa9#g,"+"UOƶzQǙL hRRKr媀vt=IQINRb[>y$H6Cl#l@p4:&ŤudPSdo9~1zxgȅA8z̮EaHJa83SB?0S5 /imGxԢDrEfYdk%\8ep/'N)+JqpƓI Y Zoq^Q(ᜠೖUjM87(E"P߿^C&.`rE@N<2 /Zt8Ej9AIaвlX%ecR! -I&%(Q9m"r#$DL>Όb廟&rl<湑x~ͨ%G4Z &IW4v)2Idt73kMg3\ɖVD2hj f'YMQ)#TEF{1i]D\=O$2Lв<,[y4d|#7 `j xacj?j]&'#\ - $ @-U}3XBЌs IŒ\KiF$H<@40$I0,1( R -;o_$获^+>k{3r7=?=N6]/t] qL.9OK;~+vF6d޳1P18sB1DƼj:;ưAR;^XZ07ƀG_KcLDƱ= lSihVQ(2P YA[V!9CA_ X1sV'R#}B;DnoYg"Bwx-$J$EX^ 1ڮ>\rw)݃Q nCEN$jN+U{䍑<,]+ۤn^>i09@ixqyIƚiF*HM:>6ķC36j J&H'SjLqf6 "V%8_jqRqy~kO eVCEӀ^xd2tn[jxzK zi֜뺐q{%]o*Kˤ;6r$]R[`ZNt`4uy#T,(R]'m{»OU5GH P]|j72~Lfs 3|%3L:?igi. i!5ܠ;~^hO*Q"bO-avSdହS=mblgSU6JVbJ -رuE`;Мv7}5s.@2/?θdψTr!0_zXa&c_C:}b1 PD2[צ"qTVS^Yk`YuYBf4YRK DW1l+C){;"k0M)V5;J|f 8:Z1Qsnċz,y"SStlMOT \9055Ս_Y-4.S&oء &sqxxc}ã&4]O5p{MXAaOX3=E2GZƬ W2vo>ԯ -U45Th55ޭ<jHIf/tEr(=r]&c`X[/1cdb,ݐ^Z 'f.My f4,>^扜:i-rs4*8ˡz"T㔺‹f(^}MApq%/rJ8ymb/F&HAPㆬb Uh˫~6f1F]O1S9b;RNMod$;dJEBS:JI1$W:p3 /0(Mo^Hּ-2 ͘A'Bz:Vf^ƒiDhXeTȜ=Lح rV6o,K0#K!ez[A2/s/eUAr2i4zf'Ny+uI[0n&wu浆4sܼ{^})[Ijk_âRm 5k@n G aʇu҃%V71;mfoAr\,(+l9 bV9>44Ku-˩tb}<_ T잤hY%jᷮ0?ru!|h g8딮i |0 )6 0tV/T#ᗡJV 6SߤLͻO[Q/g!`,qTbkf4\FXo~}1*#[po"Ecf mydي /T T!r5-[L~RܩqD^_ -mEs X;t)]%wkah<+,%RƎu >w@k~j2@?¬`X ;k抪< -GJ - B*G>.2 -ϛ^ɍTcE6ƌi}~{4_QȓgA#wM˕j2ݢZKaHM@H7ӈj1 dqdCBamUEKS'ޖ}$M*-T!T@ڨaL"Ӕs(|kNW 2GEcjco]kr܆ċjSpHGaz>J*,!|]3 F[ -=[%|"2+%]|vBH<;/[8ig96|Tdf>ߕ^b\:WAN"..6i+&VJԛEUϚGU솻3k)H3JD7C*wR-'좙RGpb!zgWu8E>k7>F\?ц˴1J؂ Sb"\xI$!)עb] GjQ3c!،\B#TKI֨!¸ϟgƍ YQ\8b)3`o;!PnE3Eie+\ [!W'B\$[>GM`Tm`$ ҳ-Q5̘0j-?%L3DА =>V;))Œd(U/gldznG>;;J^^'᪷7U.cLPU -xv4k"CMZa|Qzҏe9 ×?tq!]{Y&^,1głrJ [At]ц .igw[B/,SMeyzZ1fp"+_T.X YuN#nwڵQpwαbBri \3bE/ ҉<0XBB)ԢEGʾ㾻M֨=b9w7 7]w@kP/ݵ#Ov`Gv_g7)yla`06$]V4k]w!ȂTL!qI2$,޽pWŖy_{wf:O5uéTHSgYlg -tp{lHCj2^uWb\jL־5ɣh`;LڵI9! D%d3&i&x~xSpϚ8\*ɂw#\H Ae:*(#E#HJ -B\@a}=渼Ơn 1lgڢ}Z 8ʔTߌ^wsK,hC1VtUeMwIo[ڈc0Rg²A`0\y1Colsu$8Ao *^wu=Ґ:g}ŞB=\#U7o(}Rf>)4 }aY_7-/d`j9W< -Ci;.Ÿ!P^!SD8ЌE_ >HmRK'a~\ tR9=hr=-B`\M-mnBm!^ArC5 WELR$ђp?EoRw84PBwlZvP_yhK64&-?kQ.y~S5@E@EÍ'^ ƺh PuV(YJgS93O%,CcR6d]-эtF!J{]aRn'CD#H}|Ls&'JPw*73 㳷J_ -d!Dqav;HLo}lS> ~=x2㈖HMio-6[ N\qN 7šVyrx *Ƭ!5&ps;5p֏S`2,Gy)[VRĔULCBmS6Dg7uC9%oBwoGX?$bv)`zBf"׆h|e^-!Pt-j\UŊ<3Kn#I6Y&"2 ->p1̠o" HW͕P虅v 9HC]FE abFT٭(33J0],(2p)83Mtr*UkIda@_v38}eg;0ݘ{! [}Gt^t)0rnt#J?Kf.QsNԒZ#]2,vSqDDIklKGq~t(,h.cZz^N?ʘπຑ]_+p2)͑K@oɴe Q21EwzSKi6zvu%@qlZ]`B30k!IY8)y`Cʂ?}[jSמ|I|v&!d:h" -!8Xr`AFR,1I!2@(\`zf=z\=]p33-Mtt2cLm9NzjwZ_!G(xD}ZSWPņSf]`,71A|7aYZ(R+'k ?/Fq 09d -_܇r?EY7;zp~g Sܡ%)̰BsSxzQ~Ǎq}h'J?-? jsC:i.8m Qgz|2woibP*}0-Oa17fX]꾀ʧLwvQ\wPx^O<rOi,W:$޻\- wĎCU7}Q㚬{ C j%ldqr*fZk&YvY F? `C1n'˫S oXdCѸ%H`w0Oro˘_įL+Wʖx#%u+%녺nW<`6GvW| ,Kom wLu9mq[v(c'hs과ڱ Fׯ ms1/8yz)p#RLhڬψ5$9 TO>_︕S7>fFZe J@\#khA[J>R(vjT;*dJ~cPkƁ|hnT-H^#׸-D?a1v}ሉXƅ?<}Kf|U#lqeQ˺u&j&íɪ9>;ZԵLۇ] ?`ϳ"9|o|=Xp&<4šGczeb `U{$0k?6ぎx>_!jKnUK /owhJ ߕܝW ajmH%5 >\.sG dNrRqeG5g`] X;rQM,.*T|] )75`5q'╓sS4 -ǟ[ o!TۙEtꞁ6j.aFclOEe_l9aN;5JkZB$jx+ ɢ'f3vYM;#3*Ǔ, endstream endobj 22 0 obj <>stream -b3Wu7wޮ7xa -9k -սy)|s.KF*τ$$|UT^ڗe%A[Y"6|ֵzek -t -FOC| Oa eҟ%eѭ,Y*$Ǧ*n z6 wj0W"o둱~ʊJϜ8Vsa*/i©U~w) -phe."u{OP=U_;8ztYxFXd13JY]:Ȼ_eZYT"lj^?4 XF7zu-k8m?#S[M|t 2/"p_v@!CSɕ:nW#In.+H%D8_zHI(!>cDcn6wG0pֿEo3Jy8]ż& p΄Cͣc򹏁 BSwɜl1U'hPqx)Ϗ^,;X߃p4+PZ` "랼 jxo'ZSlDdUPB*|ӆJGCM3~BeX;~[`!$H`<uۑud6:'T-R谡ݶz,CTbPRM8{8Tj4MUc19tNV~+˴j53‘8(A2o(4j W_Z&Ӄ(~t~|l6a}s|,t--DC0,j'MZ0V".`z؀5Px`I*gWhfXlIs?euvMRN_8i2,7eO+lCTm z~m&7y6{.uN얾 {] =wYً=ha"/$ -<@fP*H veʗB)|D,5cRx8⵨|wf{JLb`1DBHJkiVsk1cey!!4^=qtr8Tϒшk#-/tyCj6QCo%Q+C yrmR֫]B5jLdE{85r|sKB2d%0TƁ-_Ӥb5Dpxs5oL k"")jWm[<БM -OAqH9;0:6ɴ8j2 g΢f-Xw - >nJ (cx W s%Q."r@\U҅FĞwȿ#Bf׶}0A5mc DyZ@5{ujzRыIyT`P`:ϻL$x iaY7HC!jS.% -j`gj5;S_xU_/;r%}m~_gwb?;ʸR:h} AB@ZsJC B]+† -F/8ᶥ!!H~Lך?ܔK\S'i39~XNyX͑gSWAAdIݓ.]n$&Q%7I\f0xV"{L3lWGZ = mMH|ֶEC< )s6I d)ϕ*b_Rݨ&$IM#?z} R -? -?vOLJu3Lk2R =5<]'!"HOW\p78D/IXD>3 Ӣ$ϩU*Xh~bA0#؃9 $==a̤JU5Ԛr ź -3 4S8:xqx0%IML+MJBALsTƴm[`=vEd4O3vuME -YD!* &ݰl ȗTRu]Jy~h.\f g@SB1>>|zt`'z<7  qZPFRD8mrȼ቗usTxx]} k<*suEb#Eml)xEG}Pzfʆ psVB_7%#OrȴjCXTzPeEa~t[z\zp]W6U|Q3vsU.woT<20j7*Y7:0!:^CxdH9dkяV#=HKsL>*IJve咋I@ -v, *xސKK?8-Uhs`6 -(BY-cQ8?X*@# Tw]^C:]xfrFbrKt@ia gvhI:e4}`FB3PH< 8 dCy"!3cxpnr( ^kqL\ ]A:,rkxl#pilVwaR+)DjhWE'0m 2M מh_rfs2NL0k:4Ժ9[NRHހ@ ng$rĨ9F'ǶkRցm#͢ yh 8;z(/J'$=4ǢJX-%JMUnk93:y!W$'~':kʚX}#N8OvZ`.n@k Ol4nV9?$]: (HÓēeP Iz'nVh~; w* `1wmfHzrC;+dloCGmp|o]'*Q&o^@ 0 ~U(WU;Fk.OMD֊i6d$AQ.Xu'ݝVB/o0 |oBm(y'l fT p܉7qFv5?vڦ͆GW4!ԊFZ4W٤X:T Fd9P;Cj$K![% -kSy#Gg|w`sh4+6gPY,Tq :0 -1LU O*ʷjlju,$Tbo F\Rv3>$KƚDzGtцbz5~)I80q(U@M[ҋ`0]ݦnvRDO(7SCH :n)F1)Bq=K?XD"bאmZ^KnUݤ^T-|,{ -bZ"k7V?Ilj aa#1nHzK㶐| 0 p_)==TN냟>~;97$@RbD*{3 N%k"Nvd5)*W1!zt] oiسMt'<><ݘ!.b -Ph,';"K gw}4Ks nP>5d##ai<)VN{͙u~Q (B^BHl}r9p@~TV5I ͮpFֈqwEk+mY}OYAbƾM8(LQfA ݫ={{",ț`Xσ+L\Dw:+&XHJZLTNThC -rBEb3q;7+6Y4~I,#Uv+ϒs؞H0kQ\NhkŒ%.dҲRH#ߎZ#qdpQ<E_N×YWi2+PQ;r7FpbY# i0X,X6ьГ0 ,3qo2_]U|{aLLjx;F?Gf OD c+VkiZЉ6گ) -_#=LҨ k])1azLxwiV†QEoǒVxMD%r4*D*15'm;r9JD{TRK-1o:BϠ8ND."@36-o)SSA\k %4-.%Zָ~dpJsgf$ZJHPS7KLk^keY4o[{>e -B<̦e$ F3|%贰wܗ7X@oE>mꜴu"lI?ǘfEk'Д=Ψ:$ܜIqAN `8Ȭc#tf.[,q "'s ",Hԑp#B6){äv۴s\WϏ=rgԿzL8AfJh ~]Q4(zZ.ThAг[ \^WӑL_6`BuH A{X5m(Z}2vUve lQVxPCyue|Ex6&DZiT^;. - -\'/k2ݿ@L ןvX$AB7niR/9ЌQʹRebCGˀhQt) 30Q$A)3(K;>L4.֖gE 8L|AZYy}Ht54tnquyy9BJab - !=ə ؼPA$>a`1鬖Kjf]#pchϭeLD5=b1" قè]V>:6"Nl=ϰ'#rlO|m|ZGk͜W7PQ6:M:xY,%c&~aygKI@e:Q P37F!.#HJgnaA>љv@!1u^!CT\ >T(=mgd嘕; -WwW/~19Dzx&ݾ1C)t5fВzr_ȾE0>O/¨  BD cu#R笈mei-cVA%.'؈$Oǰ$cTr_egߟEms2ݒc,LI!\C@@,CZy"Q̄+Wfgʔ0ָ|Wxr𱛐v rw{iR!ӘߑFY<%MbPd@¦T<.r)[-~965GU\NJj;)@8n/* ўKc ~[a ,XP[ -iܪFij(E,"s|ze?0mI=͞iTki{Shhd?\* bv4Qk?S` -rSXچ(/uEN(q6z#Bzl8з@7)iM {r&Ǭglޔ}hPH"+c$|v7ʄ 줃M CE5k8ZU_G\I+*cYK&)i {Uxpq0T"-r :%dpJղWPB0t8u^\7RύpiC֎hRP$)Ӊߦ+h7Njpnۖ @\٦cʼn `SujBK1#~LA.mg <1TU&cw݆"֦y"h8"Ȯt QZFb~1C 7VVLU`ьwϱgB8e; -ĸ<3w|:5I}8[J+9Rdd"Q7F_>Qب6 e\&rw _%lJo*C%jV:8*`} llq8 =r0~ԕp.$3rMV$4X #cF㤍 - 3eqc  H2%Z:e#'،I،a$H 3ad2v¬<ȶB&P@ G -,d0$H8&x8@(qQBRl R F%! .X Q %,HH-#AAH2aN@dd'̚ G< ?P6 jld'̢ "x J(tņ~L29" s񈖇#c'Ljx Q$|82>gx1@ # - R7v`366v˜FccU $@a2Jcbb$XHD:q0jK0 s=y=:f9/ö^G1K\-`"dW;\}Y? ?خ[s^;Klʉ,Q]{D[%ayP4J<-(7O^CB xrф@(%) ᤣќxTNPP8͉%}N-yqcwfm`"9ڴG_fi<,S74jaT(R:*TL*x*h||^9s8?]3vnT\}ݶw<9NY=-zc3iW<_vk:K lys~6B'm.̳ݾgDvO4_}voĺ%QG=bߡYweFeΕiԛO.軺؏Fuh~?M57rD V(āe2Q  -ţ@<+&Qr yHR'ClcjݾmQg}έb6GwO/Tմ1l"!)^.D;\Qw}g_Z*%Z6G~"P55KUywgoy~l5g]m']~m3"j25^?r%-ֳF}7[uqݫ->}CS][‹L P@DD14 ,pcd A)c@*[楔2ҨJ&QzY{ZB'TCuqȢ,J5)w$cz*_#W (uѼS  -' 9FMv"^g^HW[Wc!8Vڍ!޳{)1z09 J/*S*ɛ- 7%;{!x.HC i.8C^5 ~]bRQvS!*!Ad<I, -TN&&@/waoV7r- sy?;w2 BJ~L}.L8" 1C\6Ҫ(KymÖ.w yG8^{@m +Yl-4Iɕi6dIxǣ": -aB.wq!\UHy xM=G:jRasNo.~/jod'~aµiW\"YcbP  -]= -;Ff,-\ Mw -1?R 8ř 8xPsa|׆DŽJGWi着adF]gD2^8[{g_!ɇO.M#5͓n+L ‹#]PH{U) T\d)0V꺋 -\]HHy׈1>sY7hT@Ej;颛 ǐ2$;L)m|_ (:?z]7]B%ryk px9uQ])5&L=[|Y@2D{3w({K/y!_$NJRlDm}}IYc=+fسOX.^/F͕u$4Q)CiU7 *f7cÕLR|ޚra_*t?0BBZrpOZs51P|ڱa@:҉˚c|іv;E;U`kCx-e%fE }{23f:ZfWabX ZW镑nhXHN^y$1,ǤK$&J{ |:J)feh5$%܂&#>O?"%OB)L. /V*Q&8F[R{;= -!H?vʅ -Z. ҝt^Zn$cFǝe0}*M<1qD4Q:P$J{C4oGSs5|O(; -"JTihNU^`~+_b@ cRH`y6-cҽr`"h=u<9c:=xے_bZ7=$NqW / UnŶF| ?s9|"k7M Csp3;A|=NˎsJn8¦tB)vE_;YMg wz|FjuǡM?VxnN; FzA$;ޣ+Jq@5㰸"pZo>:G+pA"z\)i︚i7 endstream endobj 25 0 obj [24 0 R] endobj 39 0 obj <> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000053342 00000 n -0000000000 00000 f -0000053393 00000 n -0000000000 00000 f -0000059541 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000059614 00000 n -0000059854 00000 n -0000061027 00000 n -0000126615 00000 n -0000192203 00000 n -0000257791 00000 n -0000323379 00000 n -0000000000 00000 f -0000059241 00000 n -0000336776 00000 n -0000053807 00000 n -0000056200 00000 n -0000059428 00000 n -0000056057 00000 n -0000054846 00000 n -0000055496 00000 n -0000055544 00000 n -0000056235 00000 n -0000056593 00000 n -0000056348 00000 n -0000056473 00000 n -0000059312 00000 n -0000059343 00000 n -0000336801 00000 n -trailer <]>> startxref 337002 %%EOF \ No newline at end of file diff --git a/misc/branding/circle_outline.png b/misc/branding/circle_outline.png deleted file mode 100644 index 8b52bd35..00000000 Binary files a/misc/branding/circle_outline.png and /dev/null differ diff --git a/misc/branding/conreq_square.ai b/misc/branding/conreq_square.ai deleted file mode 100644 index 50b62845..00000000 --- a/misc/branding/conreq_square.ai +++ /dev/null @@ -1,1798 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_square - - - 2021-03-19T18:12:14-07:00 - 2021-03-19T18:12:14-07:00 - 2021-03-19T18:12:13-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A8y4tDsVdirsVdirsVdir sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdiqaaT5X8xauR+jdOuLpTt6iRt6Y+bmij6ThaMupx4/qkAy3T/yO 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 - - - - uuid:a186b772-fa4d-6f44-a6c3-821cd14b9728 - xmp.did:92a05db4-1ea6-407a-afb7-538f80719779 - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:92a05db4-1ea6-407a-afb7-538f80719779 - 2021-03-18T19:52:57-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HUAn1 @h%7)(6'@jv(^V۞vL_vLez(%T8xR{z 62-ckwneI%'L?E=ulDbq-^6H\ ]Ny&k0GcDE) , -!)>#H1@c1 { h5ӾHA"Ff /ntcnzk߿(%,cbͽyJH4 endstream endobj 30 0 obj <>stream -8;YQTbmhQ5%#'+E(LW.RJ575@S?aj7e:/$>,,N>3X@SF8IsEsErl]Ne^f,?"5L0g( -N"-qYpEBBrSIQj'7WCRH*AhAl\7Lil/U/C.?lGFD3ltj09rdHAjd9dR[/4t83"bOA -[7`md$s9 --hWTN9qO2':!OQCguHmQ<,j[5 endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_square.ai) %%CreationDate: 3/19/21 6:12 PM %%Canvassize: 16383 %%BoundingBox: 9 -291 291 -10 %%HiResBoundingBox: 9.57416267942608 -290.856252464226 290.119410358977 -10.3110047846894 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -110 10 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/Xu -m* mm[QΜ&" -NRj0A   %1Kݗ6KE)V^Xq>*V -qnE^&QC -%$Ͳ &Q zQ| JbA&FbĘXY[Gbbxk~H&2)>55 o+Ò(>cLiGD(щE[6E+n!Yc[+kɶƼjxVeD~!si\,O-Ytκ$ִZD<<:݅YlqQ(0,j3 %A1!bI92|% *&2I$ q "'$)aED.2- Nl=1:F e=<2IR^ EjX÷xr*80 -raa$uy6c ުjrͤ+cc1(Ic1vt'ҡrWc޹=TdvQ^*.Z=:_^l  "DD`Ѡ2ZZ0oukifN:-=dYidG][-L4o)Tw{[?)Iq.wW.o絲D-2[2{4H_b2{ɈȋB5D+dڛ]ѡR -BvjUVWGNm Ӳ/!V@ I(q.$}R$Fr$H"Q&4/q DI`bIH,ːiʄUSiiOS,YGĮ PP@$L4$#A$%0L`"x0r #a$đ@H+iI$F̼t&A \TD<4,4&.9+nOGbT>4I ((lT= ("@ūBAaHX!;<_q\r#4"&*. 4@L 3Ssɓ8Cʕ&HIK % $A@ "$!qlRRIL4dhр1^zPB^oJ~2d C TE (WxC臥fUCuJE릤.X:Z񪸹dko2$C!cԺ=^UXcA\`,("IcS&_hu Z"ڇLnF{!cUeTI[1BnxWO )MwRe)aaHR(=)x;vӄQfIJbVr,IbFIbE4DDȀ|$>M{JOMyU{,Z#^nţRRm[BQ&m,cE93}& 1Me-]ۦ(ƁQ<`A --@Dɢ[^HHCCKJbFee+ђ(4,(JRd\3Hv+꿩V__ҭ~je?%5X (Fk$%r 8CCHhI)lN -Y[4Mbl9T3:E]J̧}w)mZ=n"b+wn9.)6ʰ+u_`-e#Ia(bE%xHA*QRe+HQBTq U虍RQjRF(^VU^*qly@OO"~Hzx_kWzUH-]L݄ec&-l:xKUv;R\ZH`9+J9(УxI)3 -w5)nR*:j c\0VqW%-ǑGV9*Cjomj|kj&LsilcCGoBLKW^J:hC&KkDIg*KK˦KB3cfҸ$I]aẒGp]^>o vXQIV%Kb>hD0(t$@ 8 -U,fبDAFR$XC"q#K"$zIM:-meM-YM 0lnR {S\+=Vof otLm|䳤V}be-<ڒ߮Vdc՝5nQfFTMz~xnwWݭ;[IL>Uӗh+NEs&.kJEx4m5+E"Իl),n>LUwۘ *Ot~5]*ost.:*/|"u- GuՆǵ)$,kEC|ïک)lQ>$oE;+wlObe,M<HmNg;oUc醧yCh"ʣ7ϖw^V2kNzo3e=pW}ncy޺igiq?OOz0mdzDXMg%c\"z,J·vZs9Ow ]]Mz*mu[OM">d{6oތ>YNVQ]L?vl+jәߪj>l]mi)I͜ksG'K˚iS"+~<[NO.;hi5]wzZc{}t5Q'Vrwj{ʘ.]gE$*u=>zs$R5=-*"]^ĽKL?xth)(fnhm>)VZKhc%˧hi=m>.D^Iyhuae[F?jM}|%] -kS$j"(!^y Ȍ֕r>L.lIdxQǃG\ZS[K[=^)/Ӹh룻/Ż$ܬ#Z"ib)*Te,ҡ3g2]3cEֵ;kx>k&>ƇN1QԥA)4\ųy --xte94z۽hsMiI?ƬmX٪=9S~Hvo+ՌB[*d4[m:U5EVdsHudS7Ejnh\XuXwn$*m,5}xvToT[RsJO6>Ti4J7*ӓ۳iVK<=L4ěc|ge۵q^yOOj]Vkd5s[jZvn4zgʸXkM;4҃gf&=i蔚v]?iNkb"ӛכdiLNѼm]Xkpu=Nl˫Ǚ<׬c7.4wZnoL&;iY4ء=k4VV[zQ=L;y_Q&'ҍ+ -8 -eH`FL0^hWP,@ 0 -#P>"a0 0xx 001_L1Du`W鬯ȵKkLJ`ML]s`,(]22Ҫsg!cف)_5S)DwοvnK_ަ婚׳n?yukDC|w]U!ݝ~xZP(c^/L;Ϣ+=*חYWguk7VtEuSB -<[P(ϡOvJΎjձ}ţunɨl޹L\Bͧtw~&^ZSZO3LB*3JE_7s^Lc.Kߪ^=rtBIk}V**V鐜wNe32z?U~XUΥ滕M*;JZL[f~7^Ϳ%SY/TuީtjZSMvw.(쐌񝅪VM!unYN7tO<𵮽ïψWuUyаtө+v^CUT5NµOCDǨ*]wh^EwʘYwYmU_QvR[[םuuJmtR}T{*CZxдVեUX!A,LtL/YQޛS=SLHJzIi. -oVm\;|1չg5.ť]%;"NHuv2gA",呞_=_wBu3M-1fkO/a.zlheiAriYԲB95OEuڼ${IQOej]Jszө').;Mɺy+LTՓR1e?؃t?iy0lQ֖Notmo06>יvиڹu̺;et^n~gkMuMTw{OeJ'\|R2+ܞ4WGJ+tѬiF2QI#0 E}n@nH4CtC2 -Wa*DbX cB[3>eh)ԾN!|^S)c3ThQT 8ਈ]oijZ -ruSK!e9P1epL2!8ĩnI_hw~ˤIs7"p`aWWsE%N@pF< -pҩ:#&NΓGT{k6ƾzPV+>s_4DIH$?gFkC=ȭȢs ޱLSa;*Pv_B!A91 QmRfAE8+AJ`'UDElQ5Q90(P? ȲHI"2y{5!ŗ3SDvSaGf51#v0E#,Upxk#_辱)*)d>n&#zS%,OQ{$gz#|TjpE 1[6 - M* -bx1,oRPiSh9 趴(:=-ffnpf$Zb:$D?d`\p҉1CSBlnX&U$]Yïh'E~8ȶ-VaoƼL5ENZIjS42rv=ιM\Qn4Cr^, -Dt'xИx,+xc{Zt`ZyC Ѱ:袂FoިU)P]p|#7OH; [ yƤwKAD[UtbzɜQ -YhR˜t{݂czNgeoS+%. JcIHRX3 ud(4I=bs - D=qt}qF%]D`7 .=Qꩤ$}ݕ4+ug5M><=|ѿel*}Z뤩‚kl}F4Lm2{in5=OL5 n!y#+~]L,'u,MߟزQ,ݒg*yE*1b61$@~j#R1Z',.;ʈD, ۖ} `׫T&)l[X*ۮhEbӊApj$T|X?enR߄)]D?0}}P0"wҧQup;o'C,[4,׼OҤ<Q !ݜI;ҘmΚ|fj$Lk!!8  @K-ZQ"TB H5b\ qUE_Z*jt_LpJs(2 JĎ}\?30yaeْۓK:K3>flmǨ/F_gol(r߯~?5$}~ R'_" \=/uѪ4[!oAOnnuKPyٺoLn3)&)jt( -Tƞ=EŖ*yq232b島gf⴨eJNPg8ebR:F;hd -)sVr3*|[=-ĠnwvM/'TIv1:VQPS5qYK.t=!gGW˜UJ/>YnyC*l'؀ml45kܲ`O@e_GźYٵ {q6;Qtj5ֻe3{V;*@)V PkSqJ  5twj3xN@m=7~9i Rţ+"'ܿFui>'bձX+{ki7V|Kk=<|5W[˜q2bПIQlNl!jU,DdmUIv𭖏I]Vgվ?$Ka9s5U{֊ڟظwR -j PQoҸTs8LS5h֖eFJ-JhyA k` -V !7E_AaZ[v9WNoԹ4ǥj hmVʩZFrf5UlTItZzUw3X8yW;c-Os8i"6}՞Z$S}|95Ւ(D|"!5o͒ N5pw0B~r7?j>ڏڌ-wlU?{=ZfUSYDžvJ"4_-@nՂEL.va٫#;[}u Ѥ?&w^fi$1ĢkDJKCVs5Ai k@{]=~[sέzM5q5X܆J5ڴqz,_2|M=_]k{bёkkz 75۱r ldܽf][`lj1Ϥh1@ eę@@,$:}λ;a+P-g5ehW\،[Plgbm׫AI$6pצ_өnHKkay2pJ \,8]WT"9s7p= _! \a TAF)xzV+1>w|C{bwq>\K:HNYXA#p 8v[eLlB;oa|qJ"8'76$a"ЛF+%#Yގ]6zC8$9ڦRp%`=>fgtCC3ߺ!}P:EM6*ށ5*n)3{ Ȇ,-JRJ!:vɻ \Άy}xiND7a0 i3sx ʆ8ؕ9lHPx`֠!1XZ=O#s 9&W!GEv :ܝ1NԐx++jQ3X3J2{(+5?j]cDڨx,I[cA, 6O8A/f״vTҙ-9ū*)2@ Md d0c:'wľkd&? -28J~&u tb++oVTVr :L.SfRA&Eԗ%?'T(٘ -quekm9 #R^ ->WC,SIrc3 -O ȭh!V0kt(gKlgz -,gLo/tjAP{]+mo"R.0ى<1@:qQ$nǰT d-_YSr<1SAܝT}[V݀FOrњ"5zR2KOJ3 iw ˯[=vM~?ZZAFt \=+)צ&Wlzma[**0""bFڙ%J)ce.z͕ʖE~R+Wz!5~ ,a^tK` IlD{uJ+ܚQ}˖?H(_@:T,:ba hJD2:04`G[O̱R7Z)>;8ĴX{6 -yhk OjL҅X߾&k4;blpCXV2g'D'U'&Cx@ -jp$8{P(}6a]izbС(`DfHtG|OOX8{dˌCTQ$}Og>Fd @@֮ ?4hT }q]FϿ>RY|TP cZ%}/h(׾h3X TeXkbD5 }<1麙AG5!N*z+p4k$W:S'զNk܀dz"#)sȊ9MItwAB/ (g$J\s9\Hqw0~ŵe?%&T̈́V*().h{!؎įay<;5,H!Dfa}b`qNIU_*S6,nrnDOra%Tyy9+)Dxz>7 57,Q|0o)iT, iN2窾Ch ܡ[]Jf[pAR* -}~k4enNm㣲n ̐4tW/qZYJ epHwdA*Ӧ%ٱ&e -^$"? BB`āfܺM#M]O>:F׸jHJZjm -LbUW@[B VWk%;M86_os)?6;cm4< _6e7\`gld)2#pd8/YՔ`+ e8ф3*i4D$;TTQ`+ Ze 6F;uMz1[d;ąvm݁b (*z1 &Irpa㾓ޗ};h|^  q$$n#B:> -%ݢ1ԏ5go);BAWTVQNhG4 Ͳ'`֑FUrZxHˌW -b̚ zF -_]/a'4w'_$)=loeoX'Oܬȫ ;NWiQ5Z8uiS4qYdkM$D~yƔ3]TnR9nɺ|fVaLGeVVN9dGCAmO*k>f9\;l1[| -F|t#X 蓟eս,aub;yH3osR( -\MA~XQ.&,Ef[*h &5NzyaL-_4уO.m P4BͿzA-!E5+Ⱥ\DR;L:oƓ^3Clxsz4 ,E2+z;v/NOtF9v#&7?b>tatn>vSfB}Q:HYL_WTLY oJJQQ.\'G~XnFbb@p(9fЕ(QL#v[ࣸI3z?z=U)VR NA|4k'':gg]ɩ-9q9$Kָ=-`P%߹{Nq PB`U3gb07)zPYMW`^Gы*7IJz Y8UFȁI$47a s> +2 kDGʶϤ{*6bd,.Al{NzM#x}* &^ܬht6~my&(J.Kл,q՟ROAr2/qkgwG>| ?V L+4Ե#]ls&J=BE+}dƮ/\sL5t<7lu]l(%_pnf]ܦyڭ{yզG -AShlrIm A I1y_/ScbDVCf~Ytw=#ېL=ƹ#ߔc2+@$8!,}K0s[)D,/q=-d[ 2K(fq ͭ;Уҍͪ\ A머bۖjeRP|J-^;G:"%v眯S@N!7Vv{ MFUzz<2{٥ h.Vy~Gh< r+1K˗U[ah7[s;Uld|i]V"4XqWI:+܈+5R?iqphZRjd3`Xߴ$;`agW_Bg_JX`?v \Pb5L}U嫘$-9XJV*1Ԃ&eӽ䫜H~M U Q ] 5҉;#!Qa^Ctt9W1zrٲXP? k#fqf`N"ײ%nd7(T2 ֪b,)$C&WwLCndːR`iZ00(x/sczl)^!;NHagF'$q>$ 鞘 -Ŕ169oz'E@w8*tbzv3Pw ʮg)^E! -E"[ Jgn#XWG;m!G@,h`7)T}(ΪA誽u} 3! Q}_gV - d(ja`(׼GG9Wlj5W %31R]r!tZ8&HV` RZ遞Ǐ C{怒=72sdE+L!=.v,((jY| l8R%9w\%MŘwļئdO%vb wV lnA+ ?"Uh8*b}1m$.}B]=8~PК}:Yf[5)v>"O:RH)hcV*L -\'ܗLg ʴ7i!TdẌ.ϗ7{g.;QĵLGm`sh!rhRnK+x*AݑJ(!2Xƀӵ2 J>zbg# {Se ?ܘчHa?em;SU?Chaܞ&}3V K(xDY˺Z:j5x j;keT Ȯ裡LbE[1W*)hd^?6TvӾ$ZʥuF~,6SzkNoA{w@CG}_| Ěhs;FWofϿ_1xjrzuLY/O$SRP]p1b)MJ=|6xZ8-~,܇c\vkݽXY86BXBbC =>%'ʕ. mT--Z-' QnVymgh3&0-;:R+19`Gh ]WQȵ}.AO {2LS Ǯ".@I:#= Ī4;?6OP8=NbPpƋ;N_w7+o$'9[%$>fJMuo0l0 kK"唧Xzq7#ϵPwZr^`+j J%ѯN6ߐ㯑 Ō%PaZ>>\;je4>@ʫoЪ2#k] ViEVhDt| 玊Cla-suQ)vf]#[a~=MZvx\j8Qai;c-歸؞穹N{0k<1sɦ5.AfZ>WJuIҞ%77FQddoN e߽u~4rԘ&&u%=uSqu ɤoul,uX՗LhUG|i{%M"B=0m0Nwtpwk\ -)qeglYح<2kT<Ӂ]Q$oabB?xV47!9oG:ۓͦyܚb\smj_^Y|=tzyKD܌d$g̭Ѹm$^jטݚ&AiQm~3)c!7~EL0 +qHK#^l`E,Qy1?KTo`p#\w i -6* #pA -JIaBmdsXifXB@(/xNJ&E3yki؜q+oQp}hAB`0{u螲=mHQYQe [ǠgfG /}-ѥ*lU 4h0y*bD ͗-!XrFB;R!DZ.Q%rR/Y;$j&Tv昍htQؓsy5z- QsM)5#0 f{ZFnwʔPPu w`Brʀr,c4i)j&N?ՋBb/[r͘YTpI`QZ&׾Igiv{2_N uA}f`(޺ Ö2l UP0rҵw_q,~$~)Iajq6ZBջ{ 0*ڣ5 -Zu|z!X{l M<#Ƚ9 wXpQ<~Wi}m7w #2k>pɣ)Tr9@>Kۂ_j=\L;5 ?3m5Z-~eu$U&TQO6o3SDAС/[t!]$ )8R3n7[FvQ{AFsN4k Gy֟:)De vκ(ǴS/w;X'G-B.3lRߕs- HNr K{)cVڿ$_Æ$¢na](PS"] Da -@yժ$sxF^ c-kY)م;% Iie->Z-^򼽐7Rq:D~7DA.Љ$1xHuBx$SMdHuS*gZ a78%GQ~r`3Oi:@ \ܪuV -iUO@Tʙ+x*_g$vf";o+;.;S{X Cn%&?1XMxI>Mˆ8, : 1L*v+y=,&J6V!ObX݄tbxqTlSڶ%aMmDߔ 1?"/$t1 ,\^4V*'諕 ڱ YRE>ߞ y4.)&u(!*{ >o =4&;T@sfP|'wtL8dKIWlrZRs"dN"E]ZGSΡs~)l>X&ip,8G2.yOG{:7X.d2QW+ 3w.UiKPt+8 -v~ adE#RFeNJ^mQ1YJPzC|:E -[M(R_PjGBU?8Ҥ4jYnաAا}l5;Hpr©,}9F2%#45xQGgbS\C-lԂŒA5 BTL_}zGB\ Xjqb`3o-yH>vBQӞD>Ko|!hno`p5:L]:%!3&֖Rџt8,$`^UE'Ι[TD=HSY(#[:6HU{,\OVs ۜ(7:/tYG -ypu̳#3߲e"2`AܹBxTa1Cx.xtjM}Ӵ> :9ѧҟ*3d|}ذ3- ˸PIH֞,ɉ$lx1Xյ4#)Q~b=x2'>QC|~01g8{ = CU/${pfW?wa#:2I\:7Đ8ܽ7hz2{YI*trSVĞOCTpZ6!V`xuIuZDY AD9풀[B.l3Ǎn-E\o7hL?j0ń LRvidqXmXNE - ؏rPk=Kat p7!&kx $ 9t/-D}RLD-:d]&KEZ}>l%?<.?re!9Csm\}_mG˂+llCΪ&/"qvm$dd$F3بٹGKZry>r>lN5Ft -K-ap03&6[E7vF7fN$3b܌Ѓһ\ C]Y -4GH~s%g59Z,e휇au^늸/a!,L *QTrU qj MjPҰxM# T$)g>>f:q}j„:7:'9^ -ɴB%85}{"ټٚ!fU -_zFM$4sV Vycb]i` -O -q!)IC~;ʉF|0F0jӏH-u?7CZuOLkGc>}4 75*"&; #=3\j Q GP6Dj~zt`9 OsQjFfԋHM{b8Lp&`lE-x#5#f2[3C|ͪQM^>Z}9X;S >V=j>-pc sOqmVґe̳Np VZ']9%gUR׸Q[HP+02ne*S|n!\Lc?4 ǕuRn~HRs%<-2r&21b~YGQ3Q H_?͆G)T9 -MԅmM ;>WF=b "Ƥ[qGvגTU459}5`JR9 [v138c^Lbt.j=W%fD:aKGڜ:EI;tu~6=ńk(ԽQѓum BfwIS\{2'ۨq2 -rdHu HrRFdqA ‘%sj knŅ|| <1C\j y1q6 -|^qi&IE+_JrV\Kv]T.RhYr2.Džqk,gz'eBri@ --ؐ32!^'>)`|,UpXdN=+<$_W xThހx(VnHؾّ茌j=)"F3N&*_"8<Fl'< -MuX. }<0gD*[}C5MQo3Z_ryqV!^u\2ND\μ30IQ\j41`JU0n}< ͝?qx.s)wCvx)A][i-,iIɬ%ScnW}RSanevJM k)x]U| {"*X{ -RaQKDSpI'<!4!d4]aܭh.+u*SdmĂ5DϚ:fkwlfRkF=*ӿduXX[EKqJ+UV^Sh*vU۞ //n>|v[[@:dч@?Jb_@Ѥa$O]nGV '#A`i}~Ic!Q=iרo z~@:QQkHdKL<]'(.Hڳ̤]tƅɿ a>8RM öQ4qz+AvU 6> -[_S ^Oࣤ gJA~yu m{ *ZdĦT5֞*%>~^PēO\4t!t@M!wjր/ҫK)nW&_}hQFԌ@A&0=Aw(N=`)h~l@iGqd7610MRDŰ%3>5@Aɣ'dhXa: W`#2eE!xGܸ#>R64u>cA[HYb˰A%L*$filp`H*Ex WC\Ϥ z-qTF֯8[ʆŨ3_ -c0X$D\|Ul lB5|`F|KpB-S8XfK -:8 -"S -+Ě,$̱j65n4x4$[*+짺gVʌVG #:LC C pC %Z -h~,K@s#t#\ߍ1je>82*KO)Llj ~1 96Hfȩ Oڬ@_Y)Kj*uKPf*y esU=XFi_rڭmTnr!I#qHں*[fY+;N5n9 -g1WXE# 0]PÖ;"cW^ Y$t'WLfzjP1a>R5gY0iDcROYdC:"?}DQida)2N<PR,02_UG Q= ӿ|}t'd)$+I/Fԡ6䢩NjiQ/YGdRģd+*PD<1C 9Poqp`0Y48uūb9H1pAJ2סvT(Aki+asYcdw2tt]i՗@9igjè@}zy@v$ش'pA@0s%_Ģ .@gl4Ϣ+941M/6liUW -68(6| \ ~xPøM?>0,M[O09 ZhR208zw=)tȎlɛ4+}qGZk&ma)m[ ˲'-9v5iS-C~pBQOV7{gdj_eNYRH3V*(lZ݉q#qVz`ߗ+bl@?C©;i - A.%=勘SBZ|2Rsg9: Ϡ`F6VZAfd<3Qo2;J;-{v(*ps_{kXz O?މ -^Rl!wAFkmT ԥ)IRJ$"*O+^xUmFTUA:4Y'Rppn&.8*g[W\F0:Ckj! Ό1Lň"$4UEW=ª93RY QIT.ca -*L0-ajU)13% /#j.p)<lhS٢A^[_1 -jC{DoHt 3SE߫.{Ɇ>FW'N78UX* 7=j|T+$; |ozighA}hWŸŦWH('0θu &WHh{'"II9<2d^! )k:M)⽩:Ӈ4%(ziBzeLpi+X L)t /,Bj_Iȅ! HtkI6}dʲU\h7>4΢1yѼU$(RK6掠 ˲_ S"RUx9; .U՝MWv(RT߈Bd[$-"٧StB␅ѤBLLB`ɟ -Ok30!1h&ID#m~t"f/Wd8P*Xᛐ^, 2!k cvi#)-$3Jb2<"d$M,D}#pE74ǧVnE&MmWW#F)JVWV!Ei%mh#(qB?O|G01y75ȅ&N# $^d£GY|&^F_﹘bw,a9}|3˭pxN^a^NEbԂKv!ކxExP it8r 4I9!%D -%^JY ^*֪2D:L)o#MCZlam4,HycƁҮف46Sĝ%6LD81CbK!rC%m,,q0˃ -OIpr!r0y0SYѲv9Eδ -fqHXUbmA_rrOpA -o.$oj&7 -C*a|{B)rpʧb\y.iDB0' Ai^:=İFVV)]'1H]% 8eR v5bvǰMRcFBkP2{@ޭRv!Gp4qj'Uє";#T-}D|W7PO"m/^KgPmt -ZC;Cw5/ZU|2b?$hv4!6]Er|CO[ -|0b=9񮱷ϫ1Syg"HV$3N)fvVT4.Bz5g>.lNP̋\S}jk5c>|3?B}"7gHq;Pl324/%B}M=?NYe -}Wab4|%21&©, BB!4ýBPP(- %1aZk,;mxĽc -Dd^񺄒QLFd!3Žh|$ˬwz@ .(  l `@3j:X*=S"E@d^ a)b=ƻ.˭vJqUc;EnuC[S5c$!h7mDŒoGU\3o{LTM|,;j}4 aC6ʾ!} -Rsr idtw$8CwY#x)^iOHd5߳ҔQ%Ҧ!<.ԵĠ(: -ִ̟hQDY؎SbsF0.׻aUQiJ} SEyeR.i3.Q%<G>6yFJ_EJG2blFMYixP M4 -$vCYY˥[97*ZL7wd2n̊Dʆ(xF߶f2tvpl;e Ќ*s2,XU -CHc(Sl;FB5gw33lɽN::bH4Wv# 陗)ƦHaih+;Ba,P^ۥJ73Zk.K@ Zϔ'/NpiU><5Ѓ= -4j<>ΧOy~![G^[)4=RbvY)ʻU_rZt*^^ -I9#ŋR"?G#29dژ߰p2L.MϥV᠖>nS9EI]"䠦fT/$27(է/svno(((݈tF;,q{=$Ei\*+Ae4JDv!9ToYW%GI3#e ʇ^D=,Dj}+՞2jhQsrCW?"Y_TE{ē)$D)?Cv෻ѻchJoblQZjGL6\9R _~(1Och+KMI1jpq/z"R^jq19Ru3E% Qbt<(qWyy8~,vYP -=PP昏Tq_Q/yCc榡ʑDa+Q&bQH,㼄%Fyd$t1lIC~=-5$+ќu>$>Lq?vN#E;gZr^ukxCf/G#DԄpž9_%LiOx,-\ӪJk CDsTkIkr2;<6+۬jUgWWe.4KqInH5"PX#m&6\$܊qHIϰ!+uKN(ܡ9 WP̷$+!d2&ʈ1UĜy 14(cQGW';x[%3r01@WIJ*Ո{F(D!?M%9UrrFB&UKT+"!7kfCR%-cDzy#;OT SV׈TA![-d[IJP7ŵ Y&=Yޮޅ2.ULl뷰[$ƍRjPG"jÔt},jTQi.4&FS2oQ>f+ˬ'*[ƋBf;.&tAZEV 4(5ɎTsJt>=U!Ūhwm7Sg kB2D10^8r w3>$|`ILGS:dx7; -Yҵ䤦Ny`TS0>\2 "QT3f3HTPb\)T(JnQ>D\2U>YEM~ɢ*!'LPc%Ȣ13D!bXk*J\ c>H Ӣ\@[X>U5y9(S$w\4A߃o:Sl rE@6̐UƼG~9Xi"'2m:cs@W[;AF>wX~݁xg45N+mU?*ihhBH5= "!iV}gC$q4kAFJ5}|BɄɣM|ieI$ rk2Q2(XJ.C(!E+Gx5:!%F#(C~rFjCu&~T9 U2DX=*V#6~( -))cx@ӐGW  GCA6 p6 EC;J(1l)rE\Bf[BڈnhZܐ;6Q[ED)=I]ԃנ=y8J3͌FA7%L{h!0NH1wM{F覰n"M3e\sKX&t<ʃ)m -s@C!, A¢F^rOJSO`k"D!r9 o􀫡 ¾od"vКq ;/$jnJTaS${S(qԷ {ER9Z= Uԃa9 ̓L勳JKh4 ~z9~i\:_+ϩ+X'C,S|rJC!ㄞ:,-FReRUɩ+T*AΊF4U)*:P-Y6+2v!etI -VQ-^uWȺZчfX+:Kf.'W\TgEw3+ФNj!JG 0\|: ÉHh3啊N&XF"Uŵob&nZU苉GPBʂ^҆5CzGj 9k1F(1SD^JS)8!j<#U_ǿ]HPE &ᢦHArDYfԘ{1h6!^q9D5b'gBJL%9ۿ4%w)lH?@E^w߭!R1'qpAwJi^`" @>4 @@ 6` B` D 6 A(`A"$(,"\,8A4 < l @"| DC:2DB}: 0Xx  H@T` `A,@ -,@"H 63G8sQ1~/2!X.JuT,j+: -*`QA]C -NyLFLHV _F6 '}y_+piP#4NGE"1bU_DىCF{Pu1ZBztlU}dugnj]4E$micE^3 b1C2FED7 -* ŶLCblT&KW.RpЎl.5E`Q -đHѫP,+y$B(8xHQ':A$HK㸩eAGay)?D E1ml j)~[O?j0؋5}"'Ȑj7Z83DV1PcaS(Z4ǘ>~qruPCj9[ M|C%Rer`)_T } VLHpd&>LmOB`r{Ft:pg%u2cI]VJ5.v y/xothUbMHXWI(ad[VM%"XPp= -BAtHk0RPʈ~Oo A5b+HMҬ:E$C)#ϴ6Ce\N(̦z9:AGh*& X$ sXw_ ] -L) -!:a̻^BlU)^g<0Q lZY~2C,r/fA1R#Y꠺45DqFEi\+%Z!uCAڐu%kȴEZ"Vjʐg?Uz\XLAoe1jHdV#zKH[uXB5~66J?ff|WS!(ifՋ - !!JR19d%U%.RW>{#9eNq^=:f(KbR샢 Z;>}PXXGG$bjcűMċtX$x6'dѢmj),.0oTLLR!=L/OW*JED]CG|jq<5!BWcTxDF,BED5rKRTe*WLj]rXN!+%фs&a*"egؕT\$fUevEYY!Ո]Uc5у4IFaFIO,DJE"xttO5q?PzPZ'T1ry#+97:O -eGȍKl6Wc]iLSM2Q2KT(9)EmE*慧2ĦHEDE4 #,M#l(R?X9/)"R G`HÆ8Rt"f*xd\SŏA$D;ݶOךR;ăAGy|zcj Cy@PTe)NBpT:9+l0SLXW]/A N=8遐xPtXh5T&{B32r@tPOHV}6#aޔ ZOyB e]fNTǬzzP5U}tF|/ G6h2UxwZctp8p~f, vF5An#դx <`&$ݸ!x㤽X==7}lJHjd;Y$}DFbV1FoH7}F "ݦ cbRDk2if #+Vbv`QKy&jS0ȱ8vi։Taɢ^5(vꨟRu+椅RWTd I%Z )}U*wfLSBwI45-Ө哃TD0@prZ z%;(ha]@[ ^M}WZ}]@'Q[Wn -W8B|R_;j ġ+> - -p6MSe%QQ.^ʳ_-r+l=t"N"f5AXZ1E$y. ͑ 6G qdͬCC4 TVisv`"NO),tjt1T9wTҺ5Q_/=E._'kiq "²3S}a&;|XPX 5 JA7̫ :OD;"t5r9g(l ˕fg"涠,H*h<_(s#aD'}yP/Nб,W'q-tfCWܧ۔Nl2pWazdٶ|TɜS%YXUhvׁv]/>'mYخaoOP"HA5_QP@ -l욙I]H,% 8(t4N1y|k! F.q^FCBޕOA(7"Sx]kwڙ\"z#|DԼҟ<lsXo|ʡKH|76[0 S^Oa@0_^腎ÒGi4,3֋Z( K1 ±#{<]nl)4smYś"`+F1X-.ZhIUוE:*56HF,X?"bɫъgh3r4 -Ya(gL6)$ᮀ a{"4@6`=PEB8BH;Oً"#YW46 4iP:6OE,!8DŽ#)b /WҊ/ZN8xGrJ|VUT-#| ?HF1:Є3(]&sw1 . E-W#` wFa* -(lK Ql}yzkT"&@ƢaKE:` -8謫]S3R^;uJ$jĔ;x^ZY L̪ -R㤸G^wI[+ZҤ)bm"e<\yLW/scVyNbc:Dr#((ًR{|z%yb\e`ջ5ı9uQ.4E9 -EHHqFxHll/kFP$ݓhp'O Y+k$ Dz-k2;=!!Ykg5I !d}VФ 'odY%npiT2kJi۩9BIjcX}aI"`0ca43N4A -6UtT1H# !/I^9Qe@"m ۨ%s zX̬P2=d-cH%-GKJ1乙t |1lqћ)Ͱ/ixC$yL>Z>D {77fs3r -(x|`40L:HnETJaB5 ~P_M҄ LaEPS ֥;^a^ZhM**>$n&4~z~qz*et+t˗4M-Z\kԇ6,Wj1^#ي:J%{+^T9݋~=6>E태aɞ.Td(x%spRCSrZRד)@u@ϯhKlE$'-#Yp+Nޱ&iyKf#'$kgv`RL;hR -_kP'і?(e gN޾%)՛l(T!Zznm5ˆ0G*DbֹÅm 'Nd/f5S)T'`ϚH6G=bS&凃\"x;A-;̔8e>$BU!d銄N;(9?i8ɠ6Y0 [Tr}O>6fQ0kيEaE"̱OUW qjR##ԷXKi,6~~j?nP`9ok -SGBA!1c&$]F>mTz5I螹˼`鳂{gV]Ag*MPyvpSfQFWr+ 0yV=I}\ @)|_FS>)7Cq_b5c/}^J:hYJNRXzi2!}V\bSTVYbW~f62BN`HtVB%gv)`YiٕFNQd,γ*jGq|%At؂E{v@p1#0BxM]Y7ʢ`Ά~@̬k4dPsDi+JrրYa!0pc5zu 1ryo& 5`{ _R"U -e1Vȹ0b% zڠXe¡NdiwlDP|RBr̂rfsv'줫L&T &FqAG m2sc@G k:l@B<\ - -CJ7FLE>Me-CM&FP+R -y_ hr!Ϋ[."G̋X!l4GGUtvF>ոSG,RL%^ZFEiK1/> -7bH6mwS&(5AG_bQ }kr`*hJ)8tX$_@2+~v҅i}3ekJ+86ʷaEbOs |Vd?zwv(1 ZeVI1ltp(h"әx Dfuzʱ ƈ"Sg!/#5[U^tP+k~L Ua{e8eKO@[EP&C=Yp^K:xZߦȏ*nj8p'[ap.eLβ*`YHA$"3v Zf\h%j >V &<]h*KY|YZ38Ym@z[$gAHk ?Gz71%>d/7vu.Gd&E7%\na䥗 (!̷sE@bpZghКYv+DTSF` gy,^6FW?6{>^UBmp%iǙ QG/y|tĚc7뢵dj(;]֞B*%bw GFTNxv/R`IV a 6*V$htA<<*np$*V߹pDvCjdv'ăOŬ"BA,/rN-OBBKk/zvN\m_I 6䋞xnD@(0 #̃-#~Ys@ӦQ![M0u +^\L#T F#4'7R -"#]v8ZGk/da8;Հ|TPb{;,V:CS*6*!X30>')ZKhmi Eஎ'=) UUw,.*Wd^!wAаfqBks[R yၺ-%Ą-"^BM6$l^ *T=ueԲT/j"%)DE7'm 7Nyʆҟs"]`X@b&*uutPC#jD/CW Uk&:5W`z _[*&&_i]kRcr,i} ~ݯ<@<"c#-#ac B8r<>렀boWӄ>"sA+WxvX1%\VPσ)St̐5ā%EȌN\™LqbNvį).Pi%HeodmWCg(C,avfzmƒ5ʋ,'?+g +,%"$,z,aB%77}"N6Lq k8}0%BE(- 5R9M2d_s҂ܑRՈMQ>A@49MQݗ.1 xfnm#p88n -(ŋ.)7ǽ Ő6]xl^a5bSH1"]sBiڤ3Βp=wA Tpa䕊MBիT"_=l9"7z5+p&KB!=uNV SA5 P {ϾE/t㻟%%3yE9.G*aO4N>.$$[|xIJ=7%V8*`dmn3R&i)d,W8 ҔO-Ү~D_W'Plzˊӂ)7]>ؿ#V64ͿT!iXgnL&vbWӊJ0'ō)V.\2<6҇o^Z.d#P'p3:8B%&@G0k:\Egi#u\dٜ~pOGl=cWUJєQA0ζT0){3JC;{QgNer{죺P,o4,{@$@G]^QYmyz 2ޞ>t!ߢKm%,!ݤpv8ꗦͰF rZ)mA&?hmA,qxmi+z0X&C6sKF 4Aap ^|TBKӟ8QJ`JHË]M#V/zu7:@ S}D\}Yng?I:H8!b;]TNڲFeChp*k+}tnc9=L <aɵ!wS)Moh2j=@&bZh p nj -e PEtt" 8?b?xWH,%V;DR #L .65WkU&ǫ 1$lR8dy {MO-?\IN(w r0\3iJj2~hSCTҕ^_}PSb -ykt˄jdp๜#\> -hc_LQͳ$ ׍6·OFuWFYsNk,ѝ ՏU-Y5`>$n<EDN-{MYH.TupYn:ۋ7U5E╣$0(~vrdšU2З F:0hͲ* ShX&A_ |SyPQH> a mBxLI?`ʗ$8:k^ptxaA͋ーB+8a -|b^g/RL>Z=8PYIU6푤F Rh3@EBf6 -K2@ -Hu8sH=$qDxN 1>ؔV2Zif/b\ogq &DjY0=}A%P*0IAFl"3N P.Lkƛjʂu˷\_DFDYJEzmka᪚1&7WX@?]%݀bs$8;#nT6'$â{z1KtLjf -{3a zt04RS!/qd?!em\Fe`H8խ<xP@\c x "(h~Qrt/dpL|h%ۉ.szLHzqW=+鼐 -!Kk˭U8`L#ӎMт'ԋJ_.^Z R3LCyɉA1GQ8#tF/jaGE_;v fmN`} Z"w,]x!Z¡{-{HEq@h)KΔqZni]cs3\l݋8sܡD6>NC BXKO֥l`kOÌ9usu+x.upR\6m Xxj'In"eBfckN.XByC[~B/pB - 5"5@ΜgR&FcB4tuu>g`yE{tnP'3vF|ؓ>3ʾ:8L D+Adau(qˍz$ -<(rٛ- K!an RHSislLEĈMɌP5Pt -Cqx+ 12dYįG1 h9C'sIGՐ+B|ahZ<HpBdzN4(KoPdN~V2lŭ{I&wqH$z FZyĎ(nת%|& -}ɪgU aWKʖ6`@P ޖ`"ke-Id@^2g<_G>s}FiD!7SDQ¢iϠz8xv" 녡L)ٵ[BV-}TeHR8M*.{I4\*ψì_ޘC5lf; -DL|Lj)$K |0+9?ph|v! JԧssoFʺpU4C|_M -~aF9q:1E"LB)$&,3u?c*1d ԓdFv6GJTH!3P[m4n*#56*_4+\da=v_IJK)[9 ` ' U 1<3C ϊ좗K]7㴉'ziZz40iα? xOHG%hͺͻP.7 _v|Jj.㬏D% s?9x9ꉻHwYX+w{L;LM?]u*냛~+K -~!4l%\}7߀De0ث륌CD䧘q *(֢ml:d0G(| ^hk,!# V8v0dQ4NWm*|#+wJi0/?~+.o^EBy`ʼn~D~9 -%=?غoe@?.P-|CD..jkS?i^PާC/L@tjvpuB?G3%ׯ Ta|/>=)KAQV&˩ B*kS<4,@W`Q+y0ͪ4Jۜmk [Sf+rG>>U2DTٿ';9*"'n@6@8 0XW]A~poY,Aܗ{I>Q^BG_KC7,үӏ7YA1q lii %B@/b0يl5ֵ}g#Tg Zʎɜ|g&ؘ9I 16^a d{lo¢/I꥚l,NMͱF(C. ʃdƚf[8VpSlo4bsRϴ—P) ʑx/85"UYD_@Q<4J @HR(xOJ}Gne;. -fEW %#Vj=p -mY`9YrC^1 (ۗJ{ϲ`;TܻKEg-9hDRitIKJM/p 7Iq0Ges`CArYMl(˔x'Rp!FkЬuqypc -xa5SAQjSh)\ -3x,d+a%IP B6)0}5h&̿ɑ YPrYH89ɸI(rɑEf 60IuY#+ b:T|uZS8^F $hXHɃ{>ނ'fLNĨȡ q_6!sq" >G mr9uK=}܄_ BbAP/}WՅg[OAÍ,ȱ]|!g -/\N9BGۇM/Du⬁ FZ8a{pE%ȇCө"\d{ In7o&j텀j41B&vf6g,(GQ(B@3p>tb;rQ C9nUN AFS:Q@ $Y -x\ǜ7>LqY)ζKZ6 B4&\aT N8gPD G -&$SKy8U R@C/ȩgS./8'_{x]9RC \@cwf*h?Pv&= -ho%=7:ΑAA,3 d.- T+F:xXe UM_[-ό,RRU{4QܵQ@@K)鹲k”y\s-ĭ#8 OE/qUt-OMtEjq7GSݶ080kK䵮7 -63Ɔ×oge6`?Al kPq1s2d45* w>cQG_cT 5[QhMfg)*Q2QVX"CV&9ngֆ=kp4kEYlj7 kӣ:Xb|;em SVG*v1k`ZcmT 5]>Y=Wζ=[h:it|^,8 $t gEly ֆ -tBw54Ӛ5CɅ(%ȱ-!dW[{+_\M(x܀H(7dvJX*Z`Blz8tYTEz%sx^"ρN@.GrҜ͒81YIiDBLAzo댭`=Jk-<z'XIjQX0F -̝,DX$-uX7# ZGIX9dl ha h>FF?fqh{%6ȀffeGf)FT gj+bSчt<=Ӈ٭㰓(l0a;רVngFkqу2$K;igƶ"󑻊qiYS+ -eK'Y?xö3DW&ޔvV;wr(rgnq*2߻w0D_3Ϸ[ͳSNP{=F޺y1u𧭑7FWUqȃWZ‡pr#h-q}ڎ\D"K};w#NF*{n_X~M$Oבˏ!3+LTnyǫ-x|*5Ӊ]'MfG䟞oBN(a'' fK>d$$J#>Y(ɧO''T$|OG%iK+7fn-Pb0 U&_"KXmڦ`!`HkJ'Jŷ-2^L|y;mZ,Dʼnoˊ8/'>j3)'>\/ 0n BL9?y\0B|K?MY7Vwg-KF^#K|{ 񑿴ķݜh-SK4p*!d:R_dkMfe/Tf^>\jYA GvٳsС 3..M#&F5ҥc")P˵Kr/)94ʼwhvLU#I6=4ˈIK.3xCm6PX`Vrzfmϴ# ;yZOhRd/P.-I-~ -L5N0‹ߏ/x[1d:< jQ@MLDDLDޭ;B+`j/6&ZJ㿒 ΋Sћ]aXg8Il nrNa+ cv+*Wp}p ^/YY} ެJ>A*#>GFB4N^ ?޲'DCuqpv\H2Ĉ|(VʥHw2ΨѾA'U5}C,Q,~DGUj -*I^}(`ԾFK*1D{ˌoj&9x!y+r{ |ԻitH/2"W#6k#*9^O>?(kP{ 7<4d>i3SN鴕b^F] k}K|T!iHXn(=x(TyB_*'aΡ.ۅ:򨊆]VF]:ۣ=KHԙ}xΉDA")(# 6؝"@rWπԹW`pP\A;{[׮=iuo5wcJA67!O=x3Z*$MkW|*sI/&B扺4g'eΩ*Ҝdb^ -Jۚ Z 7|)zv~~ˈ!kց*|S64ƣ)R%F@`T_sy'KgAjg*lheJR1zML'Q]R(PT{uw2Y !7[X;*i65r;L W9`.OPS$Jg@'@/rTbW.Ե6"VwqEak Bg{)9(oB)}XPMb(E{da"+bjdhpEsZ -[BYE a, CH.f1`փ8B^EK8x嗧j`|?iۜޜ߾X3LōD C[H5|b)x;"zNQŚ-{hLl6牼,P.Y陱" -,D=jh ̩)$ ( K| C_8b [V>8TAF=sP>'a;pmX}<kΜu5L-,Qu"M3⃳F<۲ig+i~!(}3xi*EqiH5!f'V5]g 3G5/%nq74σTjKV^k9HF8|} d;?S|Fay jhL +0?dCBL%d32#qsS0nws ]^3i̙UGn6镚o -W̬*_2It.ڬW;Jx՟ĝZ’8Im-?9wJDĉ 3~ǬK;!I{;5dy - ̪ʾr+IWLE -͗X6@05 9tNVn@Bc5!xO&q cvӶ_%6! hY,8 c-FIEx -iS=C3%[wk:ݪ<χwAjGA84D=+6$Y(9 閺]Œ<8N ƔXQy0fhc i&sI߱ς.r0$!l)/HA){LGxlGXS074S)ɾh@i(>41GK,G3p/@Kk11Xaa4JM8} "n-9R -P82,Nt zRzC?@^ۘuiQ2ZWF(-7ăs avɱy] flb܇Iw?CiVj Dx}<"ab+hj&<I:d2O/M}nӽ س 8m'j4N*GnIfl -iO?{7 Y λTl,U/& /8khbG~Xu4#f",#qw.UI/cNhJWy"L^k:4~y2gO JaXAg;ԝ=w 2ﱤEҲ-@ܯH L _L8p|Fb#Mr3<AvƑXUvsp"q -ٺ6r WVӬ&!Hsѵi­a<<\06K imlR2M2E9ȊD|[;PrV g 5,:ʼnG#n{)ldn#%k"LsC3,<_֘<%YA, xz^KϙJ hu!= ->1o[yĊ8]$3EQiR*ޭxsJG/e8=3'<2NqW^*rI JP%AxŢ^G 슖Vtx.OCMZ%JܞrDt*j00dm;9\[|5i5%U0'5rwkO_pJ( -a.<'@Qq~Z_\I _מTK~,2q=.< ℂ_We/{d"{9l{P z -{ 74Lf_-NWND(F"@"ru}Za}Mxe}OadywGb8쬏/-wZ0$wJofTM\=9OsX']s +%W&jE~2P"'SNNB,3/*=yieOS|;ȱXʉ1[BuH,yaևᰯ8120]M \K,6;ʷ>}΁.چ7 ila v+scXSvGrSlZ,Jreۑ.d=~iPn@tsݨ lXcɷh-Ed"L M?:;XP/!Ď;..1k^8MxKI{xcBR(Э<(-y(4{Na˥[#^ -I5Zp:ț*(Jw$uJzIS-紾" n@ -l%TYu!l|bŗP¢. cꉅ9UMae p+ KO}`Jr% DB*)EoYc,f8dDA5ͼFpICտ"0(O%/+E"zU ^:<\ԏП80E-7]V{FL"B"ۋȈ8%8uNPk -~dX |_ -iq\гW꣰r>d @4nœ5„yog…f]/Lt?HÊ gz{gB$UȏAt&`Oؠp9a[Q=Rvg<.b jltwT?~dJ!rsip)sDP{]dVQpz8#epD ?mm{:҃ܓ ԵDYͷn۪ou`(Y D a -O,!dǵ-ʹrb)xm_ć되|_PlOҳ,vU5(8Lx(OݸwL 5fY,KunhVj>Hxw8@ݖscޠ7a]O&QJB\Z -rp5.=6WkZyV -XiavVuC^ľS}k(krnAl][* }ڕ$4*(q')MVyQ=}W6T%(}tmX&Ҏ7c~ܛ@MEPFmx |ܽ{3lp>:m#~F&JiaXe2uu w9 'Un<dTe+%Fw:1_[a+{}~ɷKCk}5'K-MI3640ri}ZQ5 -jte>ږg1k%ːE@ gxo(N3DgKcndq+`oçJFyi 9&Ó1DDN -_P1 au\N\gXXE5tFLAy1C;Gӡ AIa9lyr6:X^Z'!v skNa :$80qE3f8#qSiɯ^Nl܎:7YcH}ۆOF*L2u{>ab\+sxk`R77l6}1båAm9B2,)yj}8%OUhQW| -*V"%e!T&zn~XC=X\a4iV^YMyK{%m(}Wlcdz^sNDPIl|5٥o8Am(+Wڷ 1з}lσ8o$_p CsW4I'4y-iU'-05 p#vqJUYPgL6ҵA[ -AלQ>DqGZ&Ձ -5jhP~o/l7t{ -MTLh郞0fTXB" v2ܠxR#^l7h]XXem47L{tz:Or+ɠf)w 5pnwsD`X'=m A2]D HbF6?0U''< ]2,4Β]Ig f5D3uu,GMΆQXQofi0`. D r# ]DFxv@{, s $7?H^* $B2>F#(3Br4 K紗ZHb<3XTwyt+]`C oHRW&~C}!11Rz/C(vA$luHp5A$JwBY"1s -M$rFc UM$v5"Dw [?~tH*%HL&Blj7SA` N$ DbDŽW|AZ|,a=ggK+w [eR?@PʏBC(p*ǩ@FGJJ֙c $Itޘ^^GNd\3vJ$ (\IYØ#d0>-,\#zV^`'zg؁J/,k3 hm`d&{O":QjS?GQv50 '1yr )|_wyД 9MLY -Np'ఽ$quWQݙq`,i 3ƠlwSq[T#ke.3)180s%O޽ڲH,2[ԐX,Ϟ>.V?pc!J.ϾXL_5!1aǮ:؋z~v t -#דe`c3,Z0iaӌIM.B;U9c^ecX-&CbO3gP6" -^#fo.JWL n\'UHiiJݼ QՖL^昞5J)ua@ ,Vr;-0ϒI/ (B-OS#W!S9N,FBF"uv:ۻv[+{gd)Cѽ|ᓾ|/ G ?hiq^oFW>g} - s< -cmHsu_?qgjn?kӦ>spdeUsRg ?˒g5Ts3(',uTo7>%$Zd_5"L̠G "-W?bffIFL=ui\sQ+{ѳ왅~.suVgUSJNSc;6M)+l$gT gǢ9Rl!1sZޓOWMI57`]<ߥL<iW)fc[EobXc|PFٴU)5 ->e8@iVD'|2NX0Gs+gR9G+[w_o6(> TF:qO29⅂Psb7e(,?^ph=g,n IT Gj@z:?m=jCRA{Pγlo('[.ܨ瑢JijHo { UI+_֓&Pb5rmϺE=kz5rOCZصJxv⌭(*Y{rVYx|hZ_u6(1Z wg9Ļ_[ć8̾ -VAg>ydXsvEFfG+aJX zɖU~ O[yHz>gA(jXG p 58A7y~`O9P)ǫ?6$i^#!UI+TSh߱XzlYX+QHƅqqi5%~81:x6RƠwv'eWެ4!Yx|MZZb7Alf@9_r{5#WCf%c'6kFY2j"\ܶfiһDQ7(,HaW5*6M?-͡mMќ4?+ÄsX'si8Fk)jfPTb&39ؗ#6f P`@]lɡl2_ m"SBi徦]iqqF; mkSw̙#>X\Xl|1 3=ddZ; bp͔t'%`2IVD $KzTK#.q:+N/4M^q.O. 3ܷ{u _jCܰV@e-[rqio,u)J얚&t~ؖw[@RIRl.:i- am49rEZz*<ti0Yrwj[)f;Tae*f6Y3Qjil",xu?wЮ3ݻs[ xyW@YWR=N۲.d!Uk]mS TIe CT^-RN) R6D)5&B2SĊ8r)"8w2y4UGOH~,͛}]HɥF_@DSfqs4>Q-b>\$6(DFP[6ɿ0sC0g2$~X%Zc'QS+z@rWM7Iw"i_7cIc|4 AHI fXd+$ߡ*y%| $*AULdrK$?J"mPb d6^l.d䎅ɒkЈ#3= K -~2ca3{tLZ)Bp)sHոx#rD OI -2FIzP[^F$o2ژѝ?:L{q(S;'` 4ty - -.OoNyAwWin%pg?/(@F֙ !7 mV[A6ӊ5gfbp䤚OR'lEL7򤽺BS/O39z%Ey?G+}\JDuZ{z.0'g -#7C;sHvcF -z5DK ̩)h{Swv endstream endobj 19 0 obj <>stream -3ww{ӯYZB>ER+4A _Q\[ꗫMK|E!!`3Ww-Ĝ[eP/% bG?m49|]>eaھoh܊*J!w_а` ƻ.rΧæGK!/ (z {4*YD -l ƿB5 ieuZɬVD\3,;o 8@q@$)L)g/Zw^6]EH֓X2#4x_d1*ISV$n=$zד!5 r %<2,$ѩ(#ʕ?eXud JʣS(ҏjd/䕙ҮaYy1D̞99KY>XqI%jbpc;!'dtꊻjh(bl%!)*qG{[P4sפ^L35xIi]H#z{HTTAUO&A=l_Šh/CLaN!(@ @LHs - u>ƫz* L(`6Q /a<8+UEL4XKWBx]@y#:jGVv-i"h`;FbfetT:RJQ) }p($A*"g&ӈ`M0q35 h3,hN~Œ&S~F !b)$YLHyT F1C4R!>f, mhB!s -=.s;GF^+ely_PQ\cETDT1%NL2,r -Z]('i-N|7Ǣ":D,^m* U5>E`+ȕ ]S29d)ꮷm>A35"BK=>өi1+*^$Fe1>%LɎkx33SՠzUiSRv)}iEZ%ELS^FܯLig/' uX2DwszgP^)W67.zycyJx#22(5ޒ0HQ%Y%*AA42դS~‹x?==!:n8-)X[]BZQxn'ȝGȮH6ұˈ 9mL̜:2ǙigT"օbB27gd,JxjBbb ZwwWlSWd5gc׈$ cDMBRX"NW2O\.3h7RNNT? uⷜ쩩D `k(&X%#5 _j$bc#2K 2cT_H0N5S r]TQ=Vd1E%娷Iv_1⢊XA&*XtE~)DAtiLӑ!1$qIF%qy6pK/42n6^r©ym53#"3e5DN+1oWXW]a_ӱk[Ťѐwjùu$K, -YMhO⨝}-,;WVUHRNe3L_t;ݡ>D$O5\pukb9Hp; kbtZȡ|U iD(%"3?FY$,.h}srz -]4ʭʼB'LB<<(DD W"sR_&y[1CSHS/fgBL#MS Mt1ɮB?XKzbhlR)hhDuvދ-I(NӑxtC&19LGhBh\ -V?Vnч:e&M;)t'画qj-Y#)VL6/ћxn-k4T*ꮪ1ŠwHQs/~]VK4`4V-n3}_autn501Cdk6PzE-[|/jƣds2}ia۫^☉{"W;Z2[cZԢ!KH˂)n\#u܉sU;%mfVǕ~927;gᖮcǤݡ,!tZ|r/"=1Y ]DFy"GtxlțNK_-/R bUЭz%Df:٬x㬄)*4L% 2*1˿0אW#')cꪋ~V`RAxK'ALQGŠ?HaRl&/8B)P< b -zh4ڽ'~xgR+&M=_4}Y"0(R)- SJ\8B&>Jڃiuzī Dڤ|E8&La7dA6epp\s&UEmq΃c\<^gDNl7\)pҮ#^]Y4_A`/AJg[7K?3J2;"b5ɄV("w1sKqxR?cT~4TP:~e *ɳ1PR24u`ZDKZt5񲙪c%pfG=9*q =:!0~LH3̹}؟+ -ť$f53[3QhFQ]Wb=DʹJ6{l|vCifDt])Zs U)yź7ϣyDhcbD1ˡ0B[UcU("M *EW.IĠ+TP0X,R-0/Vtq{)EۈD,RXU ()?J(^@aENcG&(*PHkmN#:BƋNL}bؔqPcz{~) gAf`0LP'(x̄N%f"Zp[cSGۊF״&"jaqTDud/wm,!>kB;օ JM|*{|1X^D^k…a#ҧOb%nTSƨVBQ)Vlni$¥ѥ+=j.sXkU>LLvORFf&D{3]qюQ.F4dK,;'CB8$ 5AC3F@CCD+ -4TS:tLEH|6a; փ+OxG+]ǨLbV*͙A\l`h J"PEr[I>+A*z&#" eV% 0 Caa0 Eap ¡<@@@ d D 30@#C9 %9oyaߦ(SETHqjd 4ϵ|D"E _Ƥ -I$QĬrv{d".C -mdѩCr3TrpOwz5>ڬP$h>aec`ܒr8ŢYR0VGH:Q]#+ھ|Wh5KuF6HrhgKDk=t?0ki=kk  b9H9tXQ(TĿ_P_grň*;[A"EFD_D&'JBHh"ݛJl4/(d'::"Y)$3(2>ZmTjZ`#ȑٵ^N;4Nآ KQf;G2h}T.}6 j4tsݴLg+V9Qkt"\kC4aK44v)YRtbsTM]e袗YeDߪ Grfb7o:n5 -}~tfHS9rrE0*3$_ iO!ЬQzrOPhYԪԡS ns15͞Ḥ D9IDlNP8uiVNUŴ6Gd&,dQ*9KզFMԛTqRֵYUe5F^ِ9oSr: -ɐH,֬$Ri-ܸ'蜡f$FhY} Cb 1U(/ &L 3yhUq+)Fk(ăn  pk\%U\HSh* %\$\Vr" ##$Tͨ$)œX: !!h} t(`(#QBU _]ĺS *j?e?$늯b8aJRp -xo3u?HLB ZZ?ʿ2Ks -p:EVk1QmUroZãSnM.&.%1@JK KkSpwqt6 /LH *߂xtu=6A:q+EBÛפU|T+R2 RSFLE#=Ea<^(v4^*Q)Õ5Ὺ;*R²dP{jE; :?89ťhW.|zeѤdg $f`:nʷ9LzFس+i2i?o;WiɁ.=f?DG?^~7Pp "2D&1;[\\XYc탬$o3aA|5կ)&5#w_}@sh%|A5r*?!&֏xꤤM~D@(͇mTH~"[_Cmq/@Ё~<$5.&'vB>WbtPh qbyf|bFpRLkdZD0?XLw2!?=|̪fb!s0r4@Ɇmtʓ3;Zf͂uN21*YQKg+]q`OZ[|Uo`LdÇID?~h[V%46> wH?_Z yl 0/~ڭ7ÿXbT K\ ܗ 39eZ*BFن7EB,K+ uH-W+t~ͮAlb 5y?㷠 5&摨sVGV91Y[ 111\ihUܸXY"Ӹt Rtx6B4ï2 [*0A=@aG]Qˆ߰3y8?R,KQTU ?N`"b -7=/;ġ: Wc=A<*W"K zEBlaMi^b#~W!}/ٸt@fS͚5<Ϯ -!A 4F -HMZ -ǽ400l=Sf׾ -W`~BG=3; -3M.~LCa%iCٟ/&yH6ftBz-eC}"n - dN߰ī025=ؑI,,ի:`ŋFw&jh#뫺&=%YԖIuΞno}{,bY(!.o5@* k70Z:rlꫪzގzؐx.3U?V=oDG]JXt9~ST ny>+@^W=l_#fG7yo%/'tHPpFhXtV9(t/ƏVɽo"&/p:$ =(8NFPuM_, =ͯ CG "e&3 BtB(2اT4-SOWqj'/bՂD v>{^DDyt~„}kX 9_]tq/ccL7"$= |FXigB7g;/C$X51\O܎ |ѩ(ry3V&P_>"8~#T >6/fkoc< UeDDnUr!D/Db9p%RDR>}10PR\(4/N0"gS~/Gʍ.iI9. &pDA{4K a)%-o=Lb@+3ZqϨ;T= =OMCnTQ>isIuq=dǻr|7ٶdw #0NVk4~dpQDrseBJ -Əh#,FmOcqw=xƱ֤v(lD%}/6km02 O|/q<.)oY?`j\YΉO'Q5M'>7FZe?lf.v"f  -M-WćmɜVV! vyH ER>rl}&Kk;UH,M>" ɯz%(!XĨsu} -jw˒Y_"Y_օ J(db@8yV$ &JLc~ yV#98`c&Lbn'>p'$'~e&ubUYǵ~mO|Ēlq8?o]$J?%(ᴮOC22cėC Ŕ Y3Dmק( Np=#>1fM>B$}GWMw Nȁ|]iµ;&ᯢڏ!(wH,Mmkg|䜮ف|$>JeZ -_ -> @C(,|?4mNU'u2{L{83MMy:#S52=*Y!]nN ]3R43Y_EEWձMW{B -]B>DX|nNI.aV|_qif ])|oX˵A=IXWw;#9!)FM u@=+El|_Q"-ZI  axGF3s,^kϸdz[s(7-WO eAy-;j:4^Cސ(SBơ@ -o|Éme~ 0-=plGf9Y/xmjg?5>so^1/[d03N>^!rcȎl5(-rH(P+m _\5[”=' 1lYR yɸ/ n4G ~<`\| Ǭ?Yh97BSyjzrz;6'U"&қutd +-1%kIr%u )1A?qY%q~:r XgPF$t^O8%Z:{-9)}E\W$"խsue($KwlQtf*F*7wL2-J+AINez[}'K}-4 -#[(ۧASLL=aSDMʺ\GU6J6IR٘ Jѡ۵H -]nyYz/LN:?'oY^ !a~nZEPPӷ;UPU&$0@? -䬙Dm*T#G&S( %0rNN$W7EtTC3.T#lȘN-i@i)A5z?TpBL{=uʁ` t@ rs U=ܢ lxm0M+mINT;p0w V]Kqާ]"p>3(,AH>-$<,oH! -L7g-+ )9I~j+ \N{"b8)y3u.PsƮKס6y>4}.Y'͂ $qY1Ib`kg?ɔޔDDA Zyt#3:ʻ{ -sԍ]5yޒ!Տ"ɨW-|Βn$\WAgg=DT46#b,.%{/%V1I?)Vij)24݃IMVJb)Ez`5Lf^ &ɔq݀ h[Wtձ?mάx':SkO<4׀B=`ЂsHt QD.CFj`輌H ߮R!?a۶'%606},ܓ.n_ E3B0{Z -W2)HW罍`e.lT5@1 Hdl;{R[W-Dnf?hjY}F>WUٿe,{gĘ~KoFA #{<8~%v=y'B1+±␙ȉw7\ro&j -q%Sp _:[ 4սq1s{,Zd@+.Aj˶z*LNT۱N\u62BZ!Qr~٭o=4Ӳ(T'E=;Z_8Gokz -0:K2MjQȊA|UV\`wq d) QqQC'Qxe>*c{`_ؤhVTNj?Qؤar1TM=@toXAd6zP*E -g'%Qk<LjWeVTe0(_E,oF>闶[f3!:/4#J<,WC44o2WW*]*¶XjFRv|5^kbUz8`F/9"_Ӡ~0E -hL˘PS$T K7};̿%F0%{}&vA-2{CL( (0 =킛j{#A(F⑁ QP?K%cM_<1|Ȕq-{e˘y /<_y`&9׼{(Lϼ˃/g;/0wnꬲJczXϷ7INeC:X*#o5@1 -]dl| :{_UkFX>ȞQ7:єGg4"]1?wFx1|ϲ3łQdnt^. LA~V}+H܄-(МN:|%yX"e|AŔ8[KՂLǵ"%)àD^|f&gbmeKbΆ7,N)+A!ӫ>T=>K\h~y?4iQ(({+T=М\ƏLj1Bp+:ۍI]DwI;xP-džod7&^<.y {lXw?R< `5 /"qJ!24Y<#1e!)~@( 2vqw#A|l\3^xR&~\}D$cS~B%H<#++CxUIBH8Mq:;x 7nlSa.6G 8J<?LuQg8߹e-mx o %E`^Wvsj'3 I/vk4~SOaOcM0SQlViLҥ8mIA $ mVUe \/vTJ˕>@W_أ ,vcβ~vb u-ĉvIEgz'ش{jP\+)w>u.q c,xNWgO# eBa4J/BW ї`߬(M: #|ӂ/x`f /xěɿd|^D^v@|@3W >OBG%%f =eť&uWr ~Z:" rG.3="hp.3kfJ@H܂'0脁.bՂMlNLKc#Lcz $ڂOۏj -:C -ڂgC3tۂ* wQ`r*N1m ^%A+l0-!9#MɑNBא+74T(}|.xK9_N5dӃƗy6 [;Uz=C5_z{Q${41swn4&r0bSF)/F+NNeZJRTXDЍAX2XיZ'8pdIF7ѝŢ[F#_LRF5*@.S֝gDk"%Uza Z5l[0\0:-wJ8H8^U#]v+Ӣɕ@1NZ;SsOB8]Vy9߽C8ẍ^\p3 llL΋2S'@ae:scY3, -ǍүDJRwMuJl4=AJ}pFj}pndɖ6և(Sy+(1_ "T^ ^ Gp -U҈5q"pHDBR$iT++Kg -ػ*@ejPy3B(z4d ?{f4R?qF?/ߢ⚀Hj8A80M3@  -E7#\?vތX†iQ^*q,m|/^1pFnwu!' "e"@{?qpC|>Uet -=q}p&8V #BoU|@rDFK`@#dʫ&љH y>~MxR~IT+R>J&#C̯XM'?=LFo!M\eT f8-e404HR5-RhbRH&-(h*'@Uy5 @%8K`6דws+4^C[ N2W/ -|t'? "6XF%+-G8iXtH`} JΗbph\'%T$‰B^)Œ ,/X8P3S/)Fp]3. 3IpKXFKxfJpre(& gvƄ!fEiݣq?I8J{qH©LNa0,~Fs8 '4Y"Q9$M:A4pJ*#'Gu33bcFoKG'Xf@#X%-hq ap8K]iM\8t)SEm5̓'fD, -%r $a+pRұx"Hs90:ր %UaqO>1dEa_a'U mql81n0qZ<Nkx4{!"YH/zMWXFZօyO=f-4A>@3ds.@\ޭ0Z $2iaן \Љ]IGkDt# '#U:^s2)|؂:yDpg->+t2&m~,At;]革۝|<Š>HWzLKuH$Q qpr(aN%H8= N˽xԅ$8탐犇͗KKظuǣcȳ)SZ̷2<FFV4W$n'zz -tV$h#Y.AA;KX`|S=T֘xY?OFV"InJ$8ӃFP4{#Rǔcfyu*>-΂%#=iIҋCWI m;< ^\2xÉ|oOLMFMq&r9T.c$=AZ_,_UD Հgc]9r%LZk?8KbFBsV0Ԧ՛ʇ`^P ]c9a%m,* hH;cO>4hVJ KRv~S7\DfznoUB&,Z9be[PmE-LѺ0҉tjHQT8K.$.|L#meeΧ*B8&,)7y])|RKҡV3q)XgIxNJt 0iB!)H+_%pͪ>=q%Yէ' үUe҃8b!ô|DU.Ϥڈ@dݭ -t‘yc!&qptq`F_`?ŸCzp4qeI $ds6Na\HI6dAWQU.f\7Ď՗$ -|Iɚ*$ip.mlˤy0Vx:Ҙ$4w>0{KQ>2Yw/i2IhYb'yڋ9Qم8FQY] -N&v -u`8q` -~~ Za -tcaj.>Ziyp|?gQ~.%Fΐ\Gp~l ][X󣬬}t!')Z4,mD4*_耚𱹏M]֎L7 G;q]?9D o#֡8A4eIM}8\L葔Tª:O^xA|-pkIo*;PVͅ%tz9)stιNۂԤ]NV }I;'ڳ ]o^IXtS -qDjҾ(܉8lNM}`ZWEa|ƗNr < Qp['~& `/I$gf|.q8-X3o 7CM`c$ӆ(R70vj'*UZU u!?Ad). 8L]=3?Ďdjȩ|f!p>?SzƄ:~`1V8H[CpLm2PBɡ}8ӱ;/iq|q 5#q"]cC -fsqf|IT~I}f ?G`Ǐ-UF/x(膟xh)/;2?Lna)&t%ĿIq?KȏQ*iW~<[Lp*rQ@ ؒ$ˊ81 -J5 -/uz'eh -J -+8U%1Qe$.!^ GW{aX@)CO}ŏ[?a$ -_L-FSIdg5tя -^̏{öo83;}./$L> AxM D?e:. 42 D3$2?m yyQV wR@}"\hi(w #8/ĜCOṓ~ ,'8M=9 `HSP-#>eQ wǃ2?s@ B*O@!fqn\s;Ɋr!H w˧꽎;mPo!?~$~P;V}#Nx<+$ {?~B?>yY- u8“hdI=M!4̏sD?>=N -~&|wEEhQ; P,Btܢ;IR% -0|:),6ݼ. ?F]VP%N -Wu[gQ6IV80#<#+ sPM:#I*TEIÎqsՅKDPJӳZ8PV`ܶ7"z̫4Ӭ*7~'cKRjry[XM^z24䲲Nzipgaz|IPhi:Iqg(qN3p ~ }I C.]'I$7Aȏf['OP|iN"hVE^F|'tDY&~Fϝ#qďu᫖[cj>TTF:`c(?ia"#CQt4[tďm[z򀪈y6ڨ@p–rk"[b4ftHtNGډ !UPuďKF~-7="]y(hh^qNFt}>O-MR_Ԩ_p$~κI Qoy6bvo~ [t2:0T' tU@ d%P'#z ֏'ٝJWKN/e:)xrepG?E&YrA̷MI+!m}E4k.ZMlLҧE* yHsʷßKM?l(U?](fh":]u tw b-)9fM".b4T!ev; c/wy/Fca̮xF !jz' ZO)~ڒtPv==%M&Xhy=C{KNzG$aD{|RÞ4 凱Z@@,I7xZDM`Y+Uo=EOz$@Olٵɗ$!OjBbkR0 o怌٫qSOtyz]3Ph HzwM: Ɉԇf6W=EhL -Z{ˀ%$}mXV_l`c@݂ DPI"N=Gt1,22AX%ٚJrJ͟G (hW6AgJKZ"O -{[[Ř(QRep%RBh-,)M%Ց)np.<4mwB)D E6ąi00^h9 f!'I4[bդƥL\^8OpjO80-,/P_bɥΔV,v4F)ct-1߫+YdvXegjPa -kFa*ӢsOݱB{W&ΌKܸR/Tӫ!$BV<03,(&%|YCXZ9t 1Cⷭ!& U.؈CbuDHF*s ^*TG4&54 N#!jGtgF"]'PW.fB5Q΂4|}>"XqQJ@-+?sH(b&TUd$hJ^Jg7tӊE`&S4unhXĿEE\teȋ|с6얃h5rf8ׂFg\]4m^!q`4RhSb)otm"@eA_P)AX1Τ4$: 4W DLi HmBY\&*MYС&62G>~Hȭ%?R>Olw{wSL[X3j9[G^97E/tm1qH*%:Ĩ; G (aUһt,yHbEPɹ~H7E9e#hޱh8qa~bw9 C#  &檁>wBT: c󅤍Y+6I^cE@Z-N^ ln$=؋oJǢ䗍q90SלA9q.?Wלyˤ}:L@rp,X!bMյs2MT4}A@紣FeRst( H Y8+H4$RDzY3Q~A BFq5'H\=q$;&H-PhD€ϩy(¤sڮWL@qTnPBIV1NHZXtG K R#]H6G^BXl# ->l0B":=kʴ$[xP AW&JNdb*wK>ӱ!ڝ`U+iADLTn~f7Iew%i %*^܋&$K4˨a-h87(ި܄!U+qЍ%1aѩ$E'x }<ug^~s"y(}I ϒŻ;t4nT1+ȊH4Lqpzg]-azͽ!! <bCNYI 7WH{EH&;N˻lNVz ȝjFR}bܞ$Y,t=fӳ<=䁣!ϓA ܘ$kL' -w"_'} IuwO5@kǧc"4ݳ Rb@ -RRC}2`ȔnD3?ˇ׃꧜QDW a3W*uch,'I%/o -íA;(.afWYY \*W]f *CqثtTB%AT`$V>ںPcuԬPD|3XBZ;ynZF<`튵lV3J -K KfA,Lπ,@'Ԏ,)+GXq<`)(O^2q[,$KOb[aXj-@KFK`)P9paEm&僥wCIH,;2Er`}^&u/JN~QS.&V"=6tǽ㒤itLJfdW*eLF+ _)=er ìPT1VփuT,{Gbׯ!-! iK"JJw€*\s^`Ғ&%3x-D*^B.ʶJS467R1a2.ݛRK iLꦍDb -й0ugF-<%Ns ^xO,&4੍:b7Y濲pP|OB,`Xbb?E S&TbŔs=1Α^"F2||S{C x&FKÏda'?ICNG<$ɩ I)Vk0|oe|-P\&z!(6d* :dB-$L0L,`y2AUZk,QBd,#^1J|&Su U6 - mDuZm3~N ȴz7 -ߙڦe/ 2͹;f @,|i!e8PB -ԣ kS=3 Py[tLb3\o񛉣L6]F >iwN*OfӤ WD|3r5x -ޚ`LJRD"K '6 Q,7m"W(uj/jft0ʢ=&'~4ː^3J+Fy 3<>ڑ9:.-[Iu2d9囝Nd]ÕN8A -Rh2e"OQ5O!27z)܁0 YQRWYO"KewFj(F@[6Otml:0wY9"bo"|=oFچ' "n=-:ui=~{VR*~u屼O5?:Vc!2q6-5 -?AãS -=:PFx?SF5A|N@9-,UKÌKTTYK='跔&gʘ*C+C Oa -6NrE}LՎâ8&^_l TG(7|f7M UR)`U6;S:Y*+蚴q%9R"i@ʡqSR)"??h VJ?Zӆ6 *LĹĺRP43K)gL!(T*B/0S7CT~&kTe.M$Bה) )<vQMTe#+/O}_T4|W1- R!UGr*_q>RU( -Ӄ̂TW=)Nt@n,0J Qa0M80~* PaTJK1:1*hep(Z]<HZ>҇9-1$n1*a،TŨdHTfE X.JtHܽ͂FuDd_hΊP,c:J8aT(ٛwy*^VvO3 gBVٓQ4\kߣ:j`_2{=*^zT07hQƃDζ]QI-ti,NlN#ϡܑ@ܩD/1N?ܔN10jS`PY(U7|(qk?47ZÂSN21R/]ʉqUs& 14uR@ȯC({TsKZ}\$NiGU/7 -- &<X*=I -=^4zTq;٣'i0JHGUk)Vjx[zT t[HMxtO.Q FQ!jRGHaNۺP|Heԫ+_Uv"Q-Hw|mU!Q&՝Fa &|`I._UeHiB\ѻP,GU5r|2 <*)NP*d hG*1ʤώ -%B1;^1*VFP<6TfE8KGŮU÷ VGyAp>@dd@u⨦fjhDj -ñ$(g" EClMY"sT}|(a GOBvpGk()!^o`(|2/9*"dǀxURO&GE. jӘלjoTJm8DP{:Q?1^8ȝ 垔[;eZQ1Y|c7*ߨ -6]3Q -(0"R -JZBc"y<-؉wz{ߍe N݅NZsRS dQdݨ\lT=;Ōd_T[k9U 5PquF%C ,ޘտFEdR'$lT?~D=xI/ ktEurʾG;66Ie" efWԕ Gˍ -v1 F媈_JэSDP#QU˘P^ʞ:0$aXnF9O"c!1FRZpթШ bMO!  -F_ bOJvFEqYraS&?ElШ^S$TGD9RpKm-k>+R\|;nkTFiT < I`Sv\Q-SVfBLsWQkeTCI;갾|I*/NHw"ZldTʲ }M`v!hq[tQ"s_Ȩ킘6ueqOONJ82QSm˨;3*Uw;lQѰ{Q]_d*/ J992 QޏW$3*ϱu7Az35JerPU4F^dZBSϖapre"9\)Q:P񜹑|4Jhl⎌`Z1Ux/%g8 ܳ -6rUz5Qà٤ .qIj {F%k.ؓF<:-dtN)$ֻB4y%I_44_CISN[j IrY=79Fd?׭Q-ǒJר8)Q2ʫFՒjը?[  ^۲Ix!M+0I[K@M.N|]tAҒlmߡTt5 LM`f rL(ukPyFQ,FTU(G -Ȳ4ګNdJT8eݽP)k)Ɏl)y](n dTEO -QA"JxYj(UH}^+<\ -W"FEfQ* 2ofI ̢&k4F0UJD!é#,?F?xk|MJչ.Jsf򔏚N!R$b┸ *UAMDǖcK+ϡR` &S>F(ϐjKf'At1F$z#j?CT>+eLԖ+32)V2GucAxP*Ucʕ m~Bh̜AR^Dڑ Zi:w ~K%ϕDT䔴JU甼}jٌ_p?ҳfƩ+L,dRǮ(,Qmp>;,գC|Z?*,UkH}X[ñb4y]뗒cqdJ>_tx9%͞G6Je+}+ddk *-_A2m/*}cTbQ[+}~Ƥڈ] $$]x!`JP-V!%2JlJR- 3W}rST?J2*(cA~p!I,OESQ,-aQ?`̺N")~*hLV`=$F*3("TSRg*pGSLSiAWja*$a*>L7>Fh50滩bK8%'20kAdK( \N4D@P S@/EC`*prL)vǢ6mg Sq S]!!<'EUb@5Le0Uv# aCb:Ѣs*I5FuUVwζˁ2Lxw:HT7,xd[1 ix%{;&S56:P!j,,6ETD\rxd -%;Fدd*8;LUP'ɣf2MoQ>QL R"S} >N =*.٦LU^ٓ2](&7U&S;QԺ#WDb^:2 uo&\jT^VZv 29mXTi%X3e*w'S kc~[!S#x7hܓ1'SuY@@PVv/5դ."h4U K.5(@MEKrDM^ۏR4ոcj"V@MTd| $b =l\P֚Dt L85FE6M -{*Q*Ċ-7UfMu8QB?$}kZ 7ٻt1mk*>ne -ķ^#˚*?ƒ]SA(5t**K9GHەBh)ߦS07 <1=t**wŃ4ϛ)\S&N7Qe[g8 oЩ:ړSWߨS=ڤ!s%9UQ˂%t+GN|Y.߬JE%t%ۧB -{Qޞ}ܯ>MQS~b`qN~l| -On\ : R@fUa:h'ߧ 0{ѧK^`$*o )SQbZ2*>dzOo27?TAyiUh|5A3D',o7A6j|[h5FDVZ #'qԈ*vV|lD~IBCj˸t/HCc QU(oDUZQ %ߒVE@keEcg!'֍U.'ŠJETcBTaXvFxh"gHsO#UPǥ* ćԹ|Į( ~=Q* -i;{{Ҍ8dML -:kV|DOn; yRACQ#. ]mA0Q+ %ueCDUc=& Bk[ӦAxMh5X0J+Ha>9S!= Q5~Ue+r8sx+D;QMT <@.og?UzάFJK\5QZ3*ZqFwM*BCXS$UH6q*WތDTDIU%$Uy7ЎTeZRmxvqHDj;-pf uvL2kTqUamI*Bf(呪Fp :iS l: |rAne>6 H?<@uQָ/ðXjz U=.c{*2y _U`؅بn`?Q?f "9D##}XQer`ݒSUlsXdl"7lOvwR5B7d@ĨRXXɳwc2$!޴X{iFݤ\Dݤ`_J5ţfhcỈMou~Wa'=\nY%_Vc `㍪>D^#ܛ{ި*W B}ꋚlT*gF`Vۋ ب7<ZJYr*lAhDx'3Lϼ uʃ$co ʐ.`QpMH[ -#F">ˬU/b 4ި"YzǘFo;rTQ,ZntTK=} ߗlZ=^g:AJ1^Qn [gHo FA&34F74$h90MؗݥFy~G. :r&x9QY -Dy UW7T"4G bX|O~ܰеQuøA2d) -rC -P}DQ i 1AJ@@-UU k*㴈ChTIoT1jaQ?FUígQUf _?F6ڑVUԨ -lV&Ԧ5m]I?(1g_ߨ–S}U`ŦK4WE -/M -RӥHY]AC^ Q FPQ%Kw82fQ%h΢E[ GқۓeKE!} !;Z(dB*ub*sJC)Ds-In_  6f%@bʧr"T --K\:쩘q ;,U/RiT\rVT%à*S+1Ѓlh7L$TQ, j/m29U -4*-{ U?6U+,Bda=#dPEb! Ưc> ؟1e0B'F|C4*iKv8tnjP%'DHzv,L~x`u]0n\@io]rC]Ug&TByI"<d0ӚB՚J4$y%TIҠVP !TufV/:|=N.2IJFh%Xףe\u5<FZM֍Npj^&Z5mT껸uQ8/gW++mBQ̕K/صd|SǴYB.OQE[sa+E0]7;Q0Ob_qI*qF (<wU>l|<,3nOUSؙ27EnfnC!ʡ. €h^ZJNc8y\sҊE O*  $v,G\U%UI|\G~Sk+5`0U7[N1}3.t![ 8=3ŽxOGάIL~p]VejC{aDk<,fz$S8{|wLTgqtbݱ$mGԜӡ15Da"@49Sl?]䳐Gɬ1rL4rT R5=A2lD2 y jȁl2s`ܡ> /ל6K< >[b>CV$׼#aF17%8C?S,L-M!v%: -Eb -em%yzqMlzh˙(.ήc3>S]Zq86zXXH,땒I-X8::O;9y~qԞWTv<Ƭ, N#Pu#,Z{xTaMăO1bBrWGgӛ{ed8 1*J߬{ⷩ'sW" Bo&H3[` -=T3GKXNEgW{EgA˥s1I<mHQO_JptnPZqqjmak ¤ k ?5E{F8Jce>~n hWL[WZc=ˑ+H1)eH>d+}ˬ{cV2Ssf=.MNu6H2yũ!v&82YBDLpFe%y ^{ gtPj];~X!뜝 a#4mQ~х|bH|!'&Pc+nG䅥<{Gg > vy䫫u3q?5oO{nJ(D})Bm\8FFvuT+FqF@;I|bD?[C MsZoCJM`7?ix8j_>&;| O p- -zy\賒7E8~$VɚpO4AX~,D-_lRAA O DdgublqN={jĽd/Ƈ)fV! -) .o Ac/V3;}x a E/.0,5{aɕv-q'# Tg-&\|ڶe,*tꞄP5:eKxյb!jh< ^fmE^ 6l6i'.c -NCg`Յf,αLbs6A'BQWë7;DLc+)exG FRaʘ>!s@FܕԨ6 *,!هQ]|Xy퐘TM3!WN`ӓd- \=H_?RK (|OhM (􌅬[d7*So}cMbxC6G=飮T{iQW"bǹjdBP8[/=7Y`* XY@.9ݧކknwwQ*σo9r!<: -go7.h}` LbW]+–,4w+ -NTol7起]CInOQ[zW|4(hVTY/ך2]+25ɝ]uU?+QrNKX690-Q^χؕCźXȱ9ޒQP| -r.24.bƧ+&i%0nl}(`+rsC2]D:yN1Opw/nC(lx/ds s 7u#!l6K2[eC . - # $6@(?8ߴiz~y-@x!|' VN Fr0]8?{Pj='EiLA(ϼY~)t p 4mRg?IlĢv|m~ R-l"=gU@?yRz!Epw9bNL9{˳.U3K)(TiȽ e?O0zE=1&" -=%balz.v2[& -2%c2Xq2=w\; j .^6ӅAln[fs4dHQ)->{o\0f Xl&*&(f @d C$ӯic݌LX 4.Hic6Rp@ugj6wNGθpH`^Q_Dx^w@M#pϛn&@ztqtbe\rg9(T? +"d U5eA/8&^I]y厸f\" p -aM9"Mׇ䓓_&]Tqom#p >`=Pm`}θ$ߎ}b=t[Ph_1!}>5C`K92uHSmxtKióiZ*-.,VСLm͕G))MOG\>\BBRFL: JMxGO G.^杠MԐ2V\ U n+`GLJxsSJ?"I 9<̘/#u+z{em>h]S۶8c/Qg!L)xHP5Z3W aw$,Pld&+uK>B'RU1pk*b9*=FG0Jު_06 ˅@,KyF"4 r,ύ`b9 0n`HT:>/lq92I`SK>'^Fos~9;oCMymbhI=5+#nIDI}Ҡj.PZL,eA}%D"= {80BזkEdV)f79]`Tu79>d˂qa;ɹFii<Hv:snVYlWL?XnqC @<@n)6:Yl~oY˜dALo&^̰lj;'f6xʆ|\54!V߰85dL -XA[6gнmhp-C93TX1-" _Pm˹?IHLd+(~ٴ- WS>NSL]L`N>w!gz# eu%Fcϭ_g+44_9 !?.^YǴpfPL%U$Lu8z]Exͻ|*ؐ +ęEDb@qtsXsfw =A"XߐBySi)2VSJH^ H !$Os"<0 %|0,"" &sN9NXtۇ()C`(T\HSRR]A0B'oNEph.낹͚([{ԪCzD>L8TP2Q2j݌qddkt!Uş+a 53,v֓A]W-N&"4&a~Zb긱n|!x$.^<)/q?G<pDyy]tQ"(s%Cx9"7Q~ތbJ#!.V\nrZP;1.2,GLzXBTWh)}]U-q("!BW) 9)DQ^9D0[ !mVNy*?>Ci󄷡 -Z%SS-aƦS)tbߍ[~Y(_b澥Q[nDsOg&ܰL.&lF V.ƚeWLK1Q\0E"?c!"Y21PŋkZ!| !Fo)B Ijs!-R W@3x>ZPC1cf4r;d9NPoG}7"x6."DF<,BN'>`Ht4n1\)Ek\"Aޣƪ ac hPRYc0-RbB>F'\T{Qsp``0| ^&f  -BZ#Y BOZJFA\\J#3["(e4f}PN.'>;Bf(r k#ż -.ܶy1 pj< (xi ji*% v]Z_ObJ -:pMp+qf.>WÁk-#h]<;paÃ=\kg6n(VqR\?X.n3V:]|{I>pA=ю?J} 9pKa/NÁV]K& R}h7^xJ_M$8 E \v]'EC% u\r -rE'9S u_qmBs9\aMI"u,.ὉU5Dz5a&DqS/6&#@Mfy= .y ;g=TN5!FNJ̼nԄu7nAR7+[nWp$n-vmZ{Z4h܃_= V蹝.Npx\s-uM豹>kWu_&E>g̽苫?pqp3L?{=ˊC\pp>i -/po],DQmy. si HTXQBt%=h 8_AKH`@>\U{<(xV0{\\8^zG]y -KX!& Ѧ! -^QAg GhzrޭF @{Js{PP g,.X^)`&r4)xg#lߝvg(jLo4uq=9%8e:,uJ(26P -T:pA.Jv(-& SX[b\Xו]\(-y ': oN .jƀ?#2N䔠5N=CN Z.2q_-l7.؄un LTeʗK;^ p_\pb2Xe"E8O,' pd8Mn1d4+gw-ʆoR>4-)؛ igj j"`y¾1ͿEK bI5%*#vۿh. J Cn~-JkkqQCIq8rCkUu7X˂77ZAV.ɅVL*"u׌Dn8@ģ3+C!,NO[NedU% Zkʶ:[X%>\}W Lm@ޒ"Ŭ}No,1/^GSQqIm]IF\q =ubʞf4\̲ TicxѾb$莐Z1ŎPQͩ: s -8-7OߢXt2b/w+n -x S>rHXR0 -(i&" %.epdxL}ݓWeM E&EPk^\̋Ɍs~m]pRW>φ lfzd-:-BF -65,cxS?a!lFtpaҟټѿ[{ |R5ⳡb\]VJķNyCo]Ć|pZ --'ΙSٷx>ch1-{!-=E$r :Mp>S>''(z}[ӰwtM'}AJ#rB}ߢye"@r,$.!o\_NR:U:*Exo{B[H-<^ʲL@znMk4_ TA<2'N G P/!4ֶ*R5)E}KD*-1ef:[rffԷ[/Y-Jo1A -ԥC~qTCӶа@HfA"#)izs'v͟o Bh<ƾy | Jk'U!h Џ1:E IR P\@oa5 UYn6-ZM5R-c/J(i.} L"]Da._z@kF%'x|Z,%f $Ħo%F@hAv3`ou,qA'Б:mO2` :[*_R!<1m~|+t -O -! c -^k&a3âX[2dZYp{z?WEꤨJSҥ.āxO1|e0,xSa30oqu$.w< ? _I#W}ht5T~iQM^Ѕ.e߂${u.%Sd7+L*M-o>Il} ƀ1P*h6jKq5<+f,n' )HzB?fyd -u󃢎^Y7Ro|{%2$ -~7Sp[<f7@NPI-¤X}^O/h8V(2 ir#pW,9iSb"w=S՗oaRIscx& QB; -JtJMqg 4Gn(lGrx70^X, .J[T7dVSi/#=-Iq[ham'Xw"}$XY,X@^[ص3o"X=u,ncDXl7y b[{Ysz[  7)|NC`y"z #3+ʍIDݴ()mJlW~ 縠:7=pXş90kY9W"o 8?ic9s;[IP'W5ApS>Ǘ`88?o1[1);`‚ [ujgY^xYV -?οE$`{drX`ŲBhalR-:4R %VZabVWX0@Z![auZ̊je -XEaoM*+(y++WayWQeA튲LVQ:ŷӭB -eM*?gJVVa5E{ qDz*RƩ5~_м L@U/FK<%Qq1SץJe%'T rTJxx"PP0 -̀~ -ӋW>EI)SpVK,1X -1켳xR`VT(O5)8GR(),E0R /=QH֣0@tGF!F!C?L/?KE{Er(IQD(xXE(QUX|B`"E c(Bы -⨑+O˂"#(‚ -P -[''+}'r| @ JZFZފ> jb栅kdB#j mĥL6B.)Z22uC9&0&^L蘘a0 &0&ڒ9 M " B%K[K&toМ%hO| y+hK|%/FK}/4s(8-|Y8K4UK&.k.tX.a, Bv훹o.Aďl C~@].e}ՠ%,!}aDf/VbU=7e X%@JKdThgXiJIQhF\% JJx9EMS6K%S*ᛠ KAo:4×RV%Jq0iiP?[S 䡘?O%:J -h%M?24hTRTB(r\o ;UT¶Q&~m~ SiJ< -mnmmtۥeܡ"Z'DmA*Z7rh66Ix='i4u0#Gtq.C&:#O!\G6_IP]nBL۝$F3-$4jDI<贘Gi; 7}>#3wP/T$d:y!Z!Q~QOH҃ -R1(UHl ȶj%Ddktxf'peAbppY-j!vijM8OGxbJI#8’ZFikĸqonגg#е5j66c1 ˮm5xhDTU2#yuV!A¸uc}]* ĖF)`M6ٱKlOmaqDl,BYļX i+8+bdUX2EMd Qʎ E'б:h6D3We Z"lę%lmA7""B ц[D$JODzVoВڸh#DmmA! ٦ۇpGr{ZF[ - gv(^oKWQppmT%{q! Xn7ns+`7t;nCu!Jnv#w}\xySzsCRo,{SqCN|h1ַ%"q}#wtC 6/ XsCIDvLn 1f;7n}F``̷ߎ-!sC.+1hpރ ߱p;7᪭ Aj&C_IY8!|2t1Z0 …u8g!"WݝXb -aPZ'D3&D&%DbW^v)Q.A` ƃ0BN]$Fw+9uplýA9A'9؇3A ~UrBܔ`wy'EFJ8IF;<ĩ)ng <*A-(P>q"'gF{Nzv@AN;A0(q :t#.pZkuK,)ĕI4Iy8! T:D98 "u".=ÿ{ bSd0Ra -M\N\Mqn"lvF f*FLO0U~>-=!7"*ɝ% b'W)WqQ=f#Q&u8iB].WDw[/R9ۘVs9m -|AX Eic[PVt0~CuQ{ӂqzA4&Qk\%:ɟ8\Qxx[+9Б;D@[DB6Н-.Dr2 a$H7?W3]}I"n A< }KpBbF, ULQ,kuDGj(+"' t.C+=9Gu@L=8ߦsn@l@sչKw,%\r: zAw - /@̉. 8 э(HǮWT'"9% ‡hQNa_ |k-g#^>al,>=0.=={ =b%a=΄Ht+Ljխ]y(I V{d<<X\|yx0h<_x}+k}w'zndu3 wnQq:\p;j *` -:PnZej::Xt0yDC_Qu@8Kä!aGqJ*Eu*9`<u{ ʢLl4c-3R>}9Q Xɾ8̺~|f:\n"9h Ag۔҃Q0+"| i//W2`82z[VRuo2^K<{b@ {42%\T"how>gͻ (q|{]u߽.3N,z]~ӀoR0\wvF5J/Eti\L]uz" rN n}.Cc;e@,9 ~6&~LOؠ}P6A`پ)T\/ |ʐIB4e@36{Dd&b%d}LFso<,C -)VC~ ~1TǠ[N(p 3c %'{12~n*(ѾxQbi{OC àAa-p΅U A| P(">kߤHu w0<`BP_Ӹ %PT%",x酯o څ1B /<.] + h.DLJ0t!x*.aek6[ B{s -޾㶠}e _` 9 -BR 9-4}Y[B!+'ZZrgfO, -ϲ.PA)b!+(ѵAFٽP -}>WoW`IWr8MPBھm6tm9+XNVR $پ:u\Z1_*MV*T> -3>Eu5ۇne*0/=B}М&ح2 -`1^:GT`J52쏓\(#4׾H<=x2>l?/cLÍ$.}d%־ҼT`Rr~n}$F_վ9[Y*O$TERyAm9XXIKTTx&}0L훯ڷkߟZы90I8"Gh)UT k_0TByUB1 ,&jN@>*TPoԾi' MPA '5`GU"Tx/QW{B( -0&T8 m)}PA=OYM}1.THh vq 8 JD }|X'KӘ,s < k_T8 &Xk_?7WkB}ՄN6M4K -(NJKH;cbÄ &%l_M9Kxh -o mߪ, ,VU'r*z)Aϖ6J %0{T,'Ir%I܇J)$+(>_x3 mH _KVk̓] $daD#(iGt?9'# F'E29ɼo8/Ӕ!@ۆ'K_Ё]ShǕ {9sHN噆P{_Y(hrz_[j8M߳5O!0}}5w|ཏ>Cr5kkKT! bUB(d!tR!@ (&4A -ه=RЅAk,+~D# B  " v`rH?>$?SWq<  WM>(9ǒ2/&> *>Uz`à~<( (_DP<8-XzN877(I e /{ B@_V۠4mrh hChAc*¾dk 4YFP`*g4P&:? `,zg ~5p [,~8I}h/q-A75P B o5~ ~VS54Hoۖ/}{ ԠßPN̶4_4h}0EDŽ 3_30^f ~i Ђ_ˠ~y)ݓ F C? Y( y ~?n WCo L H. 1~ -1^~B6"k[Wpmkmnc\e(ÏQ-p ^!(4*~ec7&~9)~Tj( Z{7" wx*01;~%V5qi 0x -bA&Ł? o0X{? R -㷺tB>u5yԒ%OG1 Gd23zJH"I Jbr"E"F "D tԔm*0 'b!(088X/x_Vp0_r3V d^Ŕ]p$}}ຽ`K_DŽoeT~ 'xlʯۊ 7삡N=+㸀/-\-nk b /@_-R~~1LL']5< H0bPC0 $}|`#큎APzy8y\No\uՁ0MD9́}凔/r ߦ7hd|lh=6`[~O4RŦDlMKf Tf/)߃  -@71p@h-)xEbJN1܅_LUl5]( .` s 㲀c>_? - sT`kT@*)`.oW2Nf@?H')P̏>?凕lޢ$J޾)+QP̗9bP`>O~[8 xx O@ Xb(+,H -(P@DXɆ?~ (' 'z@r$BbVVr$=3Zd?#z:܏%??KDi#/l$s+Nh'D " Ov oPHˀ!q\NQR])J`R M P%?&PW_֔J@eiߑ]VPt6s@ˏq bGW -KM6Scg{H$({ msCͨ*](T Cv>B}l&(gEĐB@䷛TZL@m2}V#9F0Jz[yߢo3YJ'*}CT]hqBOm“'4>i? o1@d7*FIOck <>Vi~=`^`XS Ro8=ӿ˅J~FZSTo;-mLs:%s)Ӓp4 5AL/vР<|rF_pD:U]F7l]qO_DpnĭڀF)XVȪXQCv]Ep4Ф1p?b]!2X- -3^ʀ -ҖK(]u F Cq`a )ZN@$ʲ x |#;x~1‘X.pi08 :H/7FEC7DR&tBT5kQYl(T\> ޤM+uD_Vtt0lE:n!orc N@Pf(k0rD' 164K6 n͸HzǷ&I@I3#&L8j~QMbv%`\\7; `о9=EPk*zxGn*$`\N<=+CF q$8R)8pT}8G~ ˒Ɉަ$ÙK؛^|I. {B&xR J*rH@PvmpؔSRV~ ˪'Xfätg.a<l_诣Hkꞟ3$4[V؈v=i86kxvpbIj/\LXͷ!zP{ $(ӦI%J\egnʼ)T] >YtpG~+/?{IB,[LaPӌAL'G#лQTSi78 8wl;i[xgfs 'eܐ^?[|и"P|r+L|hz_ 2q5n(αQZ 4Stq+DlP{S~^kA?re>@z"ȟ<7 -zΚv::}E'd\hpPBl9K8'2gR/qǹ-MWҋYDPh}3AӪ8 s_GG- Y5XYDx'O;X"z*F=)At/1v=)CC*WEg? zGx0GGÔ$oG"3CDj>i dTv9J}YB;ed‹NS29tTZD XX ?2͙Y=(#yTtgRs'cDO"iu.QH ;*3*)̧H-!gqH9V(4y(pQ=#=\│~i.0\?IQP - bj"|%8ʖٗ ç,t -@_ TBRHH!"O-'  -ތ=)1fz|bo'P]/ 84Mj1 -YI,4[:~ f@ 1̌0&yRA~_0^$L.]&HD@bJA+&ʆJBMC,hRe$ ;PG V)!~Mtypn3A6l?p'ARg&El*dTם!C5X|6BO:iAHNlfj,kZh, @UhسڡxC0!J#q?VJKy?o 4jBȔ 5KY'l9aSH:cs9yj0HF; "?v4S48Ò($fN8v$zq:  E&U1P4҆M"v~1,UŘ>ZK GI"=$nB`m&`եΰ&AIW5~/8`\O p^~8%*hD b0Ms=@bb˱ iT>&Gl# QNn!(hmŧ@65WALp P`04 -?^JWф+}qe8Qrof31稰$ڱO73ݐ<7_<=U/GxT|CÏ"؝3Q=4.% @5Đlt0 4([RY,݊(z IDf0p',mM`}tJƷ3݇\h$eȍ[EN3u]]h>"xp^Hl6`n+\ho=Z:(eŸ'W \ -mfMq] F~ϔBƥ^PV,6z@]V9亢Miz3ଝtrcmm7Y \X<_g2"' \oHsNDRЫm]$u$f.9˪(@MCɢ_mƢBm BI-#T"E^a@Kikl:I@nz J ^ TG -Өp -#C'h)Ii< -CelE6X~JT -"}J }{Ku>SuT1_ڠV}ڨ[ʼ͚Q`WlL}q53IOFj9Zr^:J_ St%}+=˔~?pmjzLcYgY,ٍ'?QcT3H:4tFMfd{4~})B)wMߍlY-flaFWR-/Tt[yˡ V.UqSqaWɘ5r$5NI/JWfW渂n~p!h^ů!GZc W4P c$#UՊpթӯ4lzeqHE#B u7 T&9)9=dXz2^oZ4OJk3q$bz(4CâRU\-Z5tʋa5n//Maz["+tm~存a1GtzG6Q5ۛ`YuHq_e쟺Mau̙?/[Drbe򅥉޳}g/7\>6fAn~cn)O  -LCh|y{UGb^1*bC1hX>mjA#H e`Afotq$%L 8lҌ٘ *Y2mf7.Vg]3z5QUe5cNlq1$81DS - -/Ex43k*85R + 'P,$WEo|&(_CK"A8ZbBtjkG  DJ̔D!fy(OuC -Q>4X`&,JXSu -9p7d4  8h8X 883 xx6RR˕ʂ#Jg#Z_R9i7# -hN:շ얐٘Ndݑdi5\XeG'8.2'PI'fedIf"jSX)J_PAYw׻] 7Lj|kŻ_rFwfmδYʋؚ,L\];>fdO4rQ@DUpjpGV4)"VQ\b+ly1DV1Ymb]`YEz{BOAD ;yw8BW( mT "#ZIɊjV;(H78DvB]}B{O ?T!rgቡ Z$!cxhFUT8* (xP".W -DڊR)LQ*Qb/&|qCXd,0(@F(2a"!.Q"j0K1X`` ! QjN4bS}M`x%( -6S"G Ϳ q*lfӢUX*%>k8/b/b4U2"E6)PcVو58mr]Bltʄ#!}UKJq<-R70R,P8qL+uzsdәMh%_|Ħ._ǘ .8=hݥ#0%^90XRw6(Ouf|!lӷW3e&Ӓ1tRq!m6Psrknⶄ Uq0@bYm@4z1edKlI띨*%_+'_p%=Hwr<5TJ>j`=N3>ܥcJ6IVSg lRe -l`0fK#P}٦-xK'ἣ cebu[`g@[=By R)LW 2 }+K@fv5lPWH14 J&j~ 6* D M4V-櫁m0;TN#ڈgx @%R!߇@z'G7q'Gkz✡.D\'WB݉# 8?&0yay=y r_9i?l= Jѵ>{+`If -&ٙ{C`JgkI:-Ӑ#HĔjۊpsO Z'*:3W8]ZxHQ[BǤF+_JpVl -TWgؔ]"0xETkXפ$^{֖Eps|.vP`E#X:85^*uRMy*b88L|hg ,:ު 7r.{ dr-jU,x,2yM氇]Ʃ2&D/hC28u4ԓu&\Fq374#ߚj,x!xYD|yqf}&J:0.:Rct+WÅӞ<gKě82Ouᵓ ` qkJ=CLv>r ~i~>stream - -ewmq|@ -LdP0H±qه,0r9Ԇ %4mH_go ]P``PCR*kU{%aҨdVeV2jrOQti:IB3n;7nXJG%-^Z(1d)_r^ipy˼Dl1Lx}:;; ы38-K4. yjlR4-71 ׯ/A|zcsC s4{Ti ,tOBk,-P{۳܆[v]4_rg&MU'ow"+qpF.^66*N9 -i7m)Dʣ>&uQBz;x KY;%򎀇@<UC|DԤrf}w*nHXR +s3&p8J6#hk4Ԛ1༖N`_SwfՉ8+n/|'c1^ l- ~Tߠ --]#;y'sS`G< Y!)/U/wAs ;RAHU;Tܬ==6gJOH \`%=*ZS+SI k kf"/k40@AzJs$Pk@1`#*vkowb`T#:zl&#X`$TJ;1pKsoiX^;|_LN7rݕ|=+)syE+GP2t4?j*q6c ~d#yV*!% ;.(W3p&+a\( w$/\64s| L j Lʜ=fkZV5&$hO#D7@%쉉bO)F53 soV9=,vo,`U'vB |]0P_q=)Z& \AO) gl _>)mz>Wޟ2ZtP(duU2$z_fXVJ@=ןXG\\C)47o» Ҡ)l̑SFO$1 p@Ask+T e|ŘϿߓ8,9 QQ͡ɞh8py `~tKHǚ0 oau'P9 mR SF`/,Wv [D [abXp χa -294qq̉bf :Yf4຅`J򢸀c%1 1T).#pvM.{AaX !>u0xk{װ5B&X]ÊJJXq[ -*cKD5,Px :6,p1a7.X,.̾x G{a(i>Xamb-,¸6*[Of^H ӸF&(/Ϸd1,hƭΰ ϰ,иF-0|E&VhحL(Ѱ!&ڰaH UIvPR%p]x9,w01 mV7O6Нbb%5prYni5.ZHg>cQcñ_/ -Xy Ꙓ)qA揹l !j'59.FF;VddfH5dA^8.(TXڕ)m\`Ee*{׸`۸`7.(23 =hYg,Yvk>ek6 E3@fyQgF=2aW͔IY5゜̈́7gY٧l3יHPͫ. daB3΅ &4`B>5Ȑ0}zC24Rh+Pm5.@x*tz]IDPD'UEo^4 gq߸(hfJAk\$hVLMh+Z"Mfno\ʜ6"1(ʍ }mFDkl2w̹ NA}} @wn\L&ږnB8!CS싍6.L}j\fゎf @)l(^"0ch^(k\yBWЌņ@s( -Z`l#V搶6M6MCYePlEl{| M+^Ǹn/ަs}[:nf\(7K"ݼ["$RU^=Mpo3.oU8 ;o&^oy{0֙|{.ҷlߎ1.4dZotVy1. #tE`\\.~=øHw&ooߴB=nyqjW >pwj\k&9܋yIq2"L b3\o8p Q\qL┥/8уh+U\ }]'.h3?qIX\;q Jܶd8-nqqs)s ?g隸` _\B_qES~!MqZ\^8 Oq5o+SŅxS\=cg-i91_/.c\U'L4n L,e6x|gg][mNI&efqao[\ tqzqƝE$(Wm/n)I*\$o1 ,.$EC..w׏t8qiȸ`^2$ƸƸpkyS@6_]nɔ-|I Oy KQ 0.-G).-=}qIxNu {X\\x&)rΒ:wݹ4y^lt"Ч'_ @'b0\rx2]en2sNP3DPΓ_EGs¼%'"Ity>t GI;#b\@t&%o\g V0Ey'BGq1&f~e#K #*.\9ss4+..9Ņׁ.BO: ߾&]L,kt}t1|(Y:R\s|} u"n◺}>uCݫCX?Ĭ_Ny^> :V"0sFq5Aht@$i51+7XXD(Ȣ\R9N|뚄Bk>1q-ҿ{~$uϦg-y:d:'h0Pq(14oQI4}&..O"f=[VňC\b^k5׍IeAoI ɣÅ..>Tsrb]GR UWp 7pbE]סI.,U˗d.zl.vI.Aԃu"s.\wT<{B".Bi^rv1?S$0=gg G?Y;:vۛ)`݊ q܁?\l".>w∋%w~|^w"N?1$]r dBν;׷3$n\x'DQ\Ĉrړf0K(gx, j -oЉס+ޱ]'.#}Ldxd0E{/Eq!: y(^W'޵XxM\oHp=#?0,y8c`/ZR]K1@pG %$[882ohao_o ;xƦ*KE(d߾oL }}rRmϻ\ rvU`jH-*`> ! -\_>Ń&a }"|pN۾+\4> ƿw7}DщR"}Lm242Tپp8J gB/)۷0BL`7} ,kqT2yOfJ1xK.p*.hkxgv ~tpO/RXbڰ7C_PaV \Qˑ/kQ77)T1B緄=غMP}pOK=a\й᷃ &go o},C!i!JW$.I} ,@23}h^ b}T REPP*҉\nH>킋;HD7 -.h!e>$tl\(;\Xվ 4YpE[Ef4+F< ϫ^p!>ewtx+쫞 BQgB`/t}~c{yW{L#w}/ynp!/_w.~>0pH5$j𴁘>\xpup6ipK>?  .؉KP .}eB*rdVxzj76yx#P( M}H&?a$fWzchp\0nD\X-e6T\$_hpbpzڦy 48 އˆڼOࢸ>`ma w9\</;)[j>&Cpr2'0?9Dpw_J\4{P#檽XL/hJ\|ݛ}JRP>5€.o}8E({ \-s}+4[ \ W!4^{"v|}\+}1'O?;ρ3F\ &iqP+ -." / ~L$]^ӑ D}š"Cֳ -.PIZp;Uph[ . \l0ͩ!@#F5s ^IdHpUk"QO#j,]LX \#/)?|Pv~7@<ɵ.@Dpo6 >ONoG߂o߬\~ˊW4WE.Y9<)n".>sz -\ B.\`379.6eR .3o)!J4~K8`4rݨX}G?ި <1"\*~rX\/M[’7HĿuS.8w9štjmq Poe]cHot§ 85A_5O>#̾煚DSՀzpqE$p1 -GSyN~}_wK~x&pawF~5.fOȕn WkgRVLyG[+pP~Sc( p!+Og|Yt 5@>^~EGf-[p!"OԤ3G33 eU~[r51j -@bUpKe˯Hv)"2{IR\ܸw^6WoAA <. )b Ҝ_Q?`~'Tɯu[h-7[8H{?:~ #th2t.8ͲEhyum &o!*2[|y0JS.-5.?2w|^o=p:\u*7Q03wN:>t$b(0ňE h#BzHV-n0b`2~iws*8IxkoQޟ(CT Nc1=y髶ŰwsQd{IG[|.X*3 -\l'O Ĕ_,!-^>A(}c$E{j^CܖNh0epoQoǸ|J2`EN p.U[^-$\dRA)5S-ꪑ[ǒJKBe囎I;[{Us NGbQBBc oagi (&T}KH|CGRTuz,9ߢ?ɥdl;Z0[Qg:P4$-eS -ukX2 >Lp߂%)}*08'ڰ%`aqK%M^n*yOdV쑧07! 7lD񖴹$A pKom@\\Z`RסΤ|C -D04y`pQ -PW paHVb/e1x8Pvp:?|\.˷/`ti:RQY =7M0@ c% oDY3eSLכ.4. GgQ[үL - - -Й&9ʙttf6.nS|iw%\_*#Q =(P,!HaUÄ -YW+ps1ezkS`+.p6nrJ>`ACX`y\$#]*Bz/ޯulF VClsO !v hrG:4 *_/4+*eBHCE Qr7 bs͎|\JB.d]ӡWÈYtao0H^^b>x͸QQp |&#YZt-7wKEUȶ( -.BI`d <±+dΛ|\%ዂ" fb`Nd -Ap^s9v nP`Ap.0]4&S VݥM*[tp"\.m=H,]zÎ;3#MXDEwoneVKqŋN=-CT"VCS^!ŀ4Q2Ynz5!I%kp*U=2+A* -ӣA}(w/;鞋=KХ[҉2BKs5BXj߂f§uX/b-S̫hI(ԫ YpQ^Úk @vqtaq^^ L8Dָ‚aĩ8A!#/@QDr{+/]-.:Їy/]P?$bT>+B҅BbYn~B؇-y9K< +ƾ]pQҐPMȃ|X%rm٥ )tl \ᷜ2QK-]Ћ!dZcvzEXp*[w?rC|W7* .)|hpџ\4B - Ut!w6SlpArSabr^*[#nD)rQVrE`[J C+ܨ7O3S48mcxB,Jp .r -"i >\A] 7dN+\XY -/]0\hw`qT1V>p?;O^\&( BWPpv_2X07Fn_@ѨيV\(xP~ɗ7W*sX\ +ŕW]pI@vK1]PK\474]H|jı@SQå\!)꬚.si&Z:A-ќZ)[TQPEJ*2\ԐMkH=Ȃ촑p7Ÿ 4hߧNgsBgC|M+>zc?8ާsaڲO~pXcQzJX慪l9\?@bvD 5GGBFNQټ6ItЈd6@5`hMlEe (#-~{Uy@g: MTd|w*v\(>~nź j#n9fuix3\#.L n4|d${ڝ N_%5Hk6_$(pGWNQ &ti"pwYl=%tN KY kN9E..b!9J eqW+./^ -FEE5`\ 2vHsVt&/F7q b= ҹPYȋ.nӣ$02 t.mGl.nP?[k.#h1 1etC_>L݇177?xq0^fGB:y6OrD `L lKiRs1"l-BA:YϺ5m.Tbٶt:62?E+TxOs$\@b᢬E!j[KC6{%2,\x94 WF!; .)YXx! 2}-.| uq TDA65e6##˚O(N9$tT#Js.s!j΅;& Qʮc3a -.Zwr2z7s.0 -+(;P7@_P+g!,}mv@os.D@1\Kn[z%)'Q!9օb(sO: g&Ps.ג{YX~F ޸º,ߙnH/Aâ"_O>B™dDp?ϴvIpQ/*+}lN -NȲ>a/EMRLYjw*JuN_Iг')SOҬbL"F\L@* iX8bڷR*_7\|;~W -.b%)@j[0DBIu-*ƺiRӇԺ:o -ok ) -Fb޷, kEDƄ}V/0lJ8?ZpM'` f5jՔQ3\l52% 3jNd,y7x\IȂ ^?nF'Q-7BCZ$~IK$EnҫzN64GdEc_ -/7ZP<+ѻߓh)X? "M/.O4 .K|R8q8{s֫6{"*b²Sc{Ȼ܆Ï.S"V0%ȑȓ*lTs9m$Y -7G H7~ |"X -f 62ESț .x&:s5( B \6! jV -^?l-8 X*X; f-CHmE9̕NNčrq?)_팢fwT([p;zIk u .zy9\p<#? nE#% `\ô!Aܛg {v9d9p>h#B}kg .*4ڣzbohSe)o(E&6+΀Jh Jt-')Ӭ .]`xBK\-u q" .7T]bP f%.^@ \wY1spьr- Ll҂)[BJKuEa8Ixiz\# xJ \6r .XQ4~pμΤ<6 +bBk \cGT .`j%proj6UTWUX@77r>,36ЌY+[f6Qg85B -6P~x9A{c/U?,ࢴ(?C 7&S+ne6IT ^AQ@!|Fdi -+aU+\1nL r4:B!rU6IZiXbHi %V}[C"*t,ZPTma)Vܷ -:UaGhEub\BM}vN[cDgK#)cdpUu*_#ށo\f2j!W  -6Oro:GV!Ժݬ"LZ{f:lp!pɓڔH/VQYfmpC쒒4z]ˀ".Vbt v@sn0@b&ㅅB0`'ak>bB+#}fIՂr^[uW7O/E]~֜`lCZLV_˒+\Lq^wv.=]dô倩uT0qG%q'C` <00 ;&->Z}<5cL׳hDhRVmB\ v "y}, \ = b'r^^),F^l6v*,ˆ>0 .%NK |DG9 U\ t쭛*y=Tel\+lQ~ e@#6r,+kP:AK#Ilf\b,cLL -%}\ʛ[7Iu81΁˝ࢂ[}Rc|-ր5T NEl-\Iߑ - xRH[&""SqN̎T#%\^zT|oiQܺаj -zFZ\X/eHH@by8p0hXM?pgYn/ Y}. -AQ5/ y -9f - $!? Ul}nQ ΙB|ŜN}oかOH%A*NZ`?r~GʁH~LE5`r]lmP-pH,jTp|z-U/5*4#Rj?`,neը % v*&Ԩo+7zXЃ͎lTp=9f"6*ta \e!׊S8|Z56*oBŨe{. _`rg+: -"p1א.Oؙ.6*8|\MHFeW$52( Hi -;Hi+ \4pEi+9#pACi΍ - U*OnRS -\lPH%*zKtOJ$?%*]+9 \LHǁ-+.p1aU_ bZ& 98ɯ7XԩPAD)"X)Br=#LȣQ}`j%\J+,w`Oyl)삛ySCPLJnux\zg#ZRKa_OEf)^w@tHvP( \\l^pTх+~Bk}b2s 9pa~T.%.`a$/\gKQ nQeS \R[87pcC JUBIfI .еb>Cg^prka̤p"_WA:bP83+PE\1 Xx TMO7Q <<:~t'IwҝtC-b"K؏(399>"(bQ;B؂W}fjE[BC4~ - A`)ˊIkǍsIzTFI%Xj`Hʿ֣B1`rthP<8UK2{ h=}hhvX!ԛb1(af4C̐aJE$M?PB5ڑC(YPIEiEOS,W4lä5)L1~KaO!l0?U˛m)WUAm`N."Gg~ѯGCdHUz!yR쿫*UiP.V#O׭:.U3 JSz;ſ_LN<7TF^B}R  -k v8JΨB"l4&>&ϬB#md4I)R@| ؉dC hJH/ET䓧XbT!W>|-b~xyKRAhEe KI46^]. 2<z"xC ShႥK 3^-c͓ -NWB4*PgJ'e\)_"Q;+n[4ܢa=f"0.UY{'vN׽Z iכ zV4eGԧ@VBUrI𣚷Zϑ[>^z!4b,T r'_]Z䦭c.tnU'$s4M[oQ>;ʇ'픫%8jSJszܢdu"9YzNr5/BX&ZFnˆS@/(PAj_>fWr;RO~ QmjEG.zas䲼ڤheZA9fRq'-]7QR&AR_gh]?:NC7(QtsIM}RɐpOIc! eIMGiBSpqP<nםVEèM1'A>-{ &=cܢ]j7hOc]bǞRI,JOj9v#eMw2ɡ,I+:R͑jzJ8r;/[do/`b,I(jU{>WG%p7C܎TӴ(aE_;es,~q.Xݐeu3 郒ӻв5=N!_DV-QJ۩GnThBͿOm*ߵ8rՖw -;?멂Ր>H_>*Ms3λmqݟzY[~6ع[6 799|{c -O^il ^^vz]W{]^jn[i%8MǞ,Ss\q(Sr8pYfOcȃ`el3w\uh'Mc(zF4A;y9ղNiz9ޝփq$f=So47\-N|2EIq!AGjݴ| o1|䮤EYO:'޲w},lkYmo Z>R2Cs#628М)Eb>zJ666jP~)VK;kLoLRn5?iZӊhß5]eO*ROQj^{)'MZb-GO棯7IN`v&g^f%zꎣ8s9;{$=b/?I{e%7fp;.=r=17 -ͻmўǏFùp:Heɇ}z(Φ t0;_zs۹ٸ<B\enӿ4 # - -Ñ76p︽;7qN6tsB%(O3?1A@?k=.;ۦRm9n:{ǐCV4mkMJfbW& 7GҬr."ra$Cgɋu HAџU?zR.,堨; d!)e?&w[u vc( ]eV9\:i(RӐ^ٴ]%(=CrY `(~Pծϫ`$=&yu[Y\UASd!IMӻThk5OOIÁ7#}_Gwِ Un{9v6(4Ů|(iNÉUZMslQ9I3.GDyPt(@NjZ٬ZwN wv:TU漶(P l rn8fCwuqց;I9v7ܜH2}oYr:j#s~,G }f{q4ўf}y`Hv8  -V4,1(-uRCP:vN?PT޲1;4jV(seSO$?5)z_~iw\e1[vܯ'f>hIRߧ8د +>'b&|Ԍ#{qשs1?4a;xbN8A?M簓7]p=o| r.Ar8mYn6/ݧfZfce;"duA9(Hm.[,<;wDDi'r@3A@JOAafٿ3u5Aaoqhm:7u,9ոVޮk7dqTun@Љhwx:t8v8lu3Yr6ZVwqHqfYٌB:jYeY֔Ժ&CP޴nkNلV'Q}4=&z= q0'jwR=ղ1;=}17/}n+9 y ծ1\ǤiBn3ų8znAĮv}Hw]e%dvZI=rpnS5NqD&;S'4⮃mt81 h{uجv8jOq[$anK3mjZ2םMD2q0ǭgN3?X8ݦi:w\k7h-' O(A@P'_ǁN1atZ8xT,*2e0NCp4JSl։M-=폢햵&bAs0w:nh/~Pd4]>8u0md*s[)M}qnͲq5-: 'NgAP9($emk3 pm=@WM k卋 2Hk֙pl3l pNA'LN4Tx?)egCw]}85.dƹC7}ʱAfմHh:*I#g ookٜ᜝qq'ɋrǕNbfq!uG1Bh~}J:m1,9xrAC<:aOm[l:qcxBMj v:fsa_ØE6}Aaz~f] Re%ٌb-6UCQD+uܭq!{ v9)zN'n]p{D$E.k ~#UU.2^{^u(ʹf}oY܀8 He;ڻmtAp8yRp@8c0$7 J2s97s17 !u=t{-Ͳ9;ubϣ=t:(p,_'s]i3Gsi/ݺNFlVMAp)5qvmk9.8)в4sEi73Pm:ҊwԪ-ǕefČz.+hMiEP4:q(mnMqApղwIN"gm@DΦjN4Wϫ64 =HŢ" -[rϓ탊#+#aDdn~K%)o,&{m'8\մ'=,}$W=d8bSъ6dz]y4"#KfO](ڣfYglMPE}MK;r^մ; ,9qI3ոy7 =YƱݸd @ID e^G{] $gjYeݷA\MSմT,cWQ.@1n6ױ;.\~4k0 ~w1EEOfE/.&nN|;*^v3>6 e r8HMS\AJTj9)?( Ъe$춡\ 4ԓUYܠh -7ќA)břr8iSzaYS-o<]yqEEGϻ&OS7 ցLzvfTl2wZ-Ow_Ǔc}67w᠜Me՟jٹM:? ym:Ѡr䢘}isv: -B{/f -~I*JQ ̢V4?8Rˑ]m''jO9!eց;-f%M{v!$]aƛ_5}Qna~G-vؕM%|^YڛnteZ$MZt\g'?ի ǒ.,ewKQ_%U/K{zU/m=(m"fZin:NMukP)p:%*%oy𦽚v:k99uhkN߇w (F$gn4m;9?vΦ<ۮ6Agُ#}Ny$?<A@P AY\$?IBQ~in93Ugmm֑-5^1M9An@L܀eH#.*wݶl{?PjrUףT;8m?A\;=q-?B{sf]_M$="Xwq7'Yb}c.b*%Q'4rW;rG;U"[bǭi-}#.TIN{0(X-*vAɟitIM}?IZQ4Y?o_Ӑ 빣h5[{_DH{wEjiU?Y{O(n:r8jH -:ML͸)9wU@qm/Zr6,{elr8%gcn6m߫mku=eIN"UE$)=qГ=m9N6Y0rГ;.8/j??9^om(UEuzt?pҌnuz˻<koc3N?ɺDRO9ah_miνy ]P9ܦfc1ѵÙR8G/Gx2T 1. ^8UCgُ $Y_ҚT?KI9ގ*8MNS4,/,w7I$N@Fm! Uezǩ<ҠJK&]zFg?䲦}jvW>]V"14Q|(La>*<|UCٓ"/~IZvᯢIdf: qll\mGQ8\]+Bѿ,q;4I;I75 enYjZqYji2'>&c,?eY?R|lStIA@NqANm=9fYu\M-޴ñ?>?冷ie}=6THqt# =IgA^CPC5ܵ_.K:bMSLղX`nզ52]sC]CrUZ`jоD"xݒ[שV 5sTɯ (Dr*wEjmM2oJX^KR,E(,v_[ZDZSRZfժ6uŬKfKn tP2y?BZxOӇmJ=Md z!Vmq0>Q0eof >OT9 C< #.薭Bv@ d::Iž 9 q&USl)~ r $m&E`k\m=(r8+sr6%g3{HMw,e?&y_ulc_u~Jy,C9 QqkYe+gfwf[5-td9NCyCoYfv:&wz1LhHnv8hd*/X㨋~릅 Q?:p?M] -NE*Cdu\:9~jU4^OIls2ŘF9ৃ`my9MKĮ.mqz]wF/G &ۏ.N!"_hM钼1~S%%5U=1K~ EhZӗ˞S8௣A8IT+v岕=Bh7\o+[,c -:]E(-?))j\Ytz_$aN{/CUP/G>+2>%$ ~ױwZ?}HU܎6 ^:xE)e~JC4E帒G]K%NrΛmT-k-&yׁPD5QV1E7K,q1DAdvTC>i{uI`x-}_ǝ *r8i3RՓҝsRNʹA:Cp6u:tⶤ+Rær/zɞ ?r1I2wX!iUQ*%G؊Yvp.u؝ÿ0TrĖeծ~}Pk#De* 3'tR?$yRA44Рa>sﴚ&wLR?V=\դYu)n O.16?z> 樊[mK7˖݆uOYG6 !s/7?-{;mԢ0"E Ă2TFcGUn0L;ӑ?: W!쎓3u׵ܶjם># %09^M+7 v庤4/9ArPd㓊zD9~RCMclK]A"8"TzJqw Hᴚvn8(S(bu7s޻mbyFqxgR͐9AO`O~oxYpfϫy9m\ 𓽎AZV0b+{3b'(55]|ۅɣ)O'1%Qb?ǝ? zǵY]x#_6_' z4ա_ -_`7ü]J \ZrIc?wѰ^of JY.W EYncmyZŦw_hE[4b -] BQloI5?`qǝ`v˩vǰWLEj{u\krnt5_<^m9o6۲M7O<}|~78~㽍.t2r}.;2< muwyZke{c9>ue~圷e{sw=sc}m]]i^^wiwki{i{Zu\=^{ܦ[iZyZ\y:{q랮{\qZm\q]uu;se\:{Z鼧{iii[u|]>벝4mw}r^u]۴y}_}n5<5.nӸyixb2XikzC4"$dɋAV3Zb&ryVp?nET˶bG8JBf\/zVms[up_:NaѠ@1Uƌ ->Xa"Bi\M8hqs(6r8+ٛeIr\&xCTc -Vo -Q*veF(ݎILj̣) i]y𓷌PQ&^,hczey"g'Iu1I2< V -aW`S+6"e_Mo;"m)"Q:+*-JLJpܚc- -鳺Ycϓ`7mSd,JZO~rrabүjȎXTH.y)`C }QU:T pZm?K ؝bwݶ+U~u024LRZZ8TH\J(:R,h80:ϢKSwmOi%kOΦdoXD0\I14$FLy'D%/m͟zq?E8 EH(QLeuǬ&^xȯ 붝Gr8ƽWcuij&2.7JFN$~x9aiKOQOͱ~dgCv6ױl[E\w7˛$AOE! -cČ4\o6Iv`GS뾈B$R/JEL*EZIZ4"ŋ~Cɧ10cM0y} $A|QD>UmY8!Aq~Qz$AhYa~m}_ 2+>D\6RSC>]]8d6.c|X#f1~w1}~:5jn"(2qrfPE?Ϗz5$Ss]"~[B(-[@n=_Քɣ4ү(R;o;fiM|;?5cv+PEv.͙UJ?MqLŸσGĢAzkvY2;R/"$bB%?KϚy)gim_>n$gvla4MJUzΡG=Q3\܊0=f8BXõx<,iՃ=Q@{ # Ed@I^)*kGPF -_L%.`L^FJ~MIJu(.gͱu-K:?v؁P1%`!aQ#{؎YaLXK%1LQ{Rdw䦦wvf-hLz?O9i#C`TpPт SFG*bD(O;PYj9At@F%EY?&d-mIhIz}ؓ%c.j ^c}M哫xOMk9 -4i ekv2ӗgdYJU' V˲6\PHSHIs -pqME1DX#p6ɏa{] -wѯs}(NhZU-׹(=K/K*QO6x1AAaR>fEhe3LJRF&4eгAoUJ>PbZb9C_-9jYu3(S}n(_ -vP4 !n.d0CK]7$KeZ'EHhNI/IRv65-a6UB -cX岔$•rJ1}Ls۷ BT fON͗7t=*:>s8W{gikUݎcɮKq"2SeL5FV:銐?Ͱߦ6v\zyy\7yifKS$e/z%)TE-$.ŰT3'&&H*( -А1BIܖ_Y<[~/znZG亟9[ wHi@;L\*?cm@Аt*HyHALDq$Q8b#&w8DP=JV1^6E`3 A>0c' k,Vr|z;c\.'x9֢~tqz݋LkE!^{k˾|,S.тB"ಌjZN.P u<`L"pH=!)̊dO@HcEg?=NN7ſ]]ӲH2R ZYն\)QeKQͬJ/b*ʞR@_YTBOL&n7ۮfGPۊ64\LyC|&:.n)f_z-:h7ŐZVh!%Q&A{VOM5[" - fB 0,4JDhV&iʤD4*CߙYMC'_7#|޲,ӜDZptHɀZW~1&M۱}V'QoIOZ}Ԭ1Sԕ۬N2mg7MQ\wuޖ$E;}i#IzRUߡ4=OAIzNSt>IGz~G/k~QruJtuǮbA\ݧ)u*b諧UE%/[Fo+}9nT]FHŸGw.)9ӳ?Sޤos]v-^eӳ0$Hr nayͲM_CGM(ڧd6zq:.i|cp%2T'U)]b0ܦE"%$Jè=>VNѿ¥R5MGm˛' rݕ#=((eTVFvf|:bUe5 ~ڴy'uׅ|4!U y\ܗ#u){u+ǽS;j]uq,7a.81H2ӱX&jOơ̓!aU iXJ!zXV$8A4]C;bY$,P(8g ]aOIvA,j-y$abY]]n39ʼntz4.m1I:=GQ`9 ~En\il׽_%K0a4Aڟf}yz65S.zQxTc8{q-c=al,ZQûzD3*ԪORӐ'Aњ&:f=&~몖5iMIʛqY п,˒WO)T>@ -~UKvIjUj9Ls_$z老@0b^TL]{Y'Jˇ}ٍs0"g1WӞ8.^t<*mX ~\JjP01Ї]GN6~mt7n2x|c(M3$@`[fy nM6r, )7 D:ʚ' Uh ! o|j취UkRd22xڵסq%ǬY͓KtDǤ42Bǎ} -~UkbY~SL 8*~SuԈI,5%2P~j6rY~1Cl;L͓ݺV^D*Rbv>z%FBmynϤ*7'(&7?T1ZB񪺗H^]oUzXh PvS5;iCѻz(Jێ7PMC5KݓdmjCn6Mu=ږVf(STV$u|;7E$oQTlDq9 s,iWj݇CEMA/宾9Z!#e :H]0q?>Muu28 -M}pJQ>X3<2}|S^cmP*.th9dwlzISg]ES;ZVX!"$V]!Ӯ{_e[U}V񼈦]{?oCzYC=.XUC -4;r8Ia)V4z8qg3}G>U}`zn[ߗvaWJ?:%\ۺH5vH d0`&`A \P (@C CÇ*XR\Jz(ns=deT0x`8X`2` ^8B``!(A(; 1b"?3 l(|~`J$D&A`*XA@ a  Zp5(H'a Gm[6I~]cQlyx3r -4|2@ nP! -\B@! bEFKH"Cx×kE롞gyY!P +8 -P X&"`\ FF1|~k8metG]|]<A@% IрI 3\ĠARB*aXCj7k/>Zt1%8//dXAs²r*b,XIK$T.Z,_ ! b,@A0$0 IhB- jB4x dЂ4>Kɉfjy,2#8 @Px`"|a b @+H Z +pA ?(Є$6h"Ŋ{߷⇞CJ$$q4"4 M&l ^+P! N@ 1A KpB\`%,Pc -*s^3(z~*HD.P 3B1DBЄ0 k`%@/H V0%&r-i]D3v0h Z0`-h -RhЄ3! SBt@:xA rXÆ 0TİFtJ< }Ӕ`1s0p2a >hE0Ѐ0q2nP0sw&KEI@~HĂ H1x)\ -a / T`IHЅ, d@1 J`%4AZBz `(@`8BĤhN^gy\R'%~ࡂh:AҐ @7 0&: <=pP -TI a=XI3ٻKwM0F 6B4 -T,l R`0H$vر .Xb&+AtN5-$E9: -8%GG"~=n&o%-L+͝tbxBifYuRVx W 0A ^ C Jq=K6bȈB}7X_:.8AP@ `|@?(& D$0AH@ C%jAR\׉:/*=JBPdMp.~ly5eCE:hlÿ>%jQlΣ;zgfYZ5Ó\~hF4@䘱)^XU -r?zux:RYV C*k9S|(͒*#P$ 4E"=xB#VHe}rgvr)+`֙01aS.&&imޒ!eH?i@7yQ52$~Qs |(,?5lC'.R1 -0)(ކzZgY$[ mwg@E)bTb)! -(m\,/N/j*j[U䗤5;'ݮS3-@_ea\d薍doTLǐF.HxD$U4|*"ChQKC^'CҤH9RFvx9yדOM91,>aH~MIUe97IDžk2 vY[ 0B\-=2ܮ%5ů#;ު{\rȎ`>QΖe}Mk_Rs7Fnz*3 r~YʫMzYxt-4%~00L`>bP~håkd׬(pyERMI/ۺk7e˦FcRRe_Z*"=bR^L0Q%Qq -xrߖ%kaZdyZe:vߪ8=-̃RÄ]T YԮޥȫϢ::7Kܪr!ݏW9YBL=X`:G˧%nq&RgݶUVH-N$C|z(G -&8VHXBD%as,n.%\A -VHdF={9= P_c0*Zn|xӲבjFU2JvI|$_B-%J1=őrvI4s EFeOD"hKf[}XDfL0%?;Me䙁2BќDEpRW^dWĢze. VU{$qTqc1hinGt:զ+E+%O@{!UCdU$FǡFqqq -JK dGHnT!$$ē|f&MGK?5Cj=b$GVS|/  V ijinaH2eO*MoK/,M~$k,Q$ćzU)~ crѮj~iRdMr죦z!,#B%*gf]eX`ߢY!H#eF!b."ljEǀ^vq&؁d3'('Vn!-KH-7ǔįcjB,LjD-ԓ#U1KbOܲ91+R:|vv1'ѫClʂB@c'vU@;8KnC,*rϚ[$ɶgP-h⇘-"4SPw.#D -kňҊ8ݩv-@VX"~ - !%F23T]41Hh=OYfGO9 J౛Mu*҇4+\%$,DEu 6=i$)(!s6}y-#9`LlAUAnZ7H0FZ+\(!"\4EJU{=S7e3Å4,3P\0ZЋVYL"f:Ɗ+%(&/lh9(-^䤘Y},Vgwh=G*̈́RċI؈Ѣzo*fEt8)xF@>5TбBBɈRrk v4˞64)EĔ8i(Y(i6EA D#+ HXfJU4?!hHvp8 ,LDlx1c#E uIKCzϺj*VKoi>v(0hVZVUg#TV5mūL#dHOB,2da -'9=V -m܆)fG~\NJr>v^{T")dT[n+^a"U5If| bH `C  0DP3In{AǎN@qx!yZ*xXH$<>r!=zi$Z$#d =aE -]`) b#fe±rI< -i\%XǏ^0b$,ϋi '7T)^+X_<,T *.ȝK - I VLjW}nD*Jԏ1ʇm9z47S -EĂRfX;G=ſ_F4b'V4?G!pIDvf1|QH<2#.3 (WNl}cG%C -쇔UiC)bOH  -I P"?qLFS-,ZP?zq1}TD1W&AP|)$$κ yqb[`2h`VN0F\{f!J4PK,|Ȝx\@}aO)%)\*AФ@iSr /&WA Dz9yXD 1*FĨ|z%[jP8Q! -?f5rqb^9OjA YR@)޺iUAGEk#U|#K Buk~%|jS|R`X)P -P|h!BD&[rJvWDpѲ +$Mח?o/[E5BP=z`˓,r7*T"-"?%ZTJ(y1C(aV7Իu8U|uI7M}A)Z녫Ɖ(PfKKF9u'ѪD!r'o*Npqm"ϐϽ9g_yؙԣvutIb5I1-iZu#TkI=?Ϥ[]X/ZM*r[7!zZOfmS3ܟdH5a])$=ɲ}8mQZe۶i^Pa0rӐ0)q)%,U{ai!W" -(#(?Wԛē7YnzT={Lw -xHv:5/=Oմ -VX+bO$1D CpO򚴢zXU"%eUtF ]">nJZ,*I/ɯm6*X!!{~p ,\h$0 9~Aj1Gd.$.$+[Bq'@M'7ߍ]l UvML/}jӈj+ -(x~ؗG+b+c''g}s3 ǴЭ[G+Gr9Q 0q妃f-wmM/IϭʤKďR:ሽtL|=}cEٕz͸! H$3:*7HB!Nnr[٤ncg^Z!Xaz@IB?Nu^gYu뮺~o(5]:v,Q=yHe"CJ-dA5/Ʀp -)EIJQ΃EMW4Q[{nIr$]HutM.[k4mS?^q{AGE{T|B4_xN9|*|A-CE:{0Lb(q"0|f -xr֪en;2r2DUo'YF78ŽrARqvH h>DEDfELú]S]pUdT.\&AԲT=|ܹ(@z$s5Mո ӕ[ݦIu}TKH\vG0H7;̽W'+6L$;|fڻߺ#Oq\ Zx @KЅbeĆA/* yZ.ŸguoZ$r0>ĀKP0 |x`;`2 -@ @!8#edJy]$;ɯvľ2ȖsNC'RKHbb!E -սZOQۃ` RIM3=jY4YX''_ -F)?0@+I()v w/E*\hɑ> -K @4P|! LGxpKvȬ#Xmɲ^m ߓ;5aqkV &L2P Xp$A,@Xa~ -ߵ"Ww\z7պCqsȳMt%d}}_K@U(0H(P/@[A!!TY@D  0xz؛'ݒ=Q˶|:B@ D A @vP6|` -ep؀ @#,NH@6D`†XXQ,?S !bt8X`!La !` pC9P ( @ 1RzKA騖f r A >` D PB8Є1 V! -vxD4xAF"Z'jFENgkӽ2T%p!6R30BX Az| Mx(`e VVŮ]{͇@G^jp(R@@ - -Hh?P&~$ATPztL`8:0$VTLVͶ>ݒ G%_ϟ+A$P TL: 4 Bk):T78CIYt=G" -10(-1* `  D^0Q_2b -(t).2Mey u K)/n@ |`*8\(h-@(.@(,|db #I"?SdP%$& -t02ABAJ0 K 9(LBP%a&"ze[e}ޘ $rtH'(IH@X"vc>P3cv0Y4!##.A (d X(N0a,8Aɏ%^7x0@C<38G&KI}D2@% *Lźgסx(8֑Nu/Hmӗ=Seb>,MKEG(NT𭖸g!ZW}ο "َ([^&*.r(@J0%QȈ ^HBW)1ȥfG]#V#v\yhꄊ} E -J;p牛Θm(i2{ i MiS|F0 "?(ޭ(uc~* #@~l-X#0bQPNdRB(+9Pogݻe:fmKbX #)^{yxV,dMGSLAPpT#U"=kd LnSV.3;gb:-}݆z ?r_+wK>鍮'Gn8" -% -6LNvf:Dns|Ṓ=wUvd-B ęq|c*ͺ;?rQ< $7Hb= h~ eL;$*$-L-1M3# -A9mtm{j]܆o+`YOLyW^];md?04ϧjon牝y(xvy"I枞2,)]U7D9穗e~? 6OdSj-HԸiYDG%XEAmW_ܪˊJn\XIs_YOd%ByB;}뱬`Xj|=dAG]K?lm8`" Hp l}Uuw5ű}gѤŒ_W8tBۍG4M ڇ#nTN$H$u+ׅjKX5EDk3Ŷ7ǯ-8ph99pT)E),a~,;zCԶ5I(ji{P4x,aOqXqu&uhE_WO~%?f:\-Ao0/M&~?,9͒94Fz1bO_ uƑrtk}A(TLzV/QD3= Tx_n|ʒ`n\oX-?Oퟞ;IzG\Mr"繓dHMU[ZW ̵O(8Zg"DcʢDJ T0z~(Y>ya\X*|e׍,$9=Yc~ ޤ\zZ%vdx^9f#׶.Q𼦭-߮dZ}:⸷Au㐏'K6ݻ6J)" --^x>mMgK\oUUԮ* &i%㻮 EKv` WYeɎ~a&\u{4nu]u&n+M}hee0|OGQ]pgW\]YtSTu >f߽ΦL(XuE" Y<W[[n1GӾ}uU6g u4oM({L<}mSu,O7`hyo8:3?9 iqqhDHt]n{L)" -yj%u蓫'Eq jDۍS-6RPO|=^M5QG׈iSt.Z]zKQ[?]|14xb SH4Zoߓf4FV!9Vɳ$:$7BbUbO~3/P P}mԺ: Qv :XV,ϋCBb -}ص - -J:c9#x|Ҫޢjڇ]Sv&*^GϯB-HeYRn1zmAF/+$>?"Bxx4U5é&ql{@:R~D0J^=^RdT&Ɉ>#~`=jeQدGM~Yr$MAoߝqt AkID~NJ!ls`%$R({eS5u&MS4ΟMIcmyDEɯt[$宣?OS4[N(~-RdJ1D8XBXPϤ8jR&YzP '9qϢw\ ~8)'"]P\USH3TP)Q*zeqԴs(Z~F Z-{e/RLpOT?h@ @ -,0D@jr(UqlMݲLH! - ,ADq6ďBԳxr]TM(XB"N탊 -!tJFrA|z dXB؁dMI5< -<W:h Fˎ WiEE$AL 4+0d!C ,hbD {uGyhH~Ȅ11ejDžUb%Je%"G7IZNBhXNZb!H MZז_S7euzԔ(OI0ܛi(z_J+P -ˊGiD<{*K@:U/-FBJnLZ[!n,{CW9,Ssl5#A*}$]=4"ݶk[H.X&T{ѽb(#[H_1lV-󠨹٘Nq.ǭfV\n=ﳪ(.A@M𳦬V1H@QH0v]E}5shU=/_b>eЊvE G - -RPY)Xt676^ aD:Tb!,'!ّۚ. LDAi#ZDLh!Cdb=j3hD>VFhJ"]TL  - 2Xⅈ- 0.XB -$ ,` -@bIPE1T4q@$'$9PX*ɇ -X3M+ 81FĶiJy%9!;vYg*cy)"烂a'wۦ|s>-F/҉GO?G\b">V!^Ut'×T-k`(_qnhzbup,J~YVKAmPLbx$kT*4I'q|յNiub^, f0s˺Xfy2(~VI֍K5muۯMOㅢIRx=2ʶQ@  k%ue&5z9[v4ϭžv[ ,_HQd#ؘ \,]c Ԯ597 i=JT._]]F Xĸi'I}a({=zx JyH0^aE oo]u&ǵ Un M?QƞfYUM3Z(uSߖY\Bb!Qsr.IzCړiɢ_va~4iU=g z:ukWuR997@\` "ZdX& $c0:dRb\0%;XC28l$JoRgzZ֠ Zd-a|fcSDh0LBx!#"x@"jjtBI@: x247^Pp -mboߺ4WKo_Ԯ.=%mFUzR E`"wIH )"3( $MeweO!?EA8 PQ~! қ翶~U,- $߮h -ȃ2 -ͰN=RDai#P@ b뤦z^Y㲥Y[_UuT A|M}Xb9`L *rB$j鶊ɫ%h(!cFĿ G.GbU˭ .bM=$QJoܓ$=[S_7/E"# C --`jZN,SE<8AyD8&(W4z%9jV#|n D`GH0F -"$ =v`RbeDa! -Q jr<fujݷ2*դ0ղzY\7l'FÐ6kX` !BE+z?͒g 8@(D*E4>z$r[ -I]hWw-~<Ȑ@W$Y@(GC,\\N{I^?$$@/Lc%"E2RjY A~k_V=PDxxXvh ȡBgEiZ%\̄Vmnuِ8"%dwڡfVbԲ]ަ'Ae]a.! C00eUT%+&'^/X+$)?m(w#Xz[Xs , zIuc@ -o|v>Gͮ uUE 5 -XViI LH -%z( SYsV}APE^U=Zr:fniE[< -EjLK-\D,h0HB0.8$hp!,3) bG>`8qZWW JOV#)w`q&頃y)d熃v4T^1(NjWVP$`vx|jiU -@rm֊zzjx]s V+_K/ǥi-WADjvHBeǢRF IHMqfR"=8D?扟% ".'+T^MG|1S.C0⇋Ɋeԗ`Wݶ,* -0/GiLDtџZcmk"c?O1RP,#Ю:^#Gzyier)^@< )jAb<_]6?\y$w:>y1~( q^o癚eu/DT?ĘA>È0`BZ+*KjEwAOݴ3;<$B/{݂UzKfEA>vPP~ȩ+HȈ!"FTeH(ǐ壛v>vYBdEgY{ t@n8$SQ},_.G2v+;Shx`WkElE Ex`FHAb-G 8TY -PC U=ɲy nY$tbIQ,bxó͘/8@H;;м11+0O3%eY6{G/KPգv - YX䲟6Mn ԫ)*Vypr:Ğ`ǯDGBZ36v"{ݩCB"rD* )jM`#GBqHč -A 2*\(<=YR8 kOzcz]uHb}Zt~IzPe!YWd##$&0eA욒<)cj[h\~X -yY-]|jvِMytH_n[m~xp)LĪ0FV-kQ"`(azz)!*Onf7bH'?/Oűd(\RRev1ŝQSuPYc87EO2D,bB0^ zl֑NyՕԶ!Ӕ'IOI 10"5V`Hr":-(d8K$#edChZn6_H`iaBҲ$TͱGW*k1l#@PF?=edR*R AQ%jٛuxQEOzfS$*/EClf*f]P2+~)p&kϓ<(Ւˎ-\X,$WmO xIz X&ŵ<NH4 -itLПz]EsA $|Pk )h@#&ytNp ax ~U݅ٱB2$e*&%f̴L4,RKkz A -`;yҞhyfp"6ɷm2B5̎z_rQH]zn罝RJ2aŊj`6fG#zxbqeCD#VY;oպZ$TѵɔTσqVReKpq-'kHA*~[ ZX oGrlb̰`]ozaՂalB&D?haPj8ijOϼQ.+2MKΆcwh^zHJj !(g;MHʡjhiӍnkS.eIo˟H UchU_uEC | oD#Y}RX]U2xSpgo$7Eφd0(8>/im9JnH!9詜 q,#EaNA-1>bIqo1_ECcxoV q #s[_,=ceQ -S'ÖDlIȐ9[Ts>XL`z.ۊfaN!/ -ǛnkAbEUY:GO Ǐ>vuo -CTsTv&r~(RW=K,d @ϏjٖӁ3M"E]-=5( #$f ۢx߳(Tyo|FO'>kCj:Ūw/z6; W>\ SůKoC9áAO%vljKvqF.> 䇇_UcNX,ĖW|In/IU~[{Gd#jiMNi=lLGlci]7,=tع0ݴxhqyȱ6&4{Ǘ>#)s\ٔ\-rZN=o3L"~ZOnz0"ؒYCԣ894*[2r/|9AC%4ZUS&ܴG s;FJrY!+EOydُ'_{_#vUoee;9;lu]}۽dR/IxfA1O)nI GRS~LlZM鋎OnZ~)GbS&yU(}Z%-Į. (ŰkMYjE?fj[Q(EKkD~Y,rW]Yub.N墰='/r^7-Vǃg OB5b^}8'zd7isiՓ!tIEܦv~Ci`.~wmqu'J͞ c;-_=M'Kꮓ 4F0zuuO]{ pˊbuA?˪hEs=N=M.]{mUIdowRK;q">ֱ?0R"T^4Ԟ zБ\qׅD.v>˻$G꺋.z2brQOޡv:4ҼX!&EK-T"Qᐚc.u!ȓmbXDK X hauMr\8>Ge1#X1PGI2I{b%]w]H]jG d=칈%if.=)TŦ^+ng^(cNOl9$|޲$NGO#9#{ROd{L1FsCLL*D!Į-]jP2f*w]7Z6dM9^vO:uL5 2,7J^{N::u 2qjo /eJ *]z~V% vA_Vzr'\ =zO(>Nrלasg Oh]z\E/Ş7-QӡN8=){e!RB!MR,i)%q1T  )df?(Yӟm477r#h ?eh_nc0|s'] -acӚZfv:6Pdx&D CR1Uz.GPPV;܀ܟbWZOϜgqÑɰH-9e|߷jYe֠G:Uzp'a6>823)2X v]$]Gb,nulT@/A^nUq eHfJ!?~"Vuɱ,Girٗ-xw6Yf.USr\ƴ(j z3!~OSmgRE1 M"آ_wGMCIRMSV?\N;.6,M-k2 :}R(%KRK)eu܌c{یT".Ps햽\v-QY:O)ZB1K"w͋a.24%K*cfe=oDTnCNi ȇx@r6]ZWw[z"57صb5䧚[ dXt?˚$[wczPSgj=mE(`||Q(eq -R&K2Mjyu5}Q00TzXêiؓ5{Xef z' R?=qq.8gUr=8} RpAJ&%rW\jNji2!Wrle0fRSSz$ryo.(i,ofq?ijZk]znݒIʝEPԪ0[f/z$\B] oANg5X-3ծ-5꟢:)2ުe[ۦbT}=:RQv>s|,Qˢ؄]x\n~){.ŭ$KlZbS$W?06Ð2DnA8yIzN6dUƊ$bǾ9ҡ׫BIի``N"ߵ\m dMOU-9n=Õ Wժ*EGyV4l!yM#:rPZ\&Cޤ{*aAQWrW+S\27A[zZwrDwߚ$=n뻰=-kަY㎢}㸃ߧ$]2Cl!_'5crYoГ ZFcՊWrUE9n$GC$]I/G|I$zwP;mCXMˈMC -Ui4*jqmr:@A3q !#cD~ -^o#7 fv:0,O( -kۖuӬvMOŦ/Ͳ}4I5`.c(V}3>pױrn։;v2r)! D -$娚c߿Iу5BZ3bYr>= =tAu^6A>*V?ybu 0.m_=nT䶵"ZOO)q'U0{OcU-z~V1{fIEIZ`ut}Zgӕ@3 m俦ybH"Y㸛$ N=lA슚c]WS(:y>eMp%9ZQD-P#F@!#]?% w8m3_4,UuN'C,qqEP|~(@fEѪRTM;ɞz?(,?oA9ߪi*שX$eP|6Q|~mO> -W{[JൈUCrqLmKn:媥qzzTTӱdS{i4ajZ/'DUcmǭrYstMT7[ KDDQscBXLڴn#YǓb+~[3IO$P\;OǞ4AVt_r]e"<02=>izGS=ǐ@-\*Vǡ睝 r0$c Ye)z]~?L;Om׮MmIjYdMn{'EۮcW,gNOe=fx6R`/C;B*ހZ>?K<=KrUfxBdEf3{ Ϸ=o{Ψڬ"z a:nc$#)PjY%0eiwmԔ7utOu:1gSD+PK$c>stream -$3|2Kbe5*V40eA2C{7Ì yqXTgL*H`6'Ô%YS=5!mr[o1n gr]O3K.{"]Q{1%INLjo񼞚-M.Z:T^+`*<$YӐ}EяG02B&>KE6&B-")L`6T>;VʮG/K^˯#s,0ŊӈKmD.r=Io6nsp4l_gzו4gOS|qN l2 ؇U߯#,  -U1\5sm^I9J,]l7ieMAĢ&b0rZu˩6Uu?ZDXrcdBlNP-# u Irp3.RHĞ[dUY˓! IlGYm(GCg[mL%̦ab~Ve?C,T nïD64QMbO^8'G[ o7I_{v7E%RZtNjzۓ~y^J"}J4E.Km䲩MU> GŚ2V(/&,&OoanYBMRD_~WJvUp]z$,&2{4ϳ$!Ѳ5)2GHa5LQ) e7G_g #mj-a$BnÌ@!xncO!xu-ٽ6/ D-(#;I; OW!f p z)7U!J=;-X};%IϞR -nA˖UʪiiÅe Ƥׅ(=BKWޏcA O/VW-m ~Nso,\'RȄEp 5$fJnE,J!]jId0 -ˣt$'l~Ov]2 -hwsEM~eR!+"AbvIv]N/&*~ys$i/SԦ9v-;TBv`1Ro\6zb'I S]H7dPHgdN11}Dh 2Ӎ -j5?jVOH!O?,wEvt\'m 2LfZ[Kv<I¬F>dPvĬL->ݷ_WorS]o߫ :CWOWn)ڣ -ӂz*a=r?-CBbX7Mץm1ZfX5)|aa?IӯӳgˎWpjSV7:RF-ZG -,;` cdbZ?nETaV$)V#n9| fThPW/;t/ﯞ1 -ja*vCGOzf7Eo\)H$3dN$JO{~28 Ѳm,`^`xs z)² -S{M Ke<&=Or{%$"h]Kyųq -NC&|FخF :)zV(1HКʘ@5HT1`!&i-sH{N/B\^RɯZ7 -Qr,%Z'Y,%*]I&A`LaqQNz=aH>o)mհKKxv؎ya{RFD6,E:b-S -"}1ʟ˨D3L\0D\|&9.Tˎ_w|zW UD铟",z`BEZ3^+'%Q.z1;6*Jvr4KGx*H~ PSE$Jle"yZF:QH5:f\;&Pd*d%z"v\]eP,{$k) XƋO2 -XPzSȇ-9RLVG\kZ0{MQ'PZru(Ņ4 -Ƌ#lx!`lrWӫ)!?%QSFȉ9fzP0p_*`@Aذg$hL,Ѓ $VЈR7C0 !TDVF"'3XNf0U2ii'MR$WC7IOKj}1(5c5e 㓼VO֦+)1ǻMcJ2BN5DJKhq1zm~;c2bXmJ"8}'LFedr!R>&]ULV0Sa-O@> JdĥbER--_9]7U=x"*"ZFxrZF-\ӒF%z;4( j""}^@Ь|P{DIp96baeD -U Ģ*'PD].Ez2~=(YqD&^aB3hF!L A 8F;L\BXib(@;1n$ZHtԳ|t-$/F^61˿π+ɃaH '꿢*V. D"p-\U_S/<ˬo˶FzWfhLpU.GO?a2@BazUL-#(0!7`P\{ePBéf[فyyaB" !XahzXFzFJ  z "E=ɒ -e( bFHypDٕK}V˦wQҚqT7MXb"Cz].PF~a>jq[154RL <cVF.$4!Ԫm BH޲dVſQzhnuB*g VV)I{Z'cҊ6V*fˈ~nyJyV^5 -o`H<;ĬxDfDY~drх zא񒲃\HHG^V,(AJ Cpb-X]_1,]e:wzc8z1.&/IO 5W%{i?-I[G [JAHk3~ -mEWJ+JsOtæU - #@ -#h\Jگ牆]\]t&nء+Dv1tJe3c(Y⃄E#jt vCP"DD%ǩ7t5@@1Ȯ?Brbc@@coP}_}r zӧh>]`.}8'jCĀO mB9بZKժӁꮇ~im}ӎohMi@UKDOqs5*Mpk'$Wav܌a1Opɮ1& -ӤWg's5Mvq܍y0Nz9d.8'[dW4mL܄aҫ3On\1&:I@ V\8StGK9dHpRK=e0 2MB%P-;>jc!5BAe"W W&EMNztqv,)jBҋbK!#Uߑچlaʐ|*:4Xm Ygs l1wF%V3ˈ1kHAz< sj@*ʚ-n /5;%6 - %Ԥ=  D] k+}\  -$sZo_sQO{َ>p9g9XHxK!m@$atu KklBr* :LO7c}Eqеyә)> )ר5o%cɏs]mtSOLu)72&P3bPP}f|gz>8Gq67tes߀*Hւ]ͷXF8Zg l3R#uDDp{..qp`oѨ!X)M9hX t0`R23GP ` N'HaoAlkNNMghIPs FLeMw6L[0nH-Y,C,ɤ2x1#Adݤ%F98ۓh%cavB-rXegM+^*਑:$/'9IkƗ^RC!4}P}i)ka& -RvKI4r~AP/H=!?-hG78Љj'mWF'&5|`^5y 6@X eF79 (\L>?Ōôc Tf+u5۶ZI>(0Nk{8nb:#NĬe/t!BPu?uӦ,NAܜ݇]3m?QĤ=SGUmE#^7 4#k']^5vz=rwP!E RE;IeVQ3~,vRj& QShlP!Sӝ՚qJXy4+ w{yץ'ɂ03ˬQ8}0vlq%il0\taU/Ty4(_;8esC<K㻔VC|gv%2lE~̈́(.Xqz?/QaOE$A@^0sAwDV'hR -<+j,+iMS/QA([ڐoE[VR7'Sjus3<*da(X0WR: sKv7R*Л"-uNl̪|蓍'O -ď6 ,WD>@@77\3ic!mCQy9a", Ewjyޠ6(6XGv#y&u 9єوe -5/Q/a{Z;`MrxR;{ N8XR)nbStzzьI&UWѥ-Qi+im[8q>Jĩ2Mm%$ I/P+$cߕI|F߅-oa\R;kaUdOXW2iwol:K|QN&]SZc ũ(gwH?ڈvˆ"PX -3ٷޞl~25R:WL",k1cˎq$^- uTIYMe'f7'dZڀ'BC#{^+jLzZW@β21'tn ApЕsk|mlZMo#{w7]~;ϻ!uM~',bXj-wSrXȇr=0Ƚ|{(4h64DݺuG^`Z]sWۯCu- v -~G5- PD5IB\CB,g2um"05nl}@q8sxuc" r婫UZԄ$*$LT,(KOz8Bxle@ ]N=/ :kʔ hJR~kWWnWDzs~ 'Ԑ*4R.e|^I8>uюI`ܾx>?\$Kқ눏BsU%d]CkeLG6B6 (pȌB -jGҩo*X6.W)b*itjhXՉa9 \ڶ]5ۡ[iW?%.^Pf c#}$$-:H"h,H1 -a}bt á?JqE{IJ^|&/F(xp3])"˿L4޽Cq=ˉpnv czvO*4ff<_ T'}- lfT=1|Q| MƾBe(G $,.qFfM&SC% &*zf\䐖 2 -!]jƅE+SiJ]fmLd-.S" -1zYVIe%+xң+]j4IƶkB@eq6+CA v:ݿ*=60E*CM1:8 s6waWox /cy$ ~O銋7aSr8cq:Bi. Q,+2.;m(m>ls)'oj⬳v G{=@-:e9d3?XG#Lv'䁙<ջf ۘhԫRD6cRfp- ㎏Kh0|2xnw g-;:%VA -D9] _WF+ҎhHS~y^H[kxMlGj u6"{ٖz$i4"yBaId=0؛2/\E 6zl -G :ʀ?ߊ9⃠^&2x7xg Mm52.315O>yiibqS -e/.3&_X xkӓ -M딮#Ӡ*mXwYll: )-VBiN#Ƌ#= h_LUVl*\PP -#I0k2e  -A4ZDi k. -b&Bz#J%9[ <9iV,Pك] !!JV3$pC Ki%nT9XsJ8hEhY~TJ!itZFCVP$,Gk=3(8mh#9ͿTj$Y}G:PZc#jP:Ǖʠ4@ k6lѶ%D p}SyL0)}fn[xh)Hg'NIa1<Õ>xh=fHբ@S<x.1BAڊaQuƿI﯇$HPsskN+; -Z7$CEd6mʡ*\5q]kx7}kb R8ʀŤχh8,`L)0ˮ']I0D&@=hۆ*Fnzeԋ}ZQb(Ohc).x׼fCCE%+="P|id\ar9qr &8 42^P%9Uкon$g(_/z_lDlx#j!@Y7InUHLJw˅R^ qdK@ft270V˜۶i<!cdTs$L,h{Ho2q|)]ϥ):"g& Ҫb%:TcPfYBy.!_ax_$9UɑT|1#Sɻ a'&TskGM'Вfv7\ ڙ09 & 2o}`\J ;5}:$~cr9EF#Z <7i[!;ι*"3=r;^;X-.낂"4 4j9OHP5'C8R_~-Khr"A^#MEcoKuu"kE(Wլ@qvc߀4#8s`3U:G꼭11UYI,$TMiϪԒ*;4@$Ŀ5/vk -lJ|r7U/S੹_ /2$% - UZ75ah:}4jr4zԢje$NuU|\@!E^B#CG8D@. 'ϩ&&س%YȼD3Rj`вkoWaٿ<8wVf})bg\eN)\*8IJ4X1 4|7!A -]EhdeXFU'~Or4'ޕ%(QȕrgHq{(?$zMJ[YC'zrEx-@vʠm;+~_Y=*u}p5h }%HvEG0mgR]{$BÔy12l9uH+(a|1¸e5c%aj 迿SLbcÑ+7s@KOJ^ nT]Ï(T7޽׸gF[u ;7W ;Bfg?mPO(ߡ+˭CŒ,\<)>&&SaЅN6j4{vTbhmTwJ1؏k!jjAmxM8҅ 7VrHB4&!-ŏ`.DQ&0ȃEhE&AL cS9ܰ 7`S{283r!p6QN&Mw?\l71mSq#*f:؎Zta gB:Es`t鑆?\m%Z>%3'd@@H -SEK dD <@vT(  \;BS4xuRSVG9]>5_x}Y] -J$8_{x~tN OJ\8Ԏ-'_T2d54b9c5c-7e9a-4361-a16d-bc43a52d252c73a3c202-7ce5-470e-b706-e559b7f91fe5324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulence;childrenbaseFrequency(0.02attribute; ,numOctaves2result(turbstitchTilnoS,feCompositinSourceGraphiinopeinwidth100%objecthxxyyidAI__id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-20000z-5xy1ystyll-color:whsurfacespecOusConstant(Exponek0k1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.dilanbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(77spli(1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 5PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre11000116$3#h -a4b*MP aa A( @ ݭ>Е/v/>%I5ѓp6Jn4sev H7ȪuWWȪhWQE[VL_T섘o{sURfCX9:;KR;". kCOծit@o2>FzPN*VR4XFG@f+ Xted K4@7(K3 v n+ @dz3=D8A/dujL9TׇeYqE60\e3D;?R8o1u|"g*фfs#u'{V1${!$ C#j|ѧskҫ~# UT -3^2V(`'w,D2:+ 7oBhmt|$}Y_ѓZrP^0c=xVV I4 -@asAglEWbO=봇)/>:8 m>έmVQ%e- H+B76Ś, RxQY@-"QLbDJclkǩNrRO& Nv0#2B!Rb5Cv?Bf~ 8uª`Iܴ^hIZ"{~E$`4C5#btu(>d.fXrLh蔑?pBܐ@\p:F)z2Pc6(@]Y!X`b:5\؄RP1YR. d2-֡<.M}\Kp$u. #paPDGH8CgI݋s\"[XQnŊ[}lg)<3SG':fjT9f.7 GNA0KU2]ȎAݧPNm |p;Ӑ2,\$3/fe v@1؊V!jl 0WHY8q.$+UުB3C'uU2_ڀ))&mU=a`S hLPyπs@SF\G?_OmSpxO!!0) ^wDI5ݔl -n2+ЬYXˆu_4l)Kl`0C-%Y*y8 `58H -zq (?jƒaю¬7q1CM`9H0Hb -(F1[]RHXW1Qj[=.P,?ق0,I.QHUxe#(aR( i=oggM:%QA嬥o0W޴7#M#9$[!_Q#35%^xBf:eQɥ\y||TʢWg$XX]=rhQ \g$#@h no>#8(qCJ9M4JAt$/<{-}.F8`H\}:@ȥ ?`!~.<##!m/^$*xy dVzVNz$UAxy+̾NݔdْT:\U~$DpDُ|A6ǁdj{M'WwM?:st68 LP  - A ,BP -Lf*HpAń 0bBD`ƒ - 0„3B .HP8$ '@GPd(4L@ - (PhpBR PQ&] 0 $X@00@\$ Ƨ­]*1D*iʿ8 /Áq(ɽ zBƧ-!'663Q4(,:?y{AuC;Ek$7ʲ DkM,X`+h o)(jN\J($$2hh0@Zd,+*DMaxX)~R"8#qD+Q5>v'Dэ#q(l憑.kVhRϬʊYcx1ۖuFk;՜˛ pu,]R"CM@UsB0!̳'=;Ιշ/bF(Y(l H)50ɽ6W3(r(F1&(FT\aDžn1q7ędTby9twP2LIpmvy7U˼dd'sBb;.:ry\[Dґlέ#RE:bD[[ݖNlMN=G.tfezwϬg%ŮU^EolMe^6 f{lsdS8שo3UYuQbτGa+L -j-ml[%x{pMp -zZm%ORuO y~h?lϊ2K((DЀ,(,<@,h`6gGY:,I5I5SBb(іSo8?HX@F$X`@J36DrbfK{]dX qU9V9zW/I?*h Iշݦ{/|r)1ɫ庩HmZ }x^vߏ , *P`,@ 0  -w̜W HH0 8*33ih?T<|jS"ꩪSZ&ee>3ҞjW~wE˼wVk=+>Rk,,2,Pծo3PlϚhnyny{Ef1)7;1-)33S/)3dLc#ˆS<=Ns̵;w[yg\]Nn*Ҷ=hˇ\!16%5٭13sqȌĈh<#hJ؍h}I؍XHJxX,,ۺy{/Q]\m3𽧨u]n61s/jъXȄ [h HHh} Miy۹/lOwsoϬghY; #7ҕXEeYG3T[Yn"wa2##ښ2`!ڇ{kڛlX:|yMEFd -ayYn0j5wM\s#&~ϡFTh4sh$#X*fv?Jo!_ky5G5kbGfw3nA~ h%wV~Oa@p4 ' viONUcʌoX-#[a Ÿ=Jx3V4ZJ00`O A#i&=Ap&dC` [spo%NcliBUkNrgo`< +jwG" KzL9zƔg,.}Yy+Yލ4W l/(в& Jg#VRsy=}- -O Xf@fД sDgx1Nk .(QI4t"q gTM\Т<-CJ7p`%D@0owdR2kT0ʨ%IJ_nnƸIJ)_g/|3mp%Y˷/nlp$sjz/V>I^t䱃g ƶf!>|{hq3 XMPJG`&\h#$~t-f}S$(4nsj-BZgQhT2Œj{f1 +>3'4~.$(@aì;4qy {"&kUՔ H'_hJIdHo_|ixm=30S]N+&$%&NUh8/pknxx -ۼ1Kd>մ'`5Bku_?>ފI۷48B@5op QĪ_>W$2R*% q9eÜ(ar&TutH[+N# ]:ė66/:>VpqimbXI2 f# -x³?g]*nz)YJ-W ->K(+4MF<}կX*DWw&s -P[) -J4(RVzT!LJǮ%g4nX4sL.M숑8(Q&J6Ybr  -NVrk" DEԤ&P E)n.޺Rp(vy; GXk;Y5I.k[ip^,1f{4b9:vj֌gz&ń0|D է,ǦaWRy7Dz0LƄCQ~)/2-j{n8d^9 O#mOs$^64~Qڜ8(x꣤1EȶxHxJ @RJ6\䕢4~1 St|FxYaZ?*Ǡ1Q5;:ݡ/T:M%˾9)&N6̈ yi%sN'J!F6huu;,o3Һt45U./ʠ]W縤pL{02pL\,LƫձVNNE%Z3B'WS'nuE]^"~ <U6E@?ZoJW i! W< -i l|haJP^GKאIQv -^c&Mp>mDg qG kP+ۚPqPzy7f\'vӺ%wNz{G@t D -`tDij0r: -YL\w&j^\ ~(t8Yz;]G0x#^`~G5ꙿ$`"E -~cq]V Z -JDgmB+{x1"k1fzz)(s_̳|CJENUI߹(3  :pCD{-HĂ[UX%lV8%\⺙i.E{2$FƩjJJ<9*0r_ (uQ(F?6X >vџp?KvQi}QGǂ2?5o}C8l%Z8~؆{ht7\:bRV u̔]үS@ zV>{:=6#jEj 6TwU~.[v)9XGs qbX ^ WL$<=yd}@ 55{ԭ^@*#DCe!=of3QgiElr2\M7zGOQ((/ZSGU -fR.nsu:)ɢb wƦ5qu)m?/1 ҒY;2њ<{lg>|Ac -2Xï XNP%nvrT$HfPqOJ _h)"a0VWoLR } {{Ͽ@r~C -{U:s~#T#f>;5#z͊q4BüOJa .GZsK C+|2iƾ.FY$b1xWl 6EĜQr]O2SʟCtij3],jã !L4UaǼ@3c~0|i"쒆(@rGA $a3sZ -N;8}hK|ZCY͏AlEd2Y:VG8ݷYC ֭q_l@/Gmj岮v}.kRRxo[즀,STjY|ٌܧ! -m C>[^%l J]Խg<\9Ob'a,nQ$]@w_v28F,VG!00-%j#7Y5LO -֌ -,hyMKh8̙2렯8cct/4a/REd{TOA~]m^U:.WRxVIBU @뭿V y@X)#z![zn5u%FrŠ -0̗|e;WIx0}"l == elA -,ǵUK}e -F -*TtE6WP`WZ3^9N`<>W - -3[ȟQI -S˗vk ԓ$cF]k*a1"4VY%P: _A<ʚK(6Y%E_baMBk3cLKDI7f[[!^[Zwzh?Ĭ _<[M20Z&9iUu:76v0MgB{ Odil(-7K2=[St˔Y{J -<<ڣMG2C""|o;Ij.g^1+fѸVd\HɓDjZ|I.1Ѝ\TXEH -2AE2G:;k``|p3^ ת8.= f2'Ɍ̸$ܫrI$Vod_18k˞;R$+ $2!ģ?#q$L³.]ΨM2wٍ3xnJ^c)ٌmCQ22jA˴JaS<^f=7(LkkEo1*ʏ}H0(Gr ȩDsRh#Y^ga*ѤU0Zp, ;+Bi,x6;5Wu(sIƦdeuJ˱v#ɻH$$V^$+t 1x6Qd(2ޤ;/+9>BӮm^2gȀ)2 S15dnh%}'ꐹ=Ӌ~!7y LoW|jߪÏLg 7Lt*osbɛ[칓3QnH4<0f' aHA^Ms@]]F%E+OtZff[N4-z?^*n%b>5Ƙ\وYtC)]bm_U['>'6tG^$^^]$66cӸ0~pT}ĢfՂ^\F& }4^b tBpD~~k0lpޭ7@-.dC֧}tb'zUΦs1| ݳg`C1e4L)jB8 d-5s/y>;9F_Mqe_ -4\1XQ&}CYWJ[kسj{q9A!&E١B5h]H+Ա^? -))"ϒa،00(|dyÉ$h:duչjn7PrU(TGeӰZ+{`+In$55˝B]@Opcڨ~NqWnkHm8+劏cf$gMP.DϰiqA0V9H>Uv{yѿ(^\C r\|A7cSQ 0;8T#U"1(c PwZA?!Q_STG&?T;X GdT -oe#d'2'F_PsqeT;V$r> ퟢq39?THm -`Bv31^U4;lt迲BscN6[6{Lۍly9[JXV2krC6iV2Ļ@JmDz8w|(gC?)8.tk3Tre4N*xA?G+Wt|D`WzNӓze -fԆ-:e ` ѵĥy.˘rkp䕨ew򮨫un 3dC8/sSB&+T:#&_N)^mP9ze lO}Ä(TޛLJc5)WbKO( WD -W$6d|"-*lSs$s( jOPHS2K$0q\.w(;tz@a0Cd]t\1 ֊ɸm>5/\BBIXoM* [R@7ڊA$ -D%ps3YHek-'$;JDi\mąA#yrV3Ro+UH"@EQL9@2nP%vOX^ a?i5/'iTg{`R}LySGTx}#?^g2ޣ=r9 \AqIpNhN$ 0-g_*oC/Y3%d-aRte+,.t nݍWULS-@kݸ3&UUZ9;TjWWwKAI8$ڽ񳌴t.TZsX!&SB@ -םq U,k:)ꄖeghc̖]:u QPr{֗_}t ̛ٹuM\pHfj}Ȟ+"+By:}5.aII͝`Q$;OViRI¿-t;+OCMV.1WV ~@s\KWH~7L s(adh ,+y-!l>sӼJ)6:@:W肋/#1 $9_sƼR?:(heZ pITM)46}q&\zs,BeiDpՒ5'ª;#ap6p gC  X~~i8O̹Y #&3eì=2(XIznGH Y]u+ c ޣzT8C[#7[Hqq"tL( 9<+OK "-uafK\ ~DuCɬ GD7a_$XkPNT竓=su|?/Zr9>ir`Q%y-@LUzf;4SD8F#}fTۂQA4p~s^qr/ę^ M1 4+ |E~44vȵ&/"ҒY޷koO q1"CI1WqLؕ85pҚ1CM -Y̯ QUS d( 6XTBT~!8*YHҤSͻʝdA F"f5ҵXi4=6@L lQ0oϖ]ӭ>Y-"f$46itSpsL\)I|2*Ym2!m9˛¾ĝU !޻‘1w&nLO\zEp -qᨑM>cs ]Sdej"RCB̦ wґ̩&et pL3LZ _<TC2&$A7`g_ȌÐP05Hں+dggoX`7F4} Ȫxf#D؎4r偏~p:c89@d f3f3WHj Y{*pɆu^ª -Ʉ#B*T^#VQ֯&MWaf b~z &oBr;VRo>  sTxKxk#o>@/0PwocJGc7*%Ph]1 -\|]=wmENJ¶c勓r-7-H,81ydw&JgUԀy򬷐,odflYCl ,AI&l>c=IMuoK8zidP(pKdVhxTlDL7ƤIQ+_}䃛.1IN؉XC5mnk)nly[%nf[o7& QuZX)ع#k8,H%t{X/B^t;l~@p~C^e}"j72]ANLD>J0ڃt.!lȗ0\2et|JA[gsZG.jdu&/B,p\&W⼞U4od|HL! K-%=-]%i)=OBrdN APf ÑCݒ%= 'pyər"Af4 ",Ь.d.D6;UHn冫эZeE” 5blb@?Ѥ_[3e<(Gω%2 b# ~Uc)ZʶaRց y0 -shz2/k !R~[DNKJRW{#^;%R$`aLjԐY[6#ʲcOlBD F%d>4@;nWJh$L5`3Mՠd9fyTdJ ,.W!|ͭ?PJtv<‰O|~e~HD7s}XwEi q CӧƒqO³a7D2wI}x5< obS4@ T؟:,ϰPc E|rā96)甁%e\Fsc ZSjn8(t؍ɖJD~D&Ӌ& ? kCݤ'[7;dp]MVo7lt6W}(V*x(,^D$=iT{ fX%W ' e{+3G E&;Q&3 C FRT?aed%;^Ss^w! -cx0y_kRg{ sV1*E - 3 -.*5+ -eBHtG.|7rm8 }DGf;cʪIORҌhT1%EVѤf";G!գ#JxTReQBU 3w-ïQ &J[*-TSK!ҁ$=z+8% {c -ˏk߽iKL4J]7n, -2I7tSdHQ,_><˙ƅk5Ye~0># y60,tz$FEh#mk_+(q]CmT[֋+,fFku2CwK6b<צ +[S Pݒ@,Ecѿf9Ҕ@Y!G5&A5FMZ%-mLL[ loߡ_N7Zi kJ֒{6F\|!Y(hD00gBɧ/AZ&9k:\lkn2aBcq, Z! eD0={F?VT:Dt 7aÇJ -F6mLWcŭ$PwӸ5kyX)UmD|E::[lJXT:H>6ՎMO9}kuV$t)4v Иp "]7璭#^D^J8*TOȌ9VF1 d춸l{a5xb( bRZ cM+CB J8|{VΖ]|ox,b%N$;)/X, 2UKVQjK^:xcxN*f3^\RoiTt|IӊkLbbRBɶlD\Q P -2 B&!ʮ_RLIiFf8ΚFLЙ}pQY\sE%u~s$sI`HN9GT:7 XpIcr>Kf"D/馟#bzMKb,@B7${ɰ]f$Af^6*_n%e$i>[i@07 6Ht_!b6B &"`"OJ7㾄x&\nE~K q1`(w%狄Գ[%ZD{Kc֫'J[lz<O5cDuxe8 -]Yn_V:"ga5kc>婨16J~g0λǁ - N8YF>NWJx~O`snPep#Rҋ4Ȃϒ)Lo#:4f@q:_~ROHI^H M r>nTPlP=3,H}"GW}Јs&w%t`Bm/Ĉ%-m>EP)OIZ0x9OjIu2S {)w ZɋڈUp5`tH cƁ`@OJBdUb)M&Ak\F߃5^/j329cu$ CsGrrhFd|ZR4{xNc6(lRv醧 fch9j<9"nUaN~E+b1BB޶[Q4P[o.r.j(]LuG9BC'&EapE%M:JU{ͦ"o$V( |S" ˗Fak h-[LelC[h`쬩.pA K]b)~;Ƀ%M sHA&.x͜ڢG #GU#;{ʰnz -Q_NFqK8q#j63? ICZ C7_Y4"5GIC - RT%ۧ* J"MDgnGdQK'DCJz0`}1*뤄.2e-]HA aں" \iq,U$[JZ+zjcaNVeԊl&7sLeAW(F\xLjMgr~iݑB7zn[RT&cO˓0z3`2\!Bg*GY:d)/&A"EW`6G4"b*ģxipj7Z @E -UO ]%һJ"rKK_l фU!l!(e{Ɣ&caȥ^Nf G)k)bZ`),fd#ҏϑ3o`ӆ^J Wow yXWTTKdt -<.m 27z( l[Dp5EAa J2H!8ήēbW_Eղ{NF+ȐU50Ƥ) .4aI]$DXjyxC= Y 6 'K7=V2!3@E| p:y񚛡g|j@P <dGF9$6jtA07k]Fg)Q`Ch7O.#L>X5}8dɊI*J"ؘHhlV%Ȑ(|Hsp` hM|vPPC NSxiVHo(dC"&qaHUgh/ɚOeT5yG5C{E:IwMAe|-^x5h ӥƊ{N;^0yygWF46|+% ʴ;Ý$w|Gu2эqF``xx` 23^qd+F(kQrAx;F(xv IT<eQTȐ9e/i'5dX #X ST! b=RK Xǣ M?Dcca2ά6Y||W%%j8E fÚn dX~m.gl%@*pHTh\/n.[x[Yxk㦳J@a @B)OPeB͖3tdNÖ́I PbD2(^ѵq^[zg+a3yLk;/@:P_o -my(<a}'>EY%t4W{i+ hJcxtpFٝ zϪBVU3=TߙȺrZ[Neer',DO蒽Qv օd,a6|}AfP A?{)?,KO Ruq#OS IA#D؝R.#GR6F'9^zƎ*U|! OT^jY!"FF|Ŀ;DgIA}OKe\aIKcI[cDi(8}\חL&,k ]!ouYl#OȹSŒ18!3F0\1mTM|T0#㑰"k1ZrZd5U陽|,ʱubD!|9reeHƀ'ZD2ZSF4s!2L]k8ԮTV 2W9VJ ^E%Ms$3][s+,D?k<_er$ !m~P|m/N,#,0h -(R~џ[Z{+[Al,PD"QR OBDL_9c6R・%|opQ! `ԋ^Vs%%5Ĥ|wTrUE&@=w -;|6yw3='/l3MPM.Ep1.êx*v*) UtLK@V3ohC.pXC5P'#U0H0W -< 7R" p0MW]ņ:#z *.0,]5͚&Lfo (:!s(cyV+O^_max -/D9_*C|y$o 0zy:rqvQרAu -N>Kz (++| [AY?_H}XԄ6:b`bN?ˆh(%W>N[ V*VñՄf _A K̴. J.$1ojRX/+RM -`ƍ) ֖JzXPV+9t_ܡʒ~1Aj_{)+j^p@'9H-f^[T{x vEoյ-khn,O8߽H,Od/hLE9Hy+ß"RYGXR[skeRygqZU?IEe$'vN4sଈ URd鷼=rv,(O/fK#$ fr:u%/4Gi^k;|_UɻF>ra% G v.XX-v1ŏƑ=5lb.JiOpy$dÀԅM4zAus%CW1½YX?IJ;i5+(T*mOb,Հa_T]FWQ1ȹE)V"~Ц*,6۳Y&xҲS@IL,f!ޢH@\4$;&FϚ CU V]3tW,0R{?ElRT%vDJ%p`H6ƇoKՒDUи9{3VA@HhoEBvq:1O_EY-hU."X9 O⻰j'V<[+)޲@w" t׸*jDԇex |v}ռ. ؤ`⇤qoi۩lY` & D!o~CًJD:~ -- -,i Zn&?jt2P.?l-"ӹrو.K - 7MOhszy%BH,v B֟ЭvVhg'R[p6X64r"Z60dy]`6P,fF*ky$m) -ӛ&4n`5Et6X{XtUJ6Ҩ^*0TN_4Sl찌 |o:|dlH{Eyr ƼӲkMrҩYqa"Q/c1n|5t/cW2\3 Q(q(849EN/*_FYSFx,S-ǎR]& u2+`]h!&槅̰_X=Ak?z9^nnAQKf%Wͪ";ܰ_v`4 hIQNnU鵞SP5E9ϋrKFlLW+W[.(ZRyِYg^'g'xwGZ<tÉuus_<KB 6,\0ڈ -_p(n}+dV6rC+@JJw2-S ܖcAc[~LVܲF)jQz[XtAWzRs}F26\Fc&G+cumz` `O|Ji*M4,}?mQ Dd 0ݽEӍ!uї? ZÌH! zjHS@耽pʧocOU7_7bv"Dn̆ppFY\qV]1\ Ì<ΣQtEA)+:*\~ :>DX!͹Hm++..jNf :/a`  %7*r㚋X/! -Vt3L_hnby\G"[  .~_QJ -P.2E+"G0Y=- gӷ -(`AXb[_+0|L/.ZVҥ7: $=ts-=gkZ&?wu=XyqB=%J-$d ~6uv˨=Ô K/n/1= SRҒ&lú_8co'Ԁz O5g^MXR;Ch!F8Sj p"Ʊ-eaaK7b a,69cɡ_Xt]/!GC7+u5.AatgǹIˏAW -aVoFg,0ŏqwv?Dd8X!ڨ}HSw t iHWRqFA0FsB Qqw P O _PX`!1hH 8m:+O!;̬3ZJTyQ7Rn|mRTB5&,7@cI+ޒz%WE.E]WPo0Mġ | Yψ@Niӛ9EqǕǡ6' 1g -z3@\Ľ3p8 _FNw;=<2e+^, +wd *`лw|mAdDRԙCIH j *Jb}\[oKQϣs> ӋR"$g1;'1ǤGygܿ{c3?)b;+mENfIIk1ZX?;d=Lz8"|c>zOr}ǽs1xg{}xGLv{&{}]~ĜswE}Rȱ8k{ֻ;7Ix7xُu[ts85;#??|丏<3ߤ:{&Ǿ?]"~g5טIۏ$ɾsXG;\Iwȧüsy89UuuqoR㭵Zԛ{;ǺqI2}ߞęb;b*0udcoN;}#1Y#{$1HZkYu箱#wyqx>ry{><:,v?ɑIyd{Nw7{E<;;01]k.Nѓ{=^gs|>c⸵_'$)r5YI>c'uT~H=Hȧ$)rL}o֙5E=~Nb>9'yc3&1<'t}:LF>1ޛ{>'3y90Yuȧ9b*pGGFoj`Pͬ^(>b:Պ;S -D)z.,rCҒNj!81yEO?׹{}9UBUJ;}ƣ$#qg'wËRT]1XHf1?E?Z=q̿hC-(4J[i)m}ζvB][BUR+bi+-eWvaN -Zڕԙܛۢ{N6Kszz[4@ksn1kWZfɶS][KǮo-aAKU [e)# 0_cz;~akSh*Sjk\hWtkUBbP pAݓW U+ [(F1;BaKH=b݂MO1w:up!U}Ko{y۫R\[R[]-}tW@J;A:EUom)$ֺkVp)s8p;Vp ֫v[I^2YڳzPuӶP:u1w밂[G-tλ>0ww=UL]:흻Pp u]M--uZ9^iҢD1]ةjO9djbbzuv;+[8^Jėz-jC]dBǎ9u({UuxĞ]b[|{gƾ9}Խs֝ḇ羵曓wsy{\ssL,Ι:oMo9I=Ɏ̚Ew'9>&G1Lwb<]$=ֹNv{ғ{zu?:kușwlIף'Iwc3^̢s8y{λ8=E2j҇yߙ$I~ŏ?G1gqCroN{#w} ƻg~G(;$w{ֽwCL{0ԝoEs9ǐqHrw5OfwvY:9kwe/~<]ƽܻuﴱs.qwf㞣]gcΙ\c9z'qna3CLrnߍw}GNk9wdu]I7CwCEL?kjn"Iv$-w.ϙ5?G#E?gf;#a|?űv.Ns޻n$u'9]=.c?9Cy8k}9pga؍8hqw?|n>>C#ɰ> ;w U@@:j Xe3Fb+b@[Øqax!2@cQ->Nb*E[)ZfhZlH"t,\h%(t*㊪𰜗u(IQZB\Q<<*&*HP|d2{Wn V@xB_;DdI(P90\D"o1e!:CVf44&Dm :(A|NY@@ -#XBD^/AsOJ|l3S7[D:O6e W@ _A~ -}\>1󲇛0;:؁8"yCm=~!ekl1)6Vy~H@A918$!FAI>. R 54XXV0`2Q< .i !bH M 0=i܈nW;4RtaI8phK?%mF[0` muJ z4*PP)ȉW=j#TWx -`SLD۪DY(= E48^8',1I%S -𩰆xn-y1zՃi0b*< X+P-M^::IU},.Un('6%/F#DL@ucR._,{_ԬM%ʃS[^3s a<$I|.CIM}hb+b!^0`@%]&cVA C".Yil1QqpRAH^$ -i`UdTGIiTMX! B:<s=  ;-ط$`ǡu1Pͨ\0k3QD)7M~@fbhݛ&l[2]yV"\“EM%!IarSyjxA/C*x22(X u7$HCE7sWc}\-m)3o7 -aѹ($ Ol -gacNF^V\eN $gf8`AeKʔ!Ṕ#4AD'1$Vpո4Jqٗ YHT@K`!*zE (0q[A&`*'։b -%/]Nf7XЍO$7ֆZq9!*шqci@`)CpUgAef#FN"\i|Gб [2d8K!uLJ6 7L h -J+r`3v@{ ?LA`A85C@;J͸IWC\,NF@0 q+N'bZ,pk/ -#/Za<[D8p6~Cftbb/m($Zl1E4ά䳊pʬʐ+/j/*% -,!#kmkYke.AsO01sYR= }"( -AtHV`'ۆVrHU [H<}\/(ăKK[H]#%n\ۣ2 =(Sm[xaEPQ#.qv>j$& ;Y -A+Є!ڏ18@XiFPbtq'&}qhl\E-l gZ}xaX':43m=O8X>NP` `SP3Z -K@7HcB”)P S&PxC?NŨO-J3?v@SRH 30T4Mn< -. ^6+p?.@ah }qt?)" :ďÐ D2­m?* -VwDͻ0w`ԇ8hOҶBj p 6hW.Ң0K}!;3@%6I)w0d0R}oI0@ ?a` VK Y.qQ&"# -ep <GK5h>N40˰uHI2hj%?j#L F' ӠyR$/P&[e!$wΨ(Ҷ,+ ^DgƄ,-2- 5Qx+SB".Mȡ1?}r1`EMF'gH58*0]+~8_E5EL ]ҐL:A(|h:fbq{fd[&X4mqVGeJ 3IРШt?n0^F>AE%mQ,$ <bcBB+K$cB 5u3K/A A_`2bf{}ɡ0;3 qdQ($`r \a匐 YY*I! px2 h$G%Ƚ|Rϫvv3KP:I]ʦM%ѥPxt:o(2$[`(qҢ¹Iz0>+*XCkVlpW5ZAN\j Rq0F+ Lh%MURE@=w)"Ydch`A)aKx@qEOvP4H[Y(bwlO`3M -\6͆ V""cG(ګŮ+!sY]->Fh[" HH%dL&9ak&mLbذ.:1~zB򃯚VOit2h=@CAɶ - -,\EA:xv2gq i@=` `:XV\YLQ!Uƫ.%Mq u("pAPRAAG 4NAd@썙B$ 1&E"92u8'$q(O9adhTX13F -$iQbvAHK!K 2) Y RId$d%Q|\E"U;*Ei؟2qdB y I ZP)a(A)[~ * ZHv2rwPKv"+IA)qDi9H$8c`1A܄dLYq)}2tH -W<Ux4F482"YB:&$d &tAʁWj4c* GJ~ھLda^ {^iBmyVd%G5y -?a8"843Sd3rB{`x\q8 D8hq8*1Iؓi9/'nnV,v_B_:#2Tzu`vzYK &"ZSRۧQ"M-fneSseR$;?Σ|y~jQ ,16^Ɯ]gD6GO`iGqnx:6PkUԜ:xĔ?^T@n$O!0l JH ?/ gZ!LZe#[dj\WbK`  F7*qTxAq$[8VI% 3 O ơUcqL %(XK0 Qq{?! _<2%/ Ԡ~ S+Y5 -t`vS83))[Relr࣑*ulnaMz] hKBKDЄe+`h;RgP -.UA.+BTӅg,q=NzS> rjxYqpbQ"wI[fx6FF" *;2r?Z(ׁG,FbP7౏U b^8@lѠLdTafFx1b 4ȅT/5s U8KGa,:LMǏ`jrp3K^p+QbA=qh+BW>m:%0bZ!A&MC. l0ܧkKpH\cK0GBW|\1%(֨$A7&d<9h8e^ [%qdSz$ ݘgQ - RFN/@& w, a7P t" >K^ X8Ih@P9BÙʁIu!Ύ35hװ -+R*c/ҁH"A^CN SI]&}8Z-1A* +% LI|\ >PK41FA!M@C xz,x#=[Boۗ4nǁ!mv( +[F ~ \y*I5QCBJyI>VSHU%>f` JC([&YJ/iF {UblB7A uxr>ipVI,hqjYë)9@#sv] B_QPlO4g8!˚bkB]*$\NV?SpU,L%*-+E3" m" nYS$D*u@ g6  f+Ȕ-kͮP WbP (V (24M)K7>4lNT$!U;IF!W;lgxI_Cqyc#;?%C+<7Eo^B_Cl&h4I8[f ;JqZcu -p [ EFN$D8ߌukHBh -K` - O sΜ-ci 00w,#5a:B@d4xqL{|L`gCK!;DTqX SL b5H!-RZ3 Fv @T$2 -k$SS#hGQ0ʋ& M^}JPB[A*U8Y0R-r -[ -.KŴ\avB0̰%`X;D+jEeN+D4Q'$ُd'FIEdwklmG8:YfJpSqkj`6ib&6Vb)6VBڗKcqƪ\-"DBԚMU` `}k?N;"[4t`T4VQ2?OL`Ub!뺋Fw &q0d6)+޶g ­U-VԌ$ ht?.a@@%ʀֈJ,%j8gS9h/똔P}kz |( G4qؼO.0-qxr*gHOHCh^UE2{pDV)[VVULxa -Z=!럐 "zFO@3[%vt_D XL+̀e%&x4a&s ։R3Pٶ --=]U83ظfwfP3c k^Jd*_4aVmeVF4?RUC4ahPU*ز2eeJpԲl:,dXXȰa*R™Ͱa`!0]eP*UpoM[7ʰL :qg.8sWTSn-Wz,wX,CĶږi;x^ kN/!~|v%w% ! t$4h4 2عs"* :k C. ?M -ʛك{-zҚ-vpEl)+ev#,Q<;7s'.)$]Т8.N*/ӁR2оCOջ8 qZb;&af}kEK4'p ڠ0˥EK\/3:luQ3kh͉9-f)Q˕1,m-{tOg@)?esXJP>c؛5]7Ȼ#]B -D U<+1ޕP<~R""MRsA\(wn`>;x yE<倚OyYF)/o-uC-[`_BsJ $g f[W yurJ|%rpոK25~Կ3궛潺d #YDpHa2#eɊcW k3KqLgW8?מKdaF\_`HR"X:EGItM%8պ]! ?9_ VMhJa8&(k^)JŖFd-"Cq괵6$NۤDi WP8{C2Pa[F.\q&tIoR0 O,= 3#DNN1-Z m5ёAI)vu '8QFn aW-5O)q#`Num6B$l]I|gMF@!*&P,UxRaPzr@?hyَ]mNiO7aq n10묧>O -rzs\&L={HIЧNZC=/Y;Z5ùHZ~ߡ}WpƎ3Gt lD -]BqiMZN6Ќ Q8Ml,5ƚ*|,?i`Rak% X/*G D - -gJ-U{Ac>#eŁ`Z2@IwzhݙrskIu_>W&(Rk^ik(T x jTȚ UBXrqV@ҟWxs#tZ -)Rmi↙>X74":v4NdfZ&IB#^uQr|-[sBwndRYۚzL,!|e8`aP:7]?R^'[Ðz}'LLMР,p3pGwnon.VScR/jD{4n5)`&5H՛Ulj jfQ  )Hg!D$Ao HgܕdeÉS \J2`t-/$8_ÕZ6mHr%Z+`*; _Fʩ~]_gAq\'c*t0'@?mrJ:tj@ lf,L1ODg`dc#Uʼk(zE:Ny_" Q?uKb{y*yhԶl$Y]M+Kf+NJ8ތU/{~!N8i0C+/S>:OZ5m.VHfSbF|g;7~@P<)_wATЬ.,M E`0&E{,; er=tPmU2WoXA|#uzMbow|j3MDcH s,jM19#$C  |,wZ&qvTQĕCx=Ò2r ޜlj00{74xZ+*.yI @*ݥr^ngpERmZ# Ikbv룭h"+Ñ-p70GK3R&YKr{ĠDxX/5gWyYBtzz`1XPO0c9Ω S=ed^+laJɋz{,.G~л?Vl8 FG>FC~ϟܾp6 -@)s$:L֏]ZKe/yV˔32jo/ޕ4qwΑk38%\ң̟|$L LGkW9ʜu -Ea)Yf&B/3˚whsKu"6i)@1 ђlʫwmp-zASЫ-7S[.nd|uvi> -~HzĊrsU +s=4sq720~WQ{6S(82V\͊| ՟ZDrx(* zj4璅:=>>l}Vh]*PѯFet;.1=pBUb$ -q, -7G%@~t]>(=szc iG}/Ģ[acd/w 7D`z1eIFBF\Eqa>:bx1}gbC{.7k13V^i_|\akFN1=qf4W\x~E4}@P:j5yblM<c dr{TQs3|PRJjU5eSSr!QޔMʐ -:Ԡ 7a"]l>~xkFOFB>{-یؤqq=+C3eKgy+jU@Zg\{=nqL7Yҝx rq.cwy5*ݧg],m~kRLPrXOl>bg^1]XC@ݲ俛隒st p+3e:|78P -IT42DkCH-22K16JJ5 ,rd`yA:⡢Đ .#(e>\u\2yIHMR+! -dAg*6c*4,MDA0:kSLrns`lw$~FWBx3m2 FiN]NQ+ȣyI;wj>^\Ɩٔu*ԥv1?ƠOdx#j5rҍۛmq#?u*FLiapd!))r+{cT! ]C2/4#ezP:SMᾆ4<3D 75 ۼ+/cՀ"7 93s"'CFBqa#('?H.6GP*;y5f._315_p >3ΏBU}rHN 2p]VJʜtˀ(%c473-s췌OLDQKy[vT<.}A$3݅5:\7(:m ȕTW*}A"Lc{Ku][֖M32~j>YJXkrw@9^WkLe||I1v2ƹgfN!*}!zumQm;@Acs@6wd;^&AO#Z3mc|BČ׭K>}/_SKU5Ε 56!߾;/Ik.Z6nmкnRCIN -}:SC? ~;FV ċ (*=QVL {^t׮ԬAIȢX;ըQ$1$[l hU.%' -i}5R- -sQ+)TkVhXyJb} j[]5eL|ss%R%u~*~K!Z̵ bI2䊁yb'X<q1xZn }eZDqg.΂cW~dE!󏬇BX"1CM6owfbLU{1_aBK[@c;5od2]3q{hn Q ?$strdAie{F=J -s \A~^[?j2 -&n'TClgDp דMK*. 7˽N.2xHk*.L#Z$ -L1n45EF]MM&0' A9%uԒ-?\F.Yc2=Y?R'iS%` _$ѷjI0;(uOZ4jh ?-' Ww1ﲤ9jDHPOsQLOD~Yc>`蓤pu<@M,Go[bQC(eXb)Sr⯞wYulBț۸<"s^Ib @}?x:&`&yO_T]fߞ|OvE0 -A87/R0!Wja1lQ;LE_&c Q( hm^K-ɻ)lܖ}`9,{ C(ҳBZ9 ϛQ +fy 蔉'2/X±9DB#jeGz14. ~Z22'p-VB^w/d ؟TXR{\߯` -W_&VҰdg - SIDF`aI]zGn:YKNrN(Y CC !|C@ &+'cXnod|Jku /&2"i6δYڲs]3:ţ<'vK{/S@fUMǿo(/mOdU10k m~$`fOf)ɰmr񁬸F71Vj' pFNځ2m*Nȥ~1u_%)4 0>ҵa9x"|fGzl,,⪾V/e[`F/)>$[\;7 -jFJIX>x[-R4ꭖ&5բ`ꡛPralԓ4^X ζލO :?|-Ux}4XqEvTu -@<ؠS8*J4W7{鋴~:<+1~#Un( 1((<2Ç9>O>-uh3to3Ck PCff#Ÿ[:D TO+`8?YH6hɔ-б1HGa؀bwSImEKw:C`pKLDwTn]'!A6/3H{L$ ;8";pb $64{P̿i;a #&s؂]w<K*SEd5֫anUoBj =GEUG%:_(ījyfGԃHt4q9=8I-@iEE; q>4'N7RRv-˚J=ĩ9;g8&E*@~|z*]S*nh`;|/94_MI`xU#3yOM{+@ -+rt0-MMm6p kaVH o/H")>3dqv" u{;))Fg9[NM -Zkj}aL & -1r2Rs_ƣ>"!=Ds}8Ʊ:e[Tr<[@"Z+B({{֛?YlM'ԫܕE /P.\Q|=9uUP~L(K伹W ;CqW.O6tT>|_F$LM;H[ADܣ]ܲ{q5!ڸR -p+в4E&'JP#9?shZ@Jl͜؋EI_2MV7/ZA.@C~JC_II455N蕦ƍxEkz1aYaZASe9_;ߦY$k \\ÊW> X I]gEz>U ;{iщL__lvNiAsDLk\Z4`ͪ*ǫ -KSV`aCu(ۼ@1 !%@m(.3P(V%fPZIt_jű :6C,1LP%ntjX[PžbYrP%q uҸv,9b4u| endstream endobj 22 0 obj <>stream -9L$cȆXV;qpN0.="rœI/kQ8K'wa _ $ZfUHJpZ91yhll=7kOiAB ,K {m|4s[ۊM06KOnzICٜ<d= 4] 2^_p3 $ թ-Z=~. -nņ7gT+:. TVhwt:yFZ.[>UTA1y¨%mMGK!*P^5&AhP)$hRYB/v+|2'W;D'_YTY`%pSzwMmFĭ p(]^Yۼj@`\4k0.b /k8qAUx(Su; ^bǻ(~Si9|@aV]C!‹ (­/s#[|;Lrע#~uLqZsu^U(Mkz5Z&m?rJH!yNPmT.:dj Am+'a|P(|4ՐJZM@0i@$\q)GYcbXRž*ənHB_&¾F{*T4^G,3.ZBg\zС0 4Y<\4Bi‘yU?#+bf,EtN:9P6C!)sIQhWR'!a;;3M   -_1HŇh7L3GvAD #;'V`DX+" -qlgXAHy "rk=8 xaC$ -~=dKP{v+3{:Q(-u8@N3Nrq3F]WSP;0՜y?X^C)kD($[ M~DkE, -hVY1"?5 MEIM]S#BD23nAM%t8utcAchO)'{YtP2cˆv TXd ,K[P4LX)G9! 8܇1HKԉH><@>``ZyiFi1[]XxR{/h&g$ Nlsv"} b%ghP0O1Vtϐ=c?g -^0FB,tbc#B6,L.cXZ m'D7w޶QZZu %$i EpSLA %.ϲ3^t0]$kEBGSm,y4*!-"D$&KwjmE~[$BA phSnM_LuࣥAQxopg\Q9\h=h3l[!uHm}Qu5\G4sZEa-6-h݈zt6{X-C',#yd:j'  -&0sb 𺃆}tD8\JÙr5鼰 ZPAb -kfCq+ha5ճ"풓BKl"I3@> |lf^FvKO辶{:X sbp:4\{aUjJӟZOף{䞒tQaT/&EhC D6ֶ߱D\R#P޾ҿI?XO{i^v%bcPhoAi)XaeO1<}ѷDX}hI͈)7D9}8T$6x;gr ga(w4xn=_( S ?M6XO=׊x?!={]+s7D9~ - _"7Q>8Y 28$I6ǻm1Sn@aM uE_ dgʻv,1T6GWQOJgaV1 ̆q} ,Yk,"xb(Qgeht;ЋX/4* =:|G:p}iao oZ ,s|EAe>3&3G8M谽TtPH$zH\lghp ƀDjӠ r]wJ< 3 >bs|d^{HtScVHJ=ʈƆ5SB:–|(tdp 07!#7?-o?y -si@ZVjYtn3Fgdb ymO{XKfK*Nz3ތhT͞tC -בE} qC`ց~Ra !ee2Qi&Ԛ!CquT6JFld94 .)X#;gEߦ>s]92]% yG:;A`+0z䈧X`-q"-qE.`I OFk%)I4m3eˍP\ӜYxO}$`#?]" X@ TУ mND-Sf6!xp3P}(nt&6TD'6L\g]VfX|ux*K&hc g@.(M$d{G4k"C Y<.fldkHHcoQdͤMqr&z!b1{ @B\֞KVa Z[n,pWhg\,媥,,hk@,nnјYֱe5x4#צ>J(9G5|1fqw-.}]_< 60dwl]Pۣ""ht(M>Sl,MsdIvu~vQyO`(;lDIb)-{G.M;pd"B__(ܗ0&HUGiNe2gX5ܖ?$!$I3m-L.XG޸Tp)г))e&?W j*$C!Gɲ4p>ꫵ-{ /‚@S;ы <b 8LrӀ\(ۦf-Сǣ)$BD1X?!($c`FZc9>ƀhleܔwA j%APӯ,5c$tvi>H/?i`T33ZUy$Q#W""8f-ݡE'كLIg}8mU%6#R B~n+ih=a*ùR1DmmDb*IxJcypzM7uNȟA  n,2wLq kMUZMDBZcZ+fȏː?!X@#{\H [FXf< HO[p:B_;rǧƭH*ӁKu9T8xY3F&Dr HѾS6DeA1*gdĊi-G(:hi<0yfqK?E?l]+8[A Exŷ`8v2J8AgSxeNjv/>2r1Ñ@p| 5s=Tt#H9{]90j~}bPorbDx@`$it|K) 4Qޤr|{6)dQL!~o6k2c:6rO&)Qޏn0cjXxdLX>?jBJtȎHmJAO-L6.a&Q()${j7 ܢ~۲ r{v9 pK(]]و<:RFSQ){xD&r|$׳\DZ כ5uˁi@la8a$p Kf !5 q#riѽ_7K|Q,Ŷhv6ʏB#и哶3y%i&ǃw^\{f ꈻzEhn|೼t;#EH"p~7UI#qY̮b]ݳGQi5:7˯/1d{P&TTN<(R_zjs^MyNr/sq CYH1F4FOFة&1jg]em?q).3SE<&QaTGY"8 ch}F +FXgmN'QqŢn@iU]i.oYYJZUuf܌"Jn[ "JePXMeډ)6h6ę4y3}Xn%TFϼ ώչ1IN)o4vhxq ; j;!>;0ƜOFZt#m}ty=M_F ߞ_ĻoWi;Ñ?+&Dowd  -ODWր#(Ur7!W^U}:0!Y\OrmY|8/AB0JZ(1|P*5˨Hy|!QeG0FN? [%bF:k3Q. *9`ւbfJP: 1sh2> --%:D -Ŀkl -žTG9},ϥBp&2Z ?B]h4DGff1Av U9qF`-#Փl,`pGՈ v!jϤ2%2 X'A"@7d:T]A݃+ 8. Nv0X<$(؄,h. -ۙt&>R -eFp`a.q -=* !h_a -۲-2e[S.ڢüp}P҉Kx -ʔRAHL+RUIk*(2$JH}ZhKY?08f` ɋ9?0쇄-cz:Ty}x\>LD-.QXbL+$41l}`*ݼ(LU,mCIR -X#-㸶 -wdPs0tŪ$pc@,[ļ( phӋ1@'@Eń& y@JѷѬь[1Agaǵ ֶF_8q P8 :<jS1Hq -4$NH3tKr\j;2 > 4e7u - F@r ZTG"a3d5r16,X@KD`AP>%aTYz\lJ+cIУԩ`$TcdbuqȕLȃcNoYHЙҙ *m84.Ed04"Z - -2؝VtFsfޯ9[klv|*Sꝥ(:yV\v鑟Sqz3i-cmsΞLk]ٓWs?KyRv/םJZ>ו{|i/tv&hw=:zs_r;OI?Zk1R*kf *T>Z(+W/ Z(\HlJ#Vʣ)meZkT$m{᪥r@ -QT8PӖi#jw8}*+׏\}zӖb! 3$|*'D1NF%$E ھڳV\mTΉ9M0Wy}k0}kx xrx数-֡4T\[ GagٶmVW0mz`PC[i^J[idŁ -!NyRGt)߿=:WGe7Ԭܖ9/Ԍ/.I)˝&gY嬞sgӥu~{vRr=e,=ʸ[=H+kR~ݑF2wVH뿬UsOk]5:YjiSS'+O*cf?du'ӧ^W>ZGQ9rg:]G=riFܥ4ܗw:+5O:J{gon5FJs>}Mמ;_ڻUz9Gqv;'Ok  08S jA>b1c 3ȹ.K`!gS2ݣ,49>:Ga Q~vI=V5WOyAF 2ò* d}!jOB,ɰGR{V֎B6|'{B<-}Yh鐭dC(%$0B/"zKgӚYu"'‹<z !>V∯ujL -116u -଍+چa#Y v$' -MRZVEa+qNp`[~GP>jưKw!->C$ -\-R6Qus3waH: ;| J#R{[0 4|5k~EP6i΅TCH, -,&[`lL hAc- =<{2n_-Vh>=p2[c)x|daWIL"ڃ.d͑y Y;4QWSea:u&+MQiN#;)ZQN8OVW%mVis);2 f*0&UM,afr?n2v4RM˖ZVSd~L F iLbd4ӣ1wˋg~VjLHjxN(qլT*4)&K=gP -' ӐhF'I#N-'͋lY1;L LWl|8)n6GP}~#bJ)W[-=z5̈́d.L'"Cq\y3m\ -srBb8SC8jdk =3y.eh:ZS. W`bl)TYbQC;OixpN$%h\E)ahb֖!73mts.{/cp"LI 3D4ϑㄋq HiF09iӏ+X3=z>2rՃxgh\=HW˰PP -1|TEâ4 -L& |0sw OF:18Œ?KۚnhZX~fAh^Vĸ=CZ[eLT1##\ - lk@UTLbsB9Ɯ( -]6jqc1uh1:؃֏pQpu5=dҋ[r/(AG YlBB(rj2bv\'L >tV =ö2M\2E =dW,aje%ju`U5{]ڶԪ 9b躁~m HF!dtVLbP2]ik. oԽxUȮ8_-.|Іr)$s}-qߞ%]^O:操:2ǝ2F5H^! "H{_Cr8EO4 -.O-BD~@SPeds*R|S˜prMn| ݛR=u_!y,ptە qt 2-tۨ^!Aq^ zi"rǿmdk;BqJdfqԙU8>HؙU^y=џALv\ZK5o{#{\?psnJc=\/qL ;.9{V7)t׮1OxfQo3ÞxoHZyw\mN#;޶Ƿɫio;3@M{L8T؎'GгI8|R)dk=ޘ!;ZwR=}*-Svې98@?I%]91f(6k+?ë{_2iWl$xՖ ^$^P"T`3—^֮"^f]^X+KW9(j_ ]}n/U2HβQ eoǦ 2z*䲲@pO82&xu‚wLDM5i21Ћ<<CH8yrq=gzoI_3ÎOp> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000044363 00000 n -0000000000 00000 f -0000044414 00000 n -0000000000 00000 f -0000050155 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000050228 00000 n -0000050468 00000 n -0000051622 00000 n -0000117210 00000 n -0000182798 00000 n -0000248386 00000 n -0000313974 00000 n -0000000000 00000 f -0000049855 00000 n -0000327518 00000 n -0000044828 00000 n -0000046814 00000 n -0000050042 00000 n -0000046671 00000 n -0000045612 00000 n -0000046110 00000 n -0000046158 00000 n -0000046849 00000 n -0000047207 00000 n -0000046962 00000 n -0000047087 00000 n -0000049926 00000 n -0000049957 00000 n -0000327543 00000 n -trailer <]>> startxref 327736 %%EOF \ No newline at end of file diff --git a/misc/branding/conreq_square.png b/misc/branding/conreq_square.png deleted file mode 100644 index 91a422e8..00000000 Binary files a/misc/branding/conreq_square.png and /dev/null differ diff --git a/misc/branding/icon.ai b/misc/branding/icon.ai new file mode 100644 index 00000000..7de41f18 --- /dev/null +++ b/misc/branding/icon.ai @@ -0,0 +1,778 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + conreq_icon + + + 2022-01-12T02:00:14-08:00 + 2022-01-12T02:00:14-08:00 + 2022-01-12T02:00:14-07:00 + Adobe Illustrator CC 23.0 (Windows) + + + + 256 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A8y4tDsVdirsVdirsVdir sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdiraqzGigknoBucVtzKymjAgjqDtirWKuxV2KuxV2KuxV2K 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 irsVdirsVdirsVdirsVdir//2Q== + + + + uuid:9d11e7b4-db71-4812-8be0-126cedbc01ea + xmp.did:8359a53a-d8aa-ee49-8402-e0c80ad93cef + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:a186b772-fa4d-6f44-a6c3-821cd14b9728 + xmp.did:92a05db4-1ea6-407a-afb7-538f80719779 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:92a05db4-1ea6-407a-afb7-538f80719779 + 2021-03-18T19:52:57-07:00 + Adobe Illustrator 24.3 (Macintosh) + / + + + saved + xmp.iid:8359a53a-d8aa-ee49-8402-e0c80ad93cef + 2022-01-12T02:00:10-08:00 + Adobe Illustrator CC 23.0 (Windows) + / + + + + Document + Print + AIRobin + False + False + 1 + + 300.000000 + 300.000000 + Points + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 12 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 8 0 obj <>stream +HDPn1 $Y5N)-S7\!)R:0`îehcmw, +˅\I w+}7P/5Эx"]d>stream +8;YQT0c#9n#Xb$Her+bR]`5tC[C$X'da@V&F9qo#[(@%*e)!L@/k`Tmba[Nh-VEt% +9f.6lhJf>;:OQ_ESlg`uI'Su[F-a`Cku7$j4VYEN2RTR>*e)-l2&_g^EI9NMS&J5j +a*U=!_S*jO?TS*:YW +endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 5 0 obj <> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 11 0 obj <> endobj 10 0 obj [/ICCBased 17 0 R] endobj 17 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 9 0 obj <> endobj 18 0 obj <> endobj 19 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 17.0 +%%AI8_CreatorVersion: 23.0.1 +%%For: (Mark B) () +%%Title: (conreq_square.ai) +%%CreationDate: 1/12/2022 2:00 AM +%%Canvassize: 16383 +%%BoundingBox: 0 0 300 300 +%%HiResBoundingBox: 0 0 300 300 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 13.0 +%AI12_BuildNumber: 540 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 0 0 300 300 +%AI3_TemplateBox: 149.5 150.5 149.5 150.5 +%AI3_TileBox: -144.240000724792 -234.239990234375 444.239990234375 534.240000724793 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -11967.1998909656 5257.31658534974 0.126106944444444 3064 1274 18 0 0 78 121 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-156 -246 +%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 20 0 obj <>stream +%%BoundingBox: 0 0 300 300 +%%HiResBoundingBox: 0 0 300 300 +%AI7_Thumbnail: 128 128 8 +%%BeginData: 29731 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C4527F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805FD81F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F80405F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805FD81F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805FD81F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827FD04F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F80405F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F804F805F804F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805FD3EF805F805F805FD3EF827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F827052E0B2E0CFD04343534342E +%342E2E052D0405F805F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80404050B340C3412351234 +%0C340C340C340C340C3434340C340C2E0505F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F804F805052D0C3534 +%35343534340C3534340C3534340C3534340C353434343534350C340505F8 +%04F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805FD2EF8050B3412340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C2E0404FD2CF8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F8270534343534343435343434353434343534 +%34343534343435343434353434343534343435343534350505F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804FD05F80B0C3512340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340BFD04 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F80405F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F804053434340C3534340C +%3534340C3534340C3534340C3534340C3534340C3534340C3534340C3534 +%340C353427F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805FD26F8050B340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C2EFD2EF827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F804F82E34353435343434353434343534 +%343435343434353434343534343435343434353434343534343435343434 +%3505F8F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804FD05F82E12340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340B05F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F8F8043434 +%340C3534340C3534340C3534340C3534340C3534340C3534340C3534340C +%3534340C3534340C3534340C35342DF805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05FD21F805340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C34FD30F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F82705353435 +%343434353434343534343435343434353434343534343435343434353434 +%34353434343534343435343434350BF8F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F805350C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C05F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F80405F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F8050B35123534340C3534340C3534340C3534340C3534 +%340C3534340C3534340C3534340C3534340C3534340C3534340C35342EF8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805FD1DF805340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C3404FD31F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F8F805353434343534343435343434353434343534 +%343435343434353434343534343435343434353434343534343435343434 +%352E05F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804FD04F804340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C34122DF8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805 +%F805F805F805F805F805F805F805F805F805F805F805F8F8F83434340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C353434F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805FD1AF82E0C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%05FD33F805F827F805F827F805F827F805F827F805F827F805F827F82E34 +%353434343534343435343434353434343534343435343434353434343534 +%343435343534353435343534353435343434353427F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827FD04F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F8050C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C3534340B2E050505270505052D0B340C351234122EF8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F805F805F805F805 +%F805F805F805F805F805F8040B3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340B2D0405F804F8F8F805F8F8F805F805 +%052E34350405F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805FD17F805 +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340B +%2DFD13F80505FD35F827F805F827F805F827F805F827F805F827F805F827 +%F83434353434343534343435343434353434343534343435343434353434 +%0527F805F827F805F827F805F827F805F827F805F827F8F8F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F82D34340C340C340C340C340C340C340C340C340C340C +%340C340C340C2EF8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805 +%F805F805F805F805F805F805F805F8050C3534340C3534340C3534340C35 +%34340C3534340C3534340C352E27F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805FD15F805340C340C340C340C340C340C340C340C340C340C340C340C +%340B05FD50F805F827F805F827F805F827F805F827F805F827F834343534 +%3434353434343534343435343434353434343534350B27F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827FD04F804F8F8F804F8F8F804F8F8F804F8 +%F8F82D34340C340C340C340C340C340C340C340C340C340C340C350BF8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F805F805F805 +%F805F805F805F805F8040C3534340C3534340C3534340C3534340C353434 +%0C3534350B05F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805FD14 +%F8340C340C340C340C340C340C340C340C340C340C340C340C04F804FD52 +%F827F805F827F805F827F805F827F805F827F82E34353434343534343435 +%3434343534343435343434353427F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F8F804F8F8F804F8F8F804F8F8F804F8F8F8040C340C +%340C340C340C340C340C340C340C340C340C34122EF8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805F805F805F805F805 +%F805F8F8043534340C3534340C3534340C3534340C3534340C353434F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805FD12F8050C34 +%0C340C340C340C340C340C340C340C340C340C3405FD57F805F827F805F8 +%27F805F827F805F827F8050B353434343534343435343434353434343534 +%3434352E05F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27FD04F804F8F8F804F8F8F804F8F8F804F8340C340C340C340C340C340C +%340C340C340C340C34122DF8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F80405F805F805F805F805F805F805F805F82734340C35 +%34340C3534340C3534340C3534340C353434F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805FD11F804340C340C340C340C340C +%340C340C340C340C340C340BFD59F827F805F827F805F827F805F827F805 +%F82E3434343534343435343434353434343534343435342DF827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F8F804F8F8F804F8 +%F8F804F8F8F804F8F805350C340C340C340C340C340C340C340C340C340C +%34F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F805F805F805F805F805F805F805F805F82E343534340C3534340C353434 +%0C3534340C3534340C05F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805FD10F8040B340C340C340C340C340C340C340C340C34 +%0C34122DFD5AF805F827F805F827F805F827F805F827F834343534343435 +%34343435343434353434343534350505F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827FD04F804F8F8F804F8F8F804F8F8F805 +%0C340C340C340C340C340C340C340C340C340C341205F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F805F805F8 +%05F805F805F804F83434340C3534340C3534340C3534340C3534340C3505 +%F8F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805FD +%10F8050C340C340C340C340C340C340C340C340C340C340C05FD5AF827F8 +%05F827F805F827F805F827F8050435343434353434343534343435343434 +%35343434350504F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F8F804F8F8F804F8F8F804F8F8F804F8050C340C340C340C34 +%0C340C340C340C340C340C340C27F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F805F805F805F805F805F805F805F805F8 +%34343534340C3534340C3534340C3534340C3534350504F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805FD10F8040C340C340C +%340C340C340C340C340C340C340C34120BFD5AF805F827F805F827F805F8 +%27F805F827F83434353434343534343435343434353434343534350B27F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827FD04F8 +%04F8F8F804F8F8F804F8F8F8040B340C340C340C340C340C340C340C340C +%340C34122EF804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F80405F805F805F805F805F805F805F805F82E34340C3534340C35 +%34340C3534340C3534340C353405F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805FD11F805340C340C340C340C340C340C340C +%340C340C340C3405FD59F827F805F827F805F827F805F827F805F82D3435 +%343534343435343434353434343534343435342EF827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F8340C340C340C340C340C340C340C340C340C340C340C05F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805 +%F805F805F805F805F805F805F8050C3534340C3534340C3534340C353434 +%0C3534340C3505F8F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F804F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805FD12F82E0C340C340C340C340C340C340C340C340C340C340C34 +%FD2FF8050C340505FD24F805F827F805F827F805F827F805F827F8F80535 +%3434343534343435343434353434343534343435342DF827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F8050B353435342E0427F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827FD04F804F8F8F804F8F8F804 +%F8F8F804F8050C340C340C340C340C340C340C340C340C340C340C340C04 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F8340C340C3434340B05F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F8 +%05F805F805F805F805F805F805F834343534340C3534340C3534340C3534 +%340C3534340C350BF8F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F82E343534340C3534 +%3534340505F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805FD13F805340C340C340C340C340C340C340C340C340C340C340C34 +%05FD2AF82D12340C340C340C340C340C340C0BFD1CF827F805F827F805F8 +%27F805F827F805F827F82734353434343534343435343434353434343534 +%3434353434F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F82734353435343434353434343534 +%3534350B27F805F805F827F805F827F805F827F805F827F805F827F805F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F82E0C340C340C340C340C34 +%0C340C340C340C340C340C34122EFD05F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8050C340C340C340C34 +%0C340C340C340C340C35122E0404F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F805F805F805F805F805F805F805F805F805F80405350C3534 +%340C3534340C3534340C3534340C3534340C35342EF805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F8272E +%350C3534340C3534340C3534340C3534340C3534350C2DF805F805F805F8 +%05F805F805F805F805F805F805FD14F8040C340C340C340C340C340C340C +%340C340C340C340C340C34122EFD23F8040B340C340C340C340C340C340C +%340C340C340C340C340C34122EFD14F805F827F805F827F805F827F805F8 +%27F805F827F82E34353434343534343435343434353434343534343435FD +%043404F8F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F8272E3534343435343434353434343534343435343434353434 +%34350504F827F805F827F805F827F805F827F805F827FD04F804F8F8F804 +%F8F8F804F8F8F804FD05F8340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C3405F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F82D12340C340C340C340C340C340C340C340C340C34 +%0C340C340C340B04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F8 +%05F805F805F805F805F805F805F805F805F80405350C3534340C3534340C +%3534340C3534340C3534340C35343434350B05F805F805F805F805F805F8 +%05F805F805F805F805F805F805F8F8042E343534340C3534340C3534340C +%3534340C3534340C3534340C353427F805F805F805F805F805F805F805F8 +%05F805F805FD16F8040C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C0BFD17F804053412340C340C340C340C340C340C340C +%340C340C340C340C340C340C2EFD16F827F805F827F805F827F805F827F8 +%05F827F805F827F82D343534343435343434353434343534343435343434 +%3534343435343534340B27F805F805F827F805F827F805F827F804F82705 +%2E2E35343434353434343534343435343434353434343534343435343434 +%350504F827F805F827F805F827F805F827F805F827F805F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F82E12340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C350C2E0505FD0BF805040B0B34 +%34340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%05FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805F805 +%F805F805F805F805F805F805F805F8050434343534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C35343534340C2E052D0527052E +%0B2E0C353435123534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C352E05F805F805F805F805F805F805F805F805F805F805F805 +%FD19F805340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C3412340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C05FD18F805F827F8 +%05F827F805F827F805F827F805F827F805F827F8040B3534343435343434 +%353434343534343435343434353434343534343435343434353434343534 +%353435343434353434343534343435343434353434343534343435343434 +%35343434353434342EF805F827F805F827F805F827F805F827F805F827F8 +%05F827FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8040C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C34342EFD05F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F80405F805F805F805F805F805F805F805F805F805F805 +%F805F805F8050C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C35FD043404F8F805F805F805F805F8 +%05F805F805F805F805F805F805F805FD1CF8050C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%34FD1CF827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F82E343534353434343534343435343434353434343534343435343434 +%353434343534343435343434353434343534343435343434353434343534 +%343435343434353434343534350505F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F82D12340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C3405F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F82D34340C3534340C3534 +%340C3534340C3534340C3534340C3534340C3534340C3534340C3534340C +%3534340C3534340C3534340C3534340C3534340C3534340C35343405F8F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805FD20F8 +%2D0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C3405FD1FF805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F827343534343435343434353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%34353434343534343435FD043405F8F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827FD04F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8050C350C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C34342EFD05F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F8050B353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C353435342EF8F8F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805FD25 +%F8053412340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C05FD24F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F805042E343534343435343434353434343534343435343434 +%35343434353434343534343435343434353434343534343435343434350B +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804FD05F8050B3512340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C34342E04FD04F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805053434350C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534350C2DF8F8F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805FD2CF82D0B340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C2E05FD2BF805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F80505343435343534 +%34343534343435343434353434343534343435343434353435343534340B +%27F8F8F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827FD04F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F805052E0C3534340C340C340C340C340C340C340C340C340C340C340C +%3512340B2DF8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F804F805052E2E34343534353435343434353434 +%343534353435342E052DF8F8F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%FD38F805052D0B2E0B340C340C340C2E0B2E0505F805FD36F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F805F805F827F805F827 +%F805F827F8F8F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805FD81F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827F805 +%F827F805F827F805F827F805F827F805F827F805F827F805F827F805F827 +%F805F827F805F827F805F827F805F827F805F827F805F827F805F827FD04 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F80405F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805FD81F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8 +%F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804 +%F8F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805F805F805F805F805F805F805F805F805F805F805F8 +%05F805F805F805F805FD81F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827F805F827F805F827F805F8 +%27F805F827F805F827F805F827F805F827F805F827F805F827F805F827F8 +%05F827F805F827F805F827F805F827F805F827FD04F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F8 +%04F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8 +%F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F804F8F8F80405F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805F805F805F805F805F805F805F805F805F805F805F805F805F805 +%F805F805FD80F8F8 +%%EndData + +endstream endobj 21 0 obj <>stream +%AI12_CompressedDataxiw( +Z`yc !! !@ @lolO y=^; XJR5s?k&iA?[j2'Wm!b#efzDO}Wbr% ~W ;bwC{)R[ІdIB&qܒk&/eP<̯w|_7iB8?|VwiVAq=ЫmYOh-kMZ +P+KO(ˀ^.[KjjQy!jj9ik3#aA}d8~FFSnARԡn%/ az_s4 DCYo~YgD&‰@BDpW,4AD8 8#ñi!K(HS(Ê"!;!H[9wZh9f1 ^򏺻%<[0((\O%xCQ^R_@"B˷x/z 8`m{X,5h8W>ꪟ XH$ <D-2 h$-(Ga }4l!H+!{QBBWb:+kJ O(6Q?m&KXzD5G{A)k)a֩+}YlO]FuirE#r՜!$YeC,G(dr20!'EHyQ+#L%#ek +*Ab CD|AMQqm5ۣ'땰~PH{Q3;tXC==jᐟb1b?x$?ADhC Lp8oL Pa@` +.F0H7-cj)=Q n v 5QN &mHs=e%Z0JJVKtgu$Rg"Ǐ6thvFLe\鿛5+} 0dLh-z+.  ZQU}n 7 4 TeJWuQ ԸWq_]*ZN \pƽ@t_^Zf + +`$@E#l ]n|`k92qA5^`3вuW5A*۲f ƳPZrieY1h:Y/jW$P;y,ޭ0Ʉm^ijv-e af9cC NsFlc$^Z,x`4 A`" ;_0]liWbq\^oW#3k?UFbk nJKbZخ7"Æ:i'lf&Q"͘i`|f'g N` m6Pَ.QrƧ|C2O#!8C_ZRF#pu%40*!]U@/H?5%kf+IUJǰԠ10YA-':M>w%8bOV#kc$SkLMNԾILa+}> Ҙ VTj8zz/,?zӍ`+ W׭PC<z=*PL=;on_*Ad~{ZfB2&TrD[>>^_7FgZ3h[@)%עX7RM* 522%lR!;LI*؊* j4\o5Qj4J $e+ P{`Pm`0땮lXWlC"1_SRu. /f/t-<h&e;\,2j:p2RX 4r3jH +'w@cPjQklP7ZҞnE/ yA p) l %Ow;WTWw2;.'yUݣޔ4I#ߠPS3[Ք"B\zZ-)Pv]~ P1خ&n5>F覅a9n6nrx{0G_dѻW?x!K?œD)|гx~<3:6+w~Pwb.4&GI+v8&CoQ^4ȗ0+-cߢEry G`ې d og+ߖkh>j[j6ofV4dM7cTZ%s=_vUMa3i6+|d{zñWQџMKcܷO0޼?qZMkN..CezP"1 zp7ֹy%#7[psqZf3X~FE/fs~V:~cX) )`Xn {j'Z1w$&u 7[ٵFKou#?dŕY$f[XŎTt9xse[cM[oo,0)bW+9;Vf 76u=Z85~cZ3=ϏXmŞ׾2J ~|>">lƎ}N l}lOrہ +;yŶ>jjjVG氺fϏVo![oR7h5r7՛5nYfk-̺=kֆVm[f]ޯu@o:a##c NlQmpffsO6/ZAqn?n>mغk۪=lk<-R}66Ll6C16c&m-l#e3veWfvm`?מo0{H8Pooz"MٟɊ-ة٬vgl+kfhϭƵw|&Z:yo[u]Wff=u|\^OGz9q`S*p.gǬ7dxud9@DuGyr<8|)}eyEG^S󻟜gg? 8ooޜ:쬵{Sg-q>]nt~F^O6rn t +s>Ϯh"t[W|jzX7jmewcFڝygouwXcu<Ѹ6OtXdᅧӞ{ǚ g<ճ]^nK#M:?OoW\zόfE]=NnCǻ `H>]-z-L*wێ }(bj4rT=#j$15vO&V L%9g!Uhn&\oE'{P6nOwΛ-?.[6[vf-s~|A!Lݩ5F}{=ҾJIaUң&dfqd"n1L{da6T"lW\,\Xv"^t{z};Yy'w?g-a&^hyBHz]s\ϻi1nŻv P>rGW +:R>q߰\iOl&8K[W2Qϗ䬑yy%/?%wd=}~s&[z6ޤ0h7xxk {w|rUI&A<]5ӷo6cbwo#}QV h&'Vaן'-z/HD,ETf.Ur!L#!I9zE0p?z] {\3yoR-<H>0i4m_~S6mՔb5GgbZHQ=/IpfcD w&f4 W-m#? +^YX +,Jz%?E _9;f ^Z,t /jpD> @uhٮ! mt9ʲ +;cwtWR[Q2ö[eZk\ <=a5 r>HFT=B2efΩApE.q'ea#Fu!G!.Wӹ҇ɝϝr=T&_6W訷`%u&;JRosZEGd!^N+49UH+o1%h(P7j:,MG?HkL +mAvJ&湩>_c%OjK?v?5_ +#I -uVmyO^!^|V7(HE 6J]q)LƵ{zdq \`2o&+dHC,1&@R.+KaS=T'ZfTW'*PRPWfArz \ S[΃}_BuLӡXM^ D/-qkp8T53Y|AS5* nTO#QM`rhhyÐA0.<'x7y3qz~of Od>?BnBm,n*~)Mu30م!ozq[/ 7g̻K0_&S +0KMл"iCx(}?SO.4 NsM.[Ox)P^%/T.5!< +Goz0$NW?"A s @c3 v殙F'c5T"ftx99l׉?޽AquMeNT8-=]УFTkn8BIePWà bxy' ip!7]"mA6^ oQXܰo̰v`#{@뻽+b\ K\3X;[J&=jXYW +A62sQAIm k+:TÊ֨37 + ?CX !C+13ϸy|a e XmldځXqVɍWЭ|9xlݩ>Q-^{nmM3MPlǦCه]ETEčWXN^Ym<`-kujDv'/1h֚˶J׶7ڝUZLJ 7x靓'Jg'U[/CYWiQ#ZJ dOo]SVidgyhoT>̕S[i;fG%$y4]t\`؉v)?ty3*F}A8N=)/VVJ?[k$'>9kVׯ}ʨ=e>wS2_kx$&7attyo)'ħ(}7Nao7I`b cy4}\n(:4 >*"ƽNG,B(6+'wrvnYK +J`3}-Ӷ14wb ԰¤-Z~ϯ+^GXҼ +݌4V. EV*`5$~7ke"U'P:p.%}+:u8l"V򱥁52<7f[{|)@ݰh#w+.t5%;¾tUu?Z;AuLA)|pFGmZ$<2l tIIQ +4,v\_?#߷~ EozJh(~:;a1pzs[҇p$|;/1zcOufOtWa7FPE 4L695yL&x9&Q}+1 +DBhOEkMPvgU$t[;A+hҡט=^;SJ!Fa}GJw(ҐaiX;xeM|V;6~?RWJήkq^縷8spo6s##[KZijh8.K|8mHŀRףqpyT+o|F3zڸ#n^=? ד)Ԁ1V>E *&_᧌Uq*bS +yEЋdЄÎ%5:F#8/Re(ȠqI7䵙BH6ū6)iE.bVlkN2T1FHX5$vٯnlZgV\s[#]osC5E'i!߽pCA:҉0<4Ma1DS(|gM.y%pB`<_n*.]@sަ%$P__UUC_U~]iJs (smڜ潃j=2oW:Ώ(ZYOգ@͞`CB֩qn;c$8Vݰ#=ÅFq ȏ$ +wqWqkLQbpԠ\#\ʈ(I4 +0Դ}}QBhEh&3[Oh4 +yP!bY2pk5Φ"RՏZ:{KSۃN8'N؍"'С=2ksIN0L1ȽS* Yr'ԢhN'CtS/dOlk'fJx?нQ +R? q]WFlq$m璯ӂ[.5B/j.n1jLj*y]`h;+ +6uB$ ia4 +$P̩nW1sd5)f BhA3LU_@BBΔeY4sRxƗ(Ԩ ]skb|sFK4~$ۻ*25BxА -iButEwhmuT⚦ipbzyGuK{,2שة*;3NfNe"5N:RYg^OBh&ϕH /5 4+k@P'WA>N-XQ i鞫kaw50?,ӯSHj|b||W)#gcjK/ӯJ-ӯ:*]K,ĊjJ-ӯ哱9||Fp~9~-L@9~-Xb ;[ H*\V?lCrDTY8 ׏pRuKʩ&͒JyiBU*|JdfЯk6'I~ݒG 'u;r'T7 +KzeG嗼ل؄y7f[5jˣK |)&ewnfQ-T ͗E+aԢaP@Q^Bxj4hf 6DYRVT,"vFRS(bb>iĊVV0e'9dY3Uh: =dW88N)ԻT2HKX6n40LiU$eڤ:,Bt⽑)tT5ح7zyG:d{o2ބ(ڔ&Cbww UP SmpG&'ݝ轑l S&#\/K@˜H7W 5R=f#,m ϯ<F 0f퐺ghݘm'{&ch026d~ccckLaԖ=5E(`rNT|rxN =NTdo. Osq .qh2 i{gTr*λteɰU$^2TyWfKϫ̓4iq)*$]<tzes{\ʼ]2O<#+ {f'ʪԭU/ +G(ҐR=ypxqZTk &;~C?X )ǥ_UPi[:Z(4u j?{=óN2:XnKo}+H+E@?MzGpgQЙ둃_&mM M~&AY:pkφg`uP)}d,v"ٷV3U?FAT(;[2 .o=ذmdρBNAF0JD+\-j \IOoǷ\dۚvйEyr*#EyDtQEyR٤BQQY'̍xRQLc:BBs|fa g2e־qƕ_uh&d4ٌYʧF&P-ZHt:yV84 +Q[OoԹZ ϘpzQbSCqA3CjፂOh,SN[?t-H+ew#v URWJx5,5 &Vt\PźVٝn&J( z6|iUuDH)/ECt* K;~LIoTo;XpU7/أX+ u{ޤt:DnXKDz|^܁ +§= 0;O*ߔo*&dNpԛ\oKf +F=+UTSe-{\-1UN9'e,}wznOܺ)huTuvJu|Q0뙞>6]:7{TrPRzGH V +FhQE +}ːJQL=OK - ".Vا6+Ui=O/;>qD/9n>5DЗ*3LLa&}>3 UqhaN% ԪR{O,SNKYy}> U}Kb}jZpU +P LaZUߕu,>O ԕ}jU}MSfOA +3/Zا?/S[Kb}jU}WfZا@.l.Rا*З(SsdKv¾#Ѥq6K)Ԣ&mČ(/)_z,dvqk5ËUeS}`nfmOCR_<'}׌n4K3td[ {}4q>!2\\Ӧ-kzt l`hm BS~BQF*<&dm}1Vg\RrQYgx9+wㆿ|hq.UuBqh.s +6xW϶ e9Bl$Wի9\u~5Ѧn*àZz95}FXw{H\1RhV? ynUMsv'D\P킩VZV#b +a[^ :W D[m%:N1"վ(Ӄ'0R3𠰽2SiBH7-I63@L^UdmEέV,T5a zeaܱ'(8F_XxQ"sttB-Ɓ]Ƹ$ yQM}{)B1OCsPE5 {/!$)f)]i2&޿Tu]@et] x({:?a#(hbp'؞Ws_iǤh4md>@cT߂ZSxaj_38@W(r\"ltZڢ:^mҌ2!+\Ш^CstiW\))4B =P2B)ю1ugMޤSN lOX|o)rA=]Ⱥ['}ڟnhQ|ajldyyıa!C=|m!`P)+ln 3g lBNLS>$nk'» /ru0e9PJƃ_ PF&C\sؠR<_JL6W>Iaho#)^;W=nyثɎ" )+ LMZ~5-֪TV!R`_8 jb{ QZMѻϟ`U^M{q#Hlui1B{{} @s`xw!/DW\yAϦZXizgMK׊&e:*+X<~g 71.PkLJ"M)q6*ꨰ˻r3Uq.K7Y׹v+9$O9"?Mo~-()Eq4 I5yMBe֍NXv_uh +EW`} QimtvTL.W {y慇QQ λP:v!/<u]x1v(Y'%Is!} #>:ss܅Ezuo;TDNPH uꅇ}:X9Cqh{E#Vs;ɬΐ=*Z:K$Zo~?{9+?]QD?2=aBv̺k>q4&}ot? |z*2L&vc,ם^ѫ G3ݗz+c 7 ok~ 6#_Uq]2,1x/m^3s&k2\zM|foͻC U-o"ʔ0Up[8ˤ+O.-weWV#Jœ +pV7~rT 뇛OZ/BGkD=%< W@|MzWk}} +oo?#kٯMc@ҮGp=?I<WRg%6hDay%+_`ĹM+o~jA¯$|~~嚌7tG{<84eK߳7x.%.QdF@MT'ߤe q H"hco7L4nbé[UƳl!2M&I2d*dF@'iHvhٓ%75?_ u3zB/T"CGv]ys/;7ь%x +yb旁/O3l5'zvptީ8 ]ju䖻| 5{q?io).< ťu>9Kc P9'D%Wh:#_Q+Q%uahJaPEr4^2bh5_7/U?G+8 O.na}w@^n^,@pn8qWy4pV?r !щsE'4^g o( 5 3hB$"5&#TB׽K>'sZ&)!8N9UFЄ?tƖY47tYbo(Q3PzZghQ4<=_쵉V#t<.8=P_٘CGv[3&$'GOk:U88꽷@ƜG;|ֆmBigU0>̇}8&(Ŗ& rbyok#PZPU[}r-Ð[g \;OD-8rh.;8T/9ݑ;ۺJE6?qir5`ĘU{)pLϹvH2VӛK;0̼|ekR|GV";L^XzQ{ZM|%=.5 +#x6nf2dž"C-ـ9d.}ڙ\0WY`&yޗ.΅y`[hz37ibԚMZ}S([1suC3曺VTR 0ӡߣj lQ)Mhf6CfgZ~/'VZRA3t.XkGtz'o<ܟv9K{nU;Uz?-r] ~vDC.;t=owJG,'.=]dqG{ynKO9M/'.wK6f!m 'Grxmvu=`5čy݆v4#?`d]b E&Y\Ugؼwz3`^O; 9Ib0,i#2+e54D%0UyP!piY刬\7k!g&}ٍ-o^`=Swvҕ1߬t"!$~~~0.Y#}ӍJo7~Is)t\ ߆&tdUnuC!ozYV` ƹ̓}P.>EʼAWGM4hnvXeW~GWF%l|w-ygz[D˻^!: XkBcYﻳP֊'Bgk{O%V^ ^X)IHPx DeD1_@¯tUIs<@ƹ&aF% e].i +i:-Aaz{uZ+i#6uT/ D m +_rk 48Wq94Hӂ ڤT`0HH/2`ĭ+ |T$>.T1WQJYk4$4p_+AEeNzOljrK}e]Zkxuim=/h6znI W+}jKZZ +3[t'Qgqpf WcI,5'&\A4S'?41Dpᵫ6Hs/y$0\lڐLL)pP, }1'Qԡ7RRGW>%˴!,9ܽg{H`L4Ɠ/pF?!L rBOaF֟ G4/\,JQ}_>(.|;"%zbɯGY;6ı\D)LK)LK9d +p{2c)P>d +R\ EgLaX +iLaX +)LKќ{2 [LaX +{2c)gLaX+ieω'S8?)LK漓)LK7=ıW谤N0k%#P?H%Ȃ$͍4ϽCO1)?H?HSBC7^>w'` xNӌO$f"022.<+2d>hqOՠ#'O|*ϧȧJ˟|JsYK'i:~^K$i|*9-"?/\CɑO s-LsyOӤ?4qAuSO"'mG>kH#OnnO|-iKD>y_gPD>YD>QS#O.v]+|!'@8H! zv48 =7ʇ: sW.nch4QP2 E1  +tQ@h(@c" *VSi| ~5|ՠ&,p?7dBF"KJ nKcAUr1|W%~{n6kEK½3X\g4(:",.M--.֦p7% ÑDC&p"Da$X(D$!'p"GX8'8lGb, Qې噂H:v>}iyxؽO~`+@<K{ڀ>!$I-$D8?s?fCZsh8?/`~B1 I@(!c 0$7C%sJԅ`I"xAلǀP,!h$²-  y8Gq2w(AҌL=i!x8LNP7ڛ eluj+鋥-jvv_ڿv?/ +endstream endobj 6 0 obj [5 0 R] endobj 22 0 obj <> endobj xref +0 23 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000014733 00000 n +0000000000 00000 f +0000016392 00000 n +0000073660 00000 n +0000014784 00000 n +0000015161 00000 n +0000019375 00000 n +0000016691 00000 n +0000016578 00000 n +0000015450 00000 n +0000015830 00000 n +0000015878 00000 n +0000016462 00000 n +0000016493 00000 n +0000016726 00000 n +0000019448 00000 n +0000019622 00000 n +0000020808 00000 n +0000050721 00000 n +0000073683 00000 n +trailer +<<276BE84415866442BF2446298C96C9C0>]>> +startxref +73875 +%%EOF diff --git a/misc/branding/icon_dark.png b/misc/branding/icon_dark.png new file mode 100644 index 00000000..958dff73 Binary files /dev/null and b/misc/branding/icon_dark.png differ diff --git a/misc/branding/icon_light.ai b/misc/branding/icon_light.ai new file mode 100644 index 00000000..648f8349 --- /dev/null +++ b/misc/branding/icon_light.ai @@ -0,0 +1,798 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 23 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + conreq_icon + + + 2022-02-04T00:14:17-08:00 + 2022-02-04T00:14:17-08:00 + 2022-02-04T00:11:30-08:00 + Adobe Illustrator CC 23.0 (Windows) + + + + 256 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AIMm8Q7FXYq7FXYq7FXYq 7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq2iO7BUUsx6KoqfwxUBzo6MVdSrDqpFDitNYq7FXYq7FX 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 + + + + uuid:365626fb-fe9e-4cf6-ae51-47d5edd17f39 + xmp.did:b808ad0f-6600-2a47-9fd0-e78d32178954 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:9d11e7b4-db71-4812-8be0-126cedbc01ea + xmp.did:8359a53a-d8aa-ee49-8402-e0c80ad93cef + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:92a05db4-1ea6-407a-afb7-538f80719779 + 2021-03-18T19:52:57-07:00 + Adobe Illustrator 24.3 (Macintosh) + / + + + saved + xmp.iid:b808ad0f-6600-2a47-9fd0-e78d32178954 + 2022-02-04T00:11:30-08:00 + Adobe Illustrator CC 23.0 (Windows) + / + + + + Document + Print + AIRobin + False + False + 1 + + 300.000000 + 300.000000 + Points + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Adobe PDF library 15.00 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 29 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 25 0 obj <>stream +Hl=n0 w0MJduNix I4Cgm29<=R(tw?RIh)FtO% پ_Lq]IcV|\S:uQJ᪨搼%r+pk +EHk>u难Ax?NƧB_tÑ->stream +8;WRqh$q.B#_XS0_si?V&)fQd;"UERXbQIh! +#He4[1(%0\^9c'u9X#;uaDU(Tm?B75BW)79p +!#6TbC]~> +endstream endobj 30 0 obj [/Indexed/DeviceRGB 255 31 0 R] endobj 31 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 23 0 obj <> endobj 32 0 obj [/View/Design] endobj 33 0 obj <>>> endobj 28 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 34 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 26 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 17.0 +%%AI8_CreatorVersion: 23.0.1 +%%For: (Mark B) () +%%Title: (icon_light.ai) +%%CreationDate: 2/4/2022 12:14 AM +%%Canvassize: 16383 +%%BoundingBox: 0 0 300 300 +%%HiResBoundingBox: 0 0 300 300 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 13.0 +%AI12_BuildNumber: 540 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 0 0 300 300 +%AI3_TemplateBox: 149.5 150.5 149.5 150.5 +%AI3_TileBox: -144.240000724792 -234.239990234375 444.239990234375 534.240000724793 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -265.009174311926 343.064220183485 3.02777777777778 3064 1274 18 0 0 78 121 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-156 -246 +%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 37 0 obj <>stream +%%BoundingBox: 0 0 300 300 +%%HiResBoundingBox: 0 0 300 300 +%AI7_Thumbnail: 128 128 8 +%%BeginData: 29143 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45353434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%34343435343434353434340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C34340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C35340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C3434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%343434353434343534343435340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C343534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C0C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%3434343534343435343434353434340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C34340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C34343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%34343435343434353434343534343435340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C343534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3434340C34 +%34340C3434340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C0C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C120B +%340C340C342E3534342E340C340C120B340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C3435343434353434343534343435343434353434 +%343534343435343434353434343534343435343434353434343534343435 +%34340C343459598484AFA8FD07FFAFFFA8A8838435350C34123434353434 +%343534343435343434353434343534343435343434353434343534343435 +%3434343534343435343434353434340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340B34348384FD15FFA8A859590C120C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C34340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C3534340C3534340C345984A8FD1DFF8359 +%0C3434340C3534340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C35340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%342E5FA8FD22FFA859340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C34343435343434 +%353434343534343435343434353434343534343435343434353434343534 +%34343534340C5984FD27FF34343435343434353434343534343435343434 +%35343434353434343534343435343434353434343534343435340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C343484AFFD27FF842E0C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C343534 +%340C3534340C3534340C3534340C3534340C3534340C3534340C3534340C +%3534340C350C3459FD2AFF590C342E340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C0C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340B59A8FD2AFFAE0C2E0B2E0C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C3435343434 +%353434343534343435343434353434343534343435343434353434343534 +%340C84FD2CFF592E0C342E340C3534343435343434353434343534343435 +%34343435343434353434343534343435343434353434340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C3434AEFD +%2CFFA8340C2E0C340C2E0C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C34340C3534340C3534340C +%3534340C3534340C3534340C3534340C3534340C35343459FD2EFF840B34 +%0C340C340C340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C35340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C1259FD2FFF2E0C0B2E0C2E0B2E0C +%2E0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C34343435343434353434343534343435343434353434 +%34353434343534340C3484FD2FFF842E0C342E340C342E340C342E343435 +%343434353434343534343435343434353434343534343435343434353434 +%3435340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C1283FD30FF590C2E0C340C2E0C340C2E0C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C343534340C +%3534340C3534340C3534340C3534340C3534340C3534340C3484FD30FFA8 +%0C340C340C340C340C340C340C342E340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C0C340C340C340C340C340C +%340C340C340C340C340C340C340C340C1259FD31FF350C0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C3435343434353434343534343435343434353434 +%343534343435343459FD31FFA8340C342E340C342E340C342E340C342E34 +%0C3534343435343434353434343534343435343434353434343534343435 +%3434340C340C340C340C340C340C340C340C340C340C340C340C340C3459 +%FD32FF830B2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C34340C3534340C +%3534340C3534340C3534340C3534340C35343434FD33FF2E340C340C340C +%340C340C340C340C340C340C340C3534340C3534340C3534340C3534340C +%3534340C3534340C3534340C35340C340C340C340C340C340C340C340C34 +%0C340C340C340C340CA8FD32FF7D0C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C3434343534343435343434353434343534343435343434350C84 +%FD33FF350C342E340C342E340C342E340C342E340C342E340C342E343435 +%343434353434343534343435343434353434343534343435340C340C340C +%340C340C340C340C340C340C340C340C340C59FD22FFA8A87D83FD055984 +%84FD06FFA80B2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C34353434 +%0C3534340C3534340C3534340C3534340C353434A8FD1FFF848434340C2E +%0C0C0C340C0C0B342E5959AFFFFF34340C340C340C340C340C340C340C34 +%0C340C340C340C340C342E340C3534340C3534340C3534340C3534340C35 +%34340C3534340C0C340C340C340C340C340C340C340C340C340C340C1259 +%FD1DFFA8842E0C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0B0C0B35592E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C340C340C340C +%340C340C340C340C340C340C340C340C340C343534343435343434353434 +%343534343435FD0534FD1DFF59350C340C342E340C342E340C342E340C34 +%2E340C340C2E0C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C3534343435343434353434343534343435343434353434340C +%340C340C340C340C340C340C340C340C340C340B84FD1BFF840C0C0B340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C340C340C340C340C +%340C340C340C340C340C340C34340C3534340C3534340C3534340C353434 +%0C351235FD1BFF590B340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C3534340C3534340C3534340C3534340C3534340C35340C340C +%340C340C340C340C340C340C340C340C1283FD19FFA8340B2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0C340C340C340C340C +%340C340C340C340C340C340C343434353434343534343435343434353434 +%343534FD19FFA8340C340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E340C342E34343534343435343434353434343534343435340C +%340C340C340C340C340C340C340C340C340B84FD18FF840C0B340C2E0C34 +%0C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C340C34 +%0C340C340C340C340C340C340C340C343534340C3534340C3534340C3534 +%340C353434A8FD17FFA8340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C342E340C3534340C3534340C3534340C +%3534340C0C340C340C340C340C340C340C340C340C3434FD17FFA8340B34 +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C340C340C340C340C340C340C340C340C343534343435343434 +%3534343435343434350C84FD17FF590C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C342E340C342E340C342E340C342E340C +%342E340C342E340C342E340C342E340C342E340C342E340C353434343534 +%343435343434353434340C340C340C340C340C340C340C340C340C34A8FD +%16FF840B2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C340C340C340C340C340C340C3434 +%0C3534340C3534340C3534340C35343434FD17FF2E340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C3534340C3534340C3534340C35340C340C340C340C340C340C340C +%340C340B84FD16FF590C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0C340C340C340C34 +%0C340C340C343434353434343534343435343434353434A8FD15FFAF340C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C342E340C342E340C342E340C342E340C +%342E340C342E340C342E340C342E3434353434343534343435340C340C34 +%0C340C340C340C340C340C3434FD16FF840B2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C340C340C340C340C340C343534340C3534340C3534340C353434 +%0C5FFD16FF2E340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C342E340C3534340C +%3534340C0C340C340C340C340C340C340C340C1259FD15FF840C0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C340C340C340C340C34353434343534 +%3434353434343534340C84FD15FF830C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C342E340C342E340C342E340C342E340C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C35343434353434340C340C340C340C340C340C340C340C34 +%84FD15FF2E0C0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C34 +%0C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C34 +%0C340C34340C3534340C3534340C3534340C3434AFFD14FFA8340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C3534340C35340C340C340C +%340C340C340C340C340C34A8FD14FF840B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0C340C340C343434353434343534343435343434 +%3534FD15FF83342E340C342E340C342E340C342E340C342E340C342E340C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C342E340C342E340C342E340C342E340C +%342E343435340C340C340C340C340C340C340C340C35FD15FF590B340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C34 +%0C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C340C343534340C +%3534340C3534340C35343434FD15FF590C0C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C342E342E0C340C340C340C340C340C340C34 +%0C35AEFD14FF590B2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C3435343434353434343534343435343434FD15FF59340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C0C340C +%340C340C340C340C340C340C35FD15FF5F0B2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E340C3534340C3534340C353434 +%0C3434FD15FF592E0C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C0C340C340C340C340C340C340C340C34A8FD14FF840B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E3434 +%3534343435343434353434343534FD15FF84340C340C342E340C342E340C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C342E340C342E340C342E340C342E340C +%342E340C342E340C342E340C342E340C342E0C340C340C340C340C340C34 +%0C340C34A8FD14FFAF0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C343534340C3534340C3534340C3534340CAEFD15FF35 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C0C +%340C340C340C340C340C340C340C1259FD15FF590C0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E3534343435343434353434 +%343534340C84FD15FFAE0C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C0C340C340C340C340C340C340C340C3434FD16FF34 +%0B340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C34 +%0C2E0C340C2E0C340C2E0C340C2E0C340C2E0B2E0C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E340C +%3534340C3534340C3534340C353434AEFD15FF830C0C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C592E2E0C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C0C340C340C340C340C340C34 +%0C340C340CA8FD16FF0C0C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B34FFFF59 +%340B0C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E34343534343435343434353434343534345FFD16FF840C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C342E340C342E340C3484FD04FF8434340C340C342E340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E0C340C340C +%340C340C340C340C340C340C59FD16FFAF340B340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C34 +%0C0C2EFD07FF84590C0C0B340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C343534340C3534340C3534340C3534340C3434FD17 +%FF840C0C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340CAEFD0AFF59340B340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C0C340C340C340C340C +%340C340C340C340C1283FD17FF590C0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B83FD0CFF +%A8842E0C0B2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%35343434353434343534343435343434351259FD18FF34342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C59FD10FF84590C340C340C342E340C342E340C342E340C342E340C +%342E340C0C340C340C340C340C340C340C340C340C340CAEFD17FFAF0C2E +%0C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340B34A8FD12FFA859340B0C0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E340C3534340C3534340C3534340C3534340C345FFD18FF +%AF0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340B35AEFD15FFA8842E340C340C340C340C340C340C340C +%340C340C340C0C340C340C340C340C340C340C340C340C340C34A8FD18FF +%A80C0C0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0B34A8FD18FFA80C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E343435343434353434343534343435343434350C84FD1AFF340C0C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C340C59 +%FD1AFF592E0C342E340C342E340C342E340C342E340C342E0C340C340C34 +%0C340C340C340C340C340C340C3434FD1BFF590C0B340C2E0C340C2E0C34 +%0C2E0C340C2E0C340C2E0C340C2E0C340C0C0B84FD1AFFA8340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C343534340C3534340C3534340C353434 +%0C3534340C3483FD1BFF84350B340C340C340C340C340C340C340C340C34 +%0C340C340C340C2E34AEFD1BFF5F0B340C340C340C340C340C340C340C34 +%0C340C340C0C340C340C340C340C340C340C340C340C340C340C34A8FD1B +%FFAF840C0C0B2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B0C0B347DFD1C +%FFAF0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E353434343534 +%3434353434343534343435343434350C84FD1EFF84590C340C340C342E34 +%0C342E340C340C340C3435A8FD1EFF592E0C342E340C342E340C342E340C +%342E340C342E340C0C340C340C340C340C340C340C340C340C340C340C34 +%0CAEFD1FFFA859590C2E0B0C0B0C0B0C0B0C0C343484A8FD1FFF830C0C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E340C3534340C3534340C +%3534340C3534340C3534340C3435FD23FFA8847D845983598484AFAFFD22 +%FF340C340C340C340C340C340C340C340C340C340C340C340C0C340C340C +%340C340C340C340C340C340C340C340C340C1259FD4EFF590B2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E343435343434353434343534 +%34343534343435343434353434A8FD4CFFA80C340C342E340C342E340C34 +%2E340C342E340C342E340C342E0C340C340C340C340C340C340C340C340C +%340C340C340C340C34A8FD4AFFAF0C2E0C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C343534340C3534340C3534340C3534340C3534340C +%3534340C350C59FD4AFF342E0C340C340C340C340C340C340C340C340C34 +%0C340C340C340C0C340C340C340C340C340C340C340C340C340C340C340C +%340C340C59FD48FF2E0C0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E353434343534343435343434353434343534343435343434 +%3534340C84FD46FF59342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E340C0C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340B84FD44FF590C0C340C2E0C340C2E0C340C2E0C340C2E0C34 +%0C2E0C340C2E0C340C2E340C3534340C3534340C3534340C3534340C3534 +%340C3534340C3534340C84FD42FF592E0C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C0C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340B84FD40FF590C0B2E0C2E0B2E0C2E +%0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E3434353434343534 +%34343534343435343434353434343534343435343434350C5FFD3EFF590C +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C59A8FD3AFFAF2E0C0C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C343534340C3534340C3534340C3534340C +%3534340C3534340C3534340C3534340C350C3584FD38FFA80C2E0C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C0C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C1259FD35FFA8590B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E35343434353434343534343435 +%3434343534343435343434353434343534343435FD0534AEFD32FF84350C +%342E340C342E340C342E340C342E340C342E340C342E340C342E340C342E +%340C342E340C0C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C59A8FD2EFFAE340C0C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534342E350C3459FD2BFFA8830C0C0C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C0C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C0C0C83A8FD26FFAF592E0B2E0C2E0B2E0C2E0B2E +%0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%0B2E34343534343435343434353434343534343435343434353434343534 +%343435343434353434343534352E340C3459AFFD22FF845F0C2E0C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E340C342E0C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C0C0B3559A8FD +%1CFF84832E0C0B340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E +%0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C343534340C3534340C +%3534340C3534340C3534340C3534340C3534340C3534340C3534340C3534 +%340C3534340C340C340C2E0C3559A8A8FD14FFAF835F342E0B340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C0C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C2E0C +%2E0B2E0B0C0B2E2E59598484A8A8FFAFFFA8FFA8AF84A87D5934340C0C0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E353434343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%34353434343534340C342E340C340C340C340C340C342E342E352E340C34 +%0C0C0C340C340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C0C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0B2E0C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E340C3534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C0C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E34343534343435 +%343434353434343534343435343434353434343534343435343434353434 +%3435343434353434343534352E340C340C342E340C342E340C342E340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C343534340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C0C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E3534343435 +%343434353434343534343435343434353434343534343435343434353434 +%34353434343534343435343434353434343534340C342E340C342E340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C0C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C2E0C +%340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E340C3534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C0C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C2E0B2E0C2E0B2E0C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E343435 +%343434353434343534343435343434353434343534343435343434353434 +%34353434343534343435343434353434343534343435343534340C340C34 +%2E340C342E340C342E340C342E340C342E340C342E340C342E340C342E34 +%0C342E340C342E340C342E340C342E340C342E340C342E340C342E340C34 +%2E340C342E0C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C +%2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C340C2E0C +%340C2E0C340C2E0C340C2E0C343534340C3534340C3534340C3534340C35 +%34340C3534340C3534340C3534340C3534340C3534340C3534340C353434 +%0C3534340C3534340C3534340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C340C340C340C340C34 +%0C340C340C340C340C340C340C340C340C340C340C0C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C340C340C340C +%340C340C340C340C340C340C340C340C340C340C340C340C2E0B2E0C2E0B +%2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C +%2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E0B2E0C2E +%%EndData + +endstream endobj 38 0 obj <>stream +%AI12_CompressedDataxܽז¸zZmr䜚nhڀ M60~l1a;XJJHiML#겡ojS$d=ZGdh> +[%!ӲCv|w6| e\'#8b Wh F!AmwNte ??&d%Q?J  X#cpHmW[|Oo <{j=KN"bFƏED&OդrZ0p5 ?S5Is)աF6 a f j3dr[[zĤplw`统CQ]4 (%@:<~۩^#9fVnd6v @-Wy~C !@ofiLo1Тw)=o8ysK.% xhsIs!Xgw1`)Lޫ_BrEc0bF @0+y]JOSykf8vJ V'/D; f E0zPPr"Tq?.lhߔ@L+H|7_ߓ0om tLg#"{=ڮ xE4> e +?nh\i ;w-1L&,1E1G9_.} >BZ{n_?򐗛xJI99vC،wd9O$<$\q`ݠ;G7y&|wonй!鸽t<\s26 h>p^L䁥 V wX7[ji 6G`xm@I΁C=Nh[0\5r&>p+D"M8J`B@boĹ5+88| vKVw-fZyܵ2m,Biٸ,"vt +DEzJMU +.IeejtWs0pmqɋk^" m8!@L9˄.@v2_ skdViuKDb3[7Cj + v_;w_m~yD"'_+aPsD<2p狐hOJ"P ;rF5Ͷ,=`E' yju~f<=Vz)5[W*ڤ`2W(bA +f V +Քy z_<؎GVY +|3arOdM跨,qx ߢq=Skޏ~M 6nr |* K$vr:yUf_g +Өۼ%0* NѰәI +?N @`s<͖=y_lۮᑄ?ԧ^͓bJ# +WN"v9:_ 77 $&?Y̜5?iu\vs^\w, _´wN mgu}]2ʙCkfN~`YopT@Nc.{@ޞw;`"BM+/6ʾL1qo(3qˮN(eZ>+nv[IE}ˆo ˎh>Zk@.WCY+xԺ:uC6Ro&gw7L~O㢞"9jE 0\KFiY]r*BvQD5jX`?j4tAOALz +*)e43NAC¯o0[:gq"KH7 <`ozkg/!k*ݸ9¯ck_w +')d-&%, R5e>Y*LjqhWa=VK~mïOtop'I:#J&Xj:Q Ua)asb&Wn%Z$MN@o 3S}N.\(zSQ0'ܙλδ+t4d-,fޖ ֤}s^&Na{LiIy!u*Hk~/XST'a4z3w+6G6l$.T ۜ.#ÔM?epb{$XUo2rXog',^oqI-"9S.9gΔץ9Ǿ,sH*m +Dߤ ̆Q0zbKƃߥ85}/G[Пr(U3#rJ{)_sK+Wrю|>aJü BQ wih9qN i5SQoSkߕNQ23 jÊ5~$u%S+aOŪMb|S0`]ЄY [?k]Y!#:D%]A4N*ED DD!B1C6\W%K练X_6lAu8>quj{.\@7s I/!6T-6u}H4Z"Nd73 HK=D2:R`}iw}$_ݩ@JvTbf#RyH}X |ٍя69%|#s!Uiy,Ȩh"N%dŏRuGU[ُ{hqTH?ԻdYKu*2bz2R5@ *EoP*ê8۫RFS}ݪ R:)UU}j;-UJ5l"Ch POCyj@QUMRֹcsq1ꪭMoNpjeVA M:])Tչ&KeD]oĪz SNYsuLƦ%5Әs *jT֭W} N}SoϬ_CqAiFm0xޠ!?2XP24u~&]ɰJ^1YTIbl5Tc1O5rb(Ɵ-R4.-Ƹ_=&mzo6t_jwޛb9ҔsiS]M-mi|h NvhT#s+-f\uК~j,:iqb%l~Y2lajKoPsY?e=ZvMkijf/hMX}Z\M֎e֘[OOfN~m^hew1tmRXcËmUج쪂+l6#Sܷ<·Ǿ}P!F]myp -kj3KwQA7C7b;"MܑѲ9#GjjvH8fVb0ٲN`PZ2mqɔyKڛV9Vw| 'p⇯u.}rk&Pٔ]8 Ub7Ɲ'Q.PÁBV?l z0 b`V$ Є46NeP:?ZA)4#vèA Spm>·qO?"X/&H#Î<%[$hM Y [t15E+ Vݕj1cլ=A'.| Hd&Y;Nz|ԇ@Nw(Nf964)[J%hy<RQ|&i_rH6[zН'һr3cEd̴H"0{{By66Y$hd=Vw6o@4فv\F2\F.sL46fyK'|kdxrV +QBm.4[Aa!ECP|~w) 8 ~W DRS0杯߲сtE2Uno2T̾ټf*]RY骭oYR,}f9縺OXGSݏmUjhS0kh#5:~{ M;k7ƨ]5Zon[p4T[t6;vl66 +-;SG˝.5&nMOV%̇77 ٲ<4^z_N'/y)ٲ댱L_Ek=1Oih *Ѡ]oƽ*9^L o8'q,c\X?&~PVu&ڈ4ch̓k-2(9YwzZ3IRԕۏi]3ӕUly"sW}|$Ʌo -bS)A[}w7Gjw™;9c]ۉ6zC@؎F-\| hU5?)4{OԳql :i2.fnt?.opWUFbF!(p2A.S"yGf:g^}f3$"8Q)+:ݏW;tmӃ0WG8;V}݈>X +.]՚<8  n;h\ƫh r<}XYknÊjo)CihB[Y^DxoqfϮp&=ЗƴAg$ݟV pJDy^ K5JhS0NhlivA<6-fN E/gX=}ir~L}E~t鱣=H>g[I#5U;ONM`gƞ!5wC֥3'+3q2E;xI~Z3ҜF@\h~$V?%JM0 uf_#đ :. ¡( );&Q"z%m<Kt˫Ros3 +:G7т!E&5/o[@REK0hgRBu9m: 1>PMtʻ/(f>">eМ=gpjF3g:60ph[fcрV¥  C[n7L)r0'Z_szj/38$v=K||L4rtAH=5xi.TǭKe#sImffBō:ԥg Bh2Ct8I`fY^0&9 | :gRѓ AA+9ʑD E4wZGUU8)MϳA"7tmTF 156>3#4lJ$iA ]zBSBR61,8( [0dtׇ3RUs.&28`ɺGIRy&WH=ϵA'`PAT٥a*ƄNuݩF9hRUs;ԭn!͑gu2jKq8Y'?}1`4>MYX_hf4ӿPdl+NL ~?2^w@-NiݗdeDhv&n:P5&[k2aD?7[>]5Uڷ<bҥ 7O%40lhD@`iyFg lar;#+7v¥C4QrdS8(sX 7h_RI(!SԛWoç -IJcM7]6 C _\Iت@|K7BT؝'p4P )=f-H-DAcP0TJ}= l JOXjҍahBnfM4ahί@# %H/85T|Dq_)PY0*ШN ie\4V+i졀7`e\,9$"XtH5l\`42F#%ȇw'žK=`= 9|Û(˼TcHȒ ]XU`-)J,PT,iy.k>f!Zew'z +.cy;).FDc:+DS`q(f,c06Q֡ ]fUdl’7 Tyvq-l򮅼_AgBML>E.K[t2*$X;L-~td|ʚM\ XPh8gVcPwEWէ^ʾF|IsUm-CƝZեQ rz"s4렖[Aǃu%QL!M0Hg{)3Nԙup눱/aN˜Ӷ9 6v'z)R,T Z}uKþ&5ٜ~fEcƥB^&piJ:Էjx P@MBpr(bÉ@X0ZpCmTszVTMx`PwY- ux +Nqi:/c.4 BʯdM#7Ѽ9=x3V!,thn")pJ+sY- +ۤh"`An]z>' IL#N#wzr}r7;0 Cy5?in4?0.(Z~.~`P-=oLSg(M%Kn5͙.**i2Ct3HO[i XSO|eƵQ`E1̙v k@;+D1`~'Sְozc)b|S2Ɔ]ݯL,E|nfs:70NkiV̰ R¸\5ZS4Oo4XCzpL;jn@S5I'ɧ5>X.4Hj?`&+lx݈?IV| Cj)AL{cޏl.fo|+7jIwyo5 Z X)cG@f&ح 5iz}-EڔB +5!dpfdroNĆj]|Tcf4`JZ:2n j1QEk_Krj,1A,miy.aFe"JY\a&Q&P/З2Z7l~Z[]۠:Dr?zEce?OY+=l BXR?Jv`a~{csL8X#$=Y,7匕ƴH=%{ůMOUzdZh2%VC0 d!t6޴bԀ yVZvoKD^Γ+(ZՌ:t1.J +[NGC0,K'XAc~\`P_}k[x B!NKMLs9%fqW.J:XLT68JA>hq]/626$a42!z|RV'YJ:Ӗ( 0u1WM\JnRq +e%nE rff~4 5}BmuR67^N۪0y^3-^`ӈ=w}s iRM`71s>W`4jOΎO j{5meQ[22f 5aAh#l2`zL4Cv-x{XC2'R2H"] RڸDMhee{%0/H b" έKs1`ŀ.T.!Ugp\k;Xm uw]oXdr@794AiL[/!a&=TI4HF[ٓm(~, }f|R}9W+B +Gsl'5czu`&TӃEOfEAw, xveLboTWcKjɌG uƘ*!4¼}[OV78v+& eHA;[`6n34 :ja0f +T' t6\uIٜ!" iOR$era@{V`q}~3~8ɧf#V&٨R +& +^(s_lmn/ p$ -us|Sxx{ r< L <RY!ťЌ5Kr.KJNm#nhE)՞O| +\T qec;jع Btes{knG[-ZbQ ߄:- 54ZN裦ىqM9jQȝ0' X8rP8 +vD",`y`JrOp|xq<^{oŞ;߁rݖ^d;餢Ka֚ V4fk\:E9mIx!~Xi&vlc.D xql A#_a[n&v>!~ _lo5Co+;W +'8ez7<N9 + mzڌo1Ǟ 9 w `%Y[$67fhۚ.1zOmE2yjo|yCq,{͕4A|\*+f(ٓ?- >MŚ@X9_o)̖aL@GF-GW(h0ĩ4ac[aq@hr[.l,ˍ,lbsUt`iC\4{6Y>Lpt)878}Z@ó¸zz^8^]y +b|#b[F7NqPmϺ?jGrxWowy;T]5nUr+hPAcU)ӎ.GBO'g Q?9fp@H$|`L.WG&mo΄$^iz~|XgdG]]'Aki ̩<=E{S9+Av=!Be1V>e~6| +6K#XѲGz +IPK/ݱOԕO*R{٧hnH \FF ˮR?ڰ!h뵰H"2v jmD F +x$WuXdO!rJOD;u)9f~Dࠚ~xF'^uGMv 4pQƜG%ԷJuҁ$C%MId{~cǎ{ԁ963U.9@a2G~g}633VjnB>9(+Y߷'bTJXb&@#@La@ZRkwAփRahb܀{ᒤb,UM_XÊbnJp^L$Yg[kGV"r2í"BՄJ!zY@y}#唙Ø$VϪ:Jao# +0wD֜{ۊc OGB4"%O?aE@&*ի4;dHBL(U!];MQY˩"UOճ.b'b5]Mm3|q vB%_`Y V ,-;4L32Q[^Qe 7 Y0eDA h'bh8XHk+$Ў/R9M[I=ZD;;WF";ݟ(nld:&] }x +:íTgIhKb]̺+ָ1tX߇űVF+qHbZX9ht+hFY≑b5_-:d>kb154 e{:\PX!j#b^ 髽?B%}o4!cI`U=up x6͡\گbat+Z(E` mI.LauڥoꯃgUXQVtc=;d5mf+,4ڥ~A Gho>jM>5S0&5iTDč6^qf噛κyZ܆U9~ĞB:$^f珡b>?-9I<+IMAqZ :Vѧʧ[kYj.ii^]DaC'%&M] H=VY)o/z9F.Jc{fO?~׮Mz. ޠmVӁD;g(:ጨ,>L)Q*!I):*׵c@*1$]ڮ:j=fv%p}@O`҆)57x>1c7Z7x]x)𑇓b2B Ԡ;B!0>>hd=j),j{ٿD9C@Nj"22Oΐr#5+i\UJ;C#McɊn.V/orX[ ++4rlpUY#5%{.VNg2"u75\" ։NfCvEgynDZė*+XiS!2t-FRXqY4(2RK0Nic #uyf63DT]UM(hGɴjQД< t䅖p?`w-sr{\v%m 7W R~Vql_C#VpUiO7/@4Mjn, 2zZ$\*RT@lzу,;$[scDǜ{g3P`GjID3iYwiIj\\E jR( iI)ƔhdI$O|{m$Ͱ@-'yMԨ}!,+W#be@%';ԟ˺\-=╟C#޲'93)F#hZDg/Iz&S'{h|,((4& ư3ѳ-c3/Qi &4,wk2Xz`gN?K܂и"0 Jf@HԬHeWy5e,=si+ m|Cowdb;bB`Fña6ʷB3+3]7Y%'}jQ-xzQrO"/;HKO6fwD8>ֺ^0_@*ʊ]QDCI0*0s϶$OFB3G d1)( Bޯ4&ҊB_ aGHB˲,5s\~|`QPzdL@9w(@t2EHbvols#Do`k4V?A_]#ѝBܴmũ5L夛XѴ_&:۫`f48oȣ;Rv=4 M @AviH@q]\ +_nPض3$np&N +JHqۅ'z#GM|[B\͚귭Y8,6 +/mKvʦU(q[hv6?-hH߰~V +/4t"Q +7B^AuA8]a~~ w߫{19za74P)r1X2`7\Eh^ֺO[g(\ZJZw5!) <azSriSڽ&[ͩ:7V~ Fsjoߒ^+ʔƒ'tCh +sEh$jߑ'!\̛asnIu +4MDSqT +R!Uu&/ɏHj/WjD~xE kx4- Mv #edr.'6 %PV˚t-344>2mb[||sr>IͼO9er>qZ7kΥϖqcOek.OIbjޤJ-瓯3||"xOOݓXb?k+D2M|z>7vUJSe96.@Mw#1 U yyl*Gbn,w%\ޤJn¸){ZBc:WQE0",hdOHh9C^Mh7YnxDC(%njo(w0fss4`Kp<98l| 3RW`a0హ'HARoi; tKIդ vBRLTwƂ]ezR*DO"S=a\wIZn+ϻ3#?zsK؝n]+E%ǵJ+&zCGׅ% wgrR pOGo`=0X͛ $eu@^e ,E0~* ֑[9:!ػC{+FR?Z7#@Ǟ/b|M$Bo`S{|ď>KsNDb|DNo.c6>DnZ/ؓ3<[ЉcO/@yQDe5Qy{8MPՓOV;bݦ:9z\|v@J)c 9]O6!uo5/^O2wdiT^D5N>؄Ҵ~Ĝ8t_q+ewNƍvި+h0Փ*,7:$R7mAٝaH\bX~2rWOGTEQ +מR4 VaAt%Qvg/Sa8Ia]1\UkݕTP/Jc՟X9muQe2D;X36ƟW }Ӆȓ)boʴsPS0OjjnVQBI/`Sŷ{bJp!ODYˎerH%h>&%yF]})lFˮEq^O1)蒹)qXU7qH=ܬx`^Ao%j oduWdkH%vSkuJ>T'EN~ګ +DF-٩,^V'67UI{>^wW!}TQg}b _Uw35}RJŅ}J/(G>WUɥ>X'NWY +}:W!՗Yo*_W'6k +ĪįC| +@=_Q'V<Ѥ~h D@]e O:}b>EΆT_V'V&}`ƣ}b%}bP~EaX Kql$E5OЧU# iRxI0;xI} + Ր{dQ߼X7׿MQ[ܲyT7n/o꩔Tg47/I&S~D9*9M6nݼWOWv $' .SW"MJfҗݓj"7"ݕ%Dr=a.{6ZtH! 4y$s:ߛ\Y GpͮX.,}^m W튊;n`jwɩa0ŷjIt;D~b- )q& kK[Qw4⚫@Q2 ޓ&7B0EĻr`[k֍LXRu +Em{%z]ii;6({qt/0G~B7;m"0dxyKI~` }`$.2n1'߬K?J[v/+'B%ӝ:,K e%-=|hm]*ŵC9UG3ER_ +W + sx'.< bs)jśg.Jϼ=_sɹB%PݺS酇7O^x(i\x(1&QNC9(-P|ᡢCa*Vק`q$~䤇/Tr!o^qYJId.< E'hP%{/<|\*LC _b6W)97)HyH4iFVmP= |)T!I` jmB4KzbzзfOe^$@w]qڜP3 aly~94ݙ?GR4IҥAT[bkעyYwsk%tݤI2!A8Օ94vQ EQՅ$hVjeN<ͣR#Lgt1G/8-Uf:!yԨJJ&fn4O,Q"Ș aQ7rfO7 +ҭ͒chN?6IiUR[kf f>^\LU?ct7AaEi*_U)v1,1(mXb郺ӝ&hJ=qr!>m*M"H hԠQu&{ ĩ}hk E{ |ޑS ɌjXZĂ*} da.]F=z zK6R_[5hU؃q+up ,'&Ư"~gP !AϋܮZ偉 ]Xڎ偍}@m"3UTXْ +f4~ƗV]o*vFIx*(Z;rޒ~uG n29"uEh8udMA(u + <#1U_/ƠfKxڲPOFoBF5~Թjj3;B;-i60ǍR^赋(Ү<5?Ə }:9 M~/L#G3構g17+̔t14z>2u 8³pN)dAu [J&+^%3,mޞ+q9p$t+}~D9@ꪮ]Ү`VXՂN k~LD.^l\j.0}އ&* +HR޸4KT85[~K~l3߫/5-7?M|H]u{zWc>32V ڋθU#Mfe ɬkPIvυ>46nYw+ +_i<,=I _lz> ~qwjhδj>ʃzdTQ-v6'aALtUT!}~`>&VGKk(Qb+x%2X e!]b~q%۴Ȃ,X8|3} /7a`.7=a4]8-O> +/׊+36=8uLv~iJ"jj}̮(顙2?qorBXv Ҵ-Uxia8h1RxN&Lpπe5֋_QѿMxVBMQjn *̵sQ3]F mAm ..g*N5?;$YH[,I%5}\4,%sk?'6͔Rҽ*,Ml53絝UyssFZ ȬMGLW Iw'h>'۞V-sVW2jv·FVklwZmgy2* =O:2*=N`10d2)dQqRD#C\R.pSz>1Z߼;Xˑ3#rn" 7T`3kZ썰zsXNm },A~^TYX +j[8IuS7T8H8\,9M_~W= >(Cg3iaJy6#%,&o_d&1&m<֧U4C5oG]~'zE1#q};xq/Kgbٵ0\8Ih,6F0#Jz ;B{ckZy3}?-ƟOaiAܗ36opXҌ4UJRs[? ;W +'/מNY`dvӻtAdܾV oKm4z! YiKZ?) 2dfFfG9n?ab8?'l2`<aZ OG\y:̏ǎ`A vZA0rZAf1wĵyd,KeY6qך9iHSFqsLUQ3l~apQzUG[RdM\'0 'Sq`M\eŸq)pזM+[u_V)v勋 wѧ{>Z +wgXΗ9B@56ȳk n.ЫqCӑ}XMIOk| o\YQz^͟Y?l8ĉxo*oz<2Oce?F#_fwNKkIZkM~唲6&Þݝ7GBHki3i<8pE`C:KwN BpmO_`:Vtȕ> +N2"ZGqaX`<XmU^M:_'3G \z +CxwDrj3$B^Ztr4/D cz0;-丙1}Zx!I}zNGS<60b-_0D>019ϹLE0FXaqM}n~GK͸)Z7Ӏ8/oFh0bLӁh'`isz4:zO;{<XDFtXNM4ܚ%~@ii3![M洴/%]7JIU$ 1b;@%"-JZLiBL+)i(W~ ;Փ\Q_BMݯZO/ifRS)4K0Ijx嵕*׵pnTdrfr7qZxyS +b}#q8kQE/Y?תiI4'wՔpf)C;rǙ&gn'wq;iO3Q*q&?QB;W7Ov3quI3yz'-+RU-j:7&3wIon]ag7qfvrfCr(. /MCbOÛtJH&|\ギI7MSt>$5yLQTNjwwEheTn6PicbkL`l\Y2g@sW-B>SԒTjQe˙5)_ڨj kVWǛ)Xb\ y2I*Rl'b}Sh4nB4:c +LY9#obrg*̠&, qU,q?#R|[VQ*Ɛh##qfR_Xi,Fu >vytjY.lr}UI{;fqikKWC;j.sn5C2{lf'9˩Җ(?_VQzRm"l܁{|,9ƭXJ)N^ sIxH#s4 'qW>; j!UW O jp>kakE+i6V;@yɼ`D WG +ǎU(UU(UZRp*?@ l +*$[G(ZRiaU(ǗVT6ZcMp*|gj>JUD.`j>JUD>3VQ"bVqSG +Mj>JU*|JUF\Ez\yFCѲqD 6+ h(g@4h$ -  %BlO3 h׭FOk4vL0Ps 5&LJ?hۇ? ?PM󊆆N5:s=X4tl}|DC†& fPG ZSᢡf]H4t;yh(u 3GC"2YpPi΀B~t!>+C}^Йth(u  qD+iKqPיv[@46 +.$JßBW}z2t4[rnPWD 5ßhrЈ;˯[8h4b +& EG; h(]H447 hh .$ +x?GC1wc73 å>Onm$ +?5#JD=** +P.qt$]|M;N7k$[ox?zHMbotDCw?B|:1D($ɚ$BGyQ>jUSE0T"fA#W2TI" "QTRd˚(ּ,jE H/چo/p({ѿM!?S@<z=N>&y D!* Pbc(LC(Db"~|T#D(2,EDdDr  TG"Q ]u]UFR.!e9Cu&3p@C +l@ Awৡ(k\hAM/!^@y/Q7썷uxn+N&Sy{| ډh=~7w;i?>ڙL}xk[m  6@g2%}pt[N47;OܭV3ގZVzT 4+t?= rw ?bjްw`ېV)mh +8@ʙTG%3w'x/'P[NY5Q$<4AU]QAIhDQ EV@û 2^q.ec<(;AN$ Ty):pЂ.h @u֊Z$3ʺoAECR4ЉTq F&I,sEE蒬k0"I4 * eC@Kz# J8\j%̃P!U@U'> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 24 0 obj [23 0 R] endobj 39 0 obj <> endobj xref +0 40 +0000000004 65535 f +0000000016 00000 n +0000000159 00000 n +0000016230 00000 n +0000000000 00000 f +0000079544 00000 n +0000000000 00000 f +0000016281 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000079614 00000 n +0000079645 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000017994 00000 n +0000079730 00000 n +0000016661 00000 n +0000020978 00000 n +0000018294 00000 n +0000018181 00000 n +0000017017 00000 n +0000017432 00000 n +0000017480 00000 n +0000018065 00000 n +0000018096 00000 n +0000018329 00000 n +0000021052 00000 n +0000021226 00000 n +0000022408 00000 n +0000051733 00000 n +0000079755 00000 n +trailer +<<2C66DD5D17BF7D4B850A0645ADD4AB01>]>> +startxref +79947 +%%EOF diff --git a/misc/branding/icon_light.png b/misc/branding/icon_light.png new file mode 100644 index 00000000..f2ef77b9 Binary files /dev/null and b/misc/branding/icon_light.png differ diff --git a/misc/branding/icon_transparent.png b/misc/branding/icon_transparent.png new file mode 100644 index 00000000..c1108d31 Binary files /dev/null and b/misc/branding/icon_transparent.png differ diff --git a/misc/branding/conreq_logo.png b/misc/branding/logo.png similarity index 100% rename from misc/branding/conreq_logo.png rename to misc/branding/logo.png diff --git a/misc/branding/conreq_logo.psd b/misc/branding/logo.psd similarity index 100% rename from misc/branding/conreq_logo.psd rename to misc/branding/logo.psd diff --git a/misc/branding/conreq_logo_dark.png b/misc/branding/logo_dark.png similarity index 100% rename from misc/branding/conreq_logo_dark.png rename to misc/branding/logo_dark.png diff --git a/misc/branding/conreq_logo_dark.psd b/misc/branding/logo_dark.psd similarity index 100% rename from misc/branding/conreq_logo_dark.psd rename to misc/branding/logo_dark.psd diff --git a/misc/branding/no_bg_dark.ai b/misc/branding/no_bg_dark.ai deleted file mode 100644 index 60cc5b83..00000000 --- a/misc/branding/no_bg_dark.ai +++ /dev/null @@ -1,1823 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_dark_nobkgd - - - 2021-03-19T18:08:58-07:00 - 2021-03-19T18:08:58-07:00 - 2021-03-19T18:08:58-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 240 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADwAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUDquuaPpMPraneRWkfYyuFLf6q9W+jFry5oYxciAwTWPz18r2hZNOgn1GQdHp6ER/2Tgv/ AMJhp1eXtnFH6QZfZ+Pkw3Uvz2813BIsre2sk/ZPFpXH+yc8f+Fxp1+TtnKfpADGr38xvPF5X1ta uVr19FhB/wAmgmGnDnr88ucj933JPPq+q3BrcXs8x8ZJXb27k4uPLLI8yUJiwdiqLg1fVbc1t72e E+Mcrr7diMWccshyJTiy/MbzxZ09HWrlqdPWYT/8nQ+NORDX548pH7/vZLpv57ea7cgXtvbXqftH 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 wO0xYYYxUQAjsWx2KuxV2KuxV2KuxV2Kv//Z - - - - uuid:0e0d882c-62d2-1743-9766-dc652525d276 - xmp.did:a23008e7-0043-4a74-a11f-80cbd79fb7bd - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:a23008e7-0043-4a74-a11f-80cbd79fb7bd - 2021-03-18T19:53:38-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 29 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HLTKn[1 cHmݢ(~M4:T3Hp\"s=GNe&q=d}2)1ONZsOȔu@/ҡW(J%o(IXI5- V7zfTg.\%Qӝ-cņf)e%[^I#tH>u|z&Gl{z'D>[X  fJR~"NsG8a_Dnָq//kZ_2>=k/ 7 endstream endobj 29 0 obj <>stream -8;WR1gC;(D%%H2O`@ta#+gTD`&:$=lQ-*!i\s?h-bjQ?2e.udglXYMo8&HHh`nrp( -E2(KEe=hhNF@'3Ibs:*O*(dh' -@q!N6DeIHk]9D,.A`!%3KBFj\3]_Hm06J,g"DLB2'$S;sU_dqP7.L)_l?<55?f5/~> endstream endobj 30 0 obj [/Indexed/DeviceRGB 255 31 0 R] endobj 31 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 24 0 obj <> endobj 32 0 obj [/View/Design] endobj 33 0 obj <>>> endobj 28 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_dark_nobkgd.ai) %%CreationDate: 3/19/21 6:08 PM %%Canvassize: 16383 %%BoundingBox: 19 -292 281 -12 %%HiResBoundingBox: 19.2149374131423 -291.827751196171 280.416267942584 -12.1114906146768 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -86.7846889952161 -6.78947368420995 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/X^D -m* mm[QΜ&" -FRfRj0A  --L0F^M+J]>i *. rXGWcLګ*,2 iUSL<2ԞL&" ϡ!G]ӏ[KHgu U[Ո~R3_?44l:3ƥIRW/\W7[I1ѡRPMרg4=T;Y]+T χW "" DA .0ZJ[ݝWS:543ѢC&Tk7 - QjFZDIk׃X2{Ji'jRvGuouȔ&!Uz5je,2Z2!c`@pB15!&L`áP`Qk!qx A \aa ,pAf P$H4880@D`&xHع28F2EC  -H4͓Y?ta;2UmYPO$_nUٜ/hEMZi*YܓzF5Q=]ʬ%rTNmTϪg*qӸj-<*U㝼sMVv򤕉i{&f뜞Dx4mxotN[Tʹc=seW,ynKvs)BSS{x5bTc5}mRѻ&:զp+*m%|^~kGjsl'RkYDzԫTݭq_xX܃t'"anq*TY#ߦt$ꏎzxy2g?oʠWIdGSOުSzòJ/:ڔdTGGT1x:7J[Z$]YoBy`nwhUQߣwx|ݞRP3g3Ϸ&D2|%Qso~nev=XUHM֞uʬhSvs31"ɺyݦV%1KZj{g;weLX7͵m>7}VjKx\6i٭~?*;W7gXDJ'LkQ(Olm:eeSo<ۺQ+FVJP0P(`,f_$sj[VG]'lޡ>۷T\mJ*앬PNwkRϮ2 -0VxmPKPsM/\ڸHAIu},(ZV -lj-n9LgT&õ[PP6XXHxx0`P&0 `px Q `A8,((@fAd`&! T, `̄܂B`A4@ahAў̟Z>7z6w[  0DLBa&բ 薺wR -50nRVAIIf>>bf@!W*hQLQG !!_4U%wi«R{zaҡh'%VH#$uid4PqxΌmAsQlI̲x[*qhY[˃m[J52J}K2w/R$ ]uT)NOɮjYeKw{FT3R@ mY"A ImʌBA;D -jSPR2 q<*CF~[hG&%#ZhE:\.q[e+[eP,Uf$%mbUue;V>/&Օqd[&hI3^gm푡^Qȴ&J(D$IⒼRnUUkT̞exwZy?̻K-3omJ':((~`r"Qr Y5(xuEQQ+颠%:kˁEKUT,כV L R3QcIm6M -&@ z8tZ#3HzŒ# -`l2?&mo͸dek=%apA A -;BS4#,.1,kihK`YEdвrTQEGq$*#fN 8=ё(sQBT3AS&p僆G,¬54Lˉ[Zgx6g@ezv -%0̀ -جkiJ<٢6Tq맿.Mv+\G)m-<|Т˖HqoJ3=vvmӊl:eoյf3}f'צ.y{?HuYkSmTIye꺘>.DZέTM*kլDugXS%U{ng -6K=EKtv}Ž]ډ5ksth]tTYuzj\ױȾuWZwTm[_頺tOmھW:yGyjڥ(f._g%2=X-Ec)~vƵ[G\Z);?Mdܻ_.[~GkIF-VkRvKƽ[pτ9=hĽX=soGשhG:6{>^s1>:{&Gv6<>'y=O+ t|½;y.Rݥ)O6pn ͊k1{UTK<>v.:+E#V1[5z ֕V".!屙sY+ˉhK"'%V2T=3mүT&1Nޖڭ׺gCtc|R5MOΥ:hs\TY\}FZjE=g(rɦH?^ܣ5x]WoTm=ޫleZ+~!O;m׽Kf|녈^2ړsQW&G;Ֆ?J/V>vJJ|Nwtߢ%e -]2T]}yUW˯:S:#pPyy^qj/:'$Thέ)-cט,O)u15Dky- ٘UmohNWq=L<75:=7Rz4K 5sZiYv־hygח:*t:c4'JF-UמK4c5-=Պdh,IM]{G]14K{|uh=F2-k#]ijxlXu_CXxxuƣUڶdSiRۢٚ|<ۗo)6'mH.sFR!k2=TjoVZ2""" DPu?e{vyLiwl 7}rsѨ7>l5}<}YDʬ%CB[Esy7mik_fTǰhKmYgcXs\ճULPl[kyEkJEE;4C۪oyzx5֒f[S罫vֶ}^< wiūK'VfCVhgϫlDrfx;ZgyC .C.[w^R0ou^,M7&k<+bB`o'>#շۥӏU\icVUeghVXu{k:Xe#5)Y^w>%-KƴR5>}NxL'RPl3]*-~)"^P(?*YMy^ghLg;R=[&1*ۺu^rݝzKtDWxu-UVU!꺬ji?W5s*/w&Uj+ 龵U*mAdU5~N.lýJ"/OTz[=Mn}Ke[ךRڕW{UJgej{\f\oh{B+ibZ?ˢ3.{Tdw׳gtf1N)m]/( TzEzU+;/XMtBį_]oNc&ՂB9gw[MU6WFջTFsx-j!U{v[Uxk*-kEC5znfz+{%ӞlV.*o*SO2-Qͼݩޑ~DFgetƬ]c{t0liF}\:W7au4kU tU|_Vޥֱ:n .-al}[CWﳥB-OWʿ4{(4Mi-f)S{Nw`lhuK#YfJT>$c_nIkxZD3}Ym&+1ДݷeI)R?-:vekiWESWƐH}k˽ӧY<7-9]dfws&ԵZݪn[sϴSIy#2I&]ޠlU@)|V0]:x1K;5׹M#Y.]LvS|q_uEfwN:7fVK=Kfe{?K{>eS6\Yj[yjL(Ϯ|j]OkZTWsMKsGՓ~uSO.D4,."h1"jf1dAL&30(Eyh~j@jH0$x$C@d$P ?u濽? ly?B wORe  msld>U5cGE5_Wh]g&I4O/OOg#'노b*J@3_;?æ?(BSiq{J벴 -O)r }3%`qw%՛nFnEGf~]ibR0Fw/SJ" -_Q,&tI[FѬH`QˠksUrɨ~/ 5ĭ[ԝ2#7E!VWU9oX0} -*3O/;j=~_>*JxG=bXjߠ񎹦;9jߥux" -"j&X"4XoXH1_E%x7 -/u0_`HBR~,P+s[}$* zՇS0 UcS|Bq€tG<`tjẂUV9(\g$"*LB*bᅴ7RuB :=njrsuGLTBZ )"<~?n T?L{jѓ3G͋TD|10t?bfDF 1m?V:3|v$ <% -M[~r+J$3Ʊ!->li],:;3ek >xը՘zE3a,ʮmS5TQWpAFG^[/VEiqH3-ge&t((T'L4_3ӹ^H?\'/LζflrQ!^3ђS3s284[hJy=rDsEcW@2rCZsW4X@fNTke_9thŤ+4 1._M`bAcɕ)hn2=ڮ7ҩEBe/$,V=ȏ!yQ~1S;`2\P>~;1Gȩٌ[.V\Mdh 04yt>:ff7ӷLN)F!uF -W09%M3_̂e~M"zXk󪬖Qe'xUWY . - dR\+;" o|W6/;ث S +L -W{<֘frIѓQ9$@1oKb#L r -WyrZ^"ɖt -|\E*+W%5XpzU4(58xJUA*USWg%Ѥbҋ␒䄊(H֞+xn]j (&N;WKŪLqQڤʼn1m{jd}܉XqU2-"KbG~v dU駫{ɇgg:H OܩoZ R Ԥ6 8"T;2)'!&FrZ ]]ٌu/)> -[gU^C2J] qBM{Az:T`>j|3Iؾ{鹼p`~B˓X>fF) - <j'Zh -@CwʺZ" H>jhw|9)w#7Ղm֖*y}*ɞ%c e9ZN:P -Xntge g2n - -Ü@%2YoYY83%jggPBjm?Th.cև?keqVcm1n|ōgCQk1[̯6PY;퇭 "Lcb&r f*ٿeIޘ7 -VkŤw[d( eїKFjמi"V#BbSi TTV.PG`1::*/mmQf]>0X rnc :c X swWHjIigZOj+_o8<&(\uIYjZ&yNZ]e/TL-$kUտ\/]g^Y<=WWcB(֙ v6/8vR+]C']O`_,gyV'5wM]$©}|Z8FI[wNZ[FhϵӞ2uV-t䊰j/4I~UWh4]_-wбN~~h'`u (fO3/ OCaRjf.M!t>3#,[o ?_v.o5&}[@׷v՚LSf}Q[,ւKZGr-hsVf.G&x rWYk?7Gc.B]l$ \5͹t-pcڟS|n&|̪iAE2j8Q5e^Oє\oqF[P8~+wY}7i5`CΈ3+Y[8ܶ栵Rr48~ -;vAе"C :ɀpZ {7RuCF#EcyU=Je@Ivj6d3k-E76MD!, X -úl6SJ -PQx`7V@ԝ`$ADr =7SXD>muħ4S#*)mYw,uࡋIrJ%G(ڏnpG93Ӭ^$'Y boƢQD5Er1+;SRo4O ''#6!_8VbB+mgH>эߞŁDQTaE #@2fﳰE_pA:1ifoaDA=e`}D|O6dhV SXjwG𗌽HOPoD΄gܣHod=W?=(ai߼l3OJzNj Y+8@&܄~-{BY,9fݹf AQ {B}{@1A:ЕfZ?ۻ^Q`lҢ6I -B5$X˫d$V&7 SC(uHZeK;<> Ef5+A -d.ni{xػJL»+MS_q -7JMʃ;n|XMV -784rP跖 }a6 P/ك?ÂZJi/\&ɞ.AXiڄl0S\+>ω[UkSj >'C }q]{Fw^5һ_JmP^ -6zMr5Nn\& 30όQgvOƒb#"N%;!#LL (o' ysм1wR͞!"Ad*Spʕou' L| >574MS$IښSQ(>B_gL1@*rD̀EH-zeI]IA;`*!9Կ C@1DrKhR%C/InT]kEOHлZXg#\xz`3+Vj1XƊӐ}Ġ5c #+R %Z-.OhWw2>:HF ~`YR@y@yIq$" B \Y`$SpK&PT1,KG? |Ox%6*}]pHA,?l*] p VW/{(>=gR%' Mf3*&:ЪyCHi!?s-O70d;j 21fiΩVFw) Q$9GG2CT#ҩJMlLe*[g-k655n,%N&M1v,/S^d "ٿSZʀu[ Mm$RL^Tt9'FP:–-53W !Yzڋ-k*n oCncEyX1a 4(ZڴɳyouЦV?dFLDv^UKڷ -8N AXq>r+Q CIBkBÂu+qYPVA ۮIg^@kjҀO&tGH=JY%dfȈ%pf\/!@56~r24*EI5ٞ^UR"P…{07U<ȺKAJ+f2'g~daQ,Oܖ Qav<;tt){fM!hiآ"X -` oYf*gXSLW&iG$D(tLTsm# M\kDe~]O?q ˙ΚF=*UJ5=rS}V,.m^(PːvP]H`^JS~1]x}{&E9?;8`#O -lANXoKL쒌FTws0$I/Y@9;:3 Е\X{ _|%!ck/0eDoyJH!F"8-M"('hP# ,]vbu>h&^ iw7>y֮ l *Ǵ=Rc"RZߩ~鿟ϟ?Øwʐ пa/gWL? Hse # _k#=s!QiG4 & -aqҧ4Q;dBY%k^G€zwWq& - -|cB>Z!\Uz>uR?2砢WG.rn~Sk l4=2 BCgčn!916z+(j3yvxhvEHu 'y>]ϣÂƥE-0 9n@ B  '2b\ -I:eDn8攅3U-dgad.~. -01Ý <=k -iw@KVDP%"5%ZJ0#ewcI$ `zQj#[O]t>D[ZLl8etc,jSTb6U uRaO:ճz"I1:k0ǛG -ߛ!lZn A)S;}v%? -;>g+;d P5y${U4k2mY)C,0>k$d]ԨWc)nRCLxn97JPmO+XKn1`qsHh~<& KJ^&M+a{i+ngt`E!g,ܾhW/m_vU(OS>: QZe%ȉKlǥP]l;OJ[:i+gO*(ъ4L2I2qsڔ`fzWâlD. ,M+eA>q܌u[A̯{R&b /+oU#߯gn_ |Fy. ~pK]rn!oq񁽖GVH ^7"uGF1}蔧V}Sd DV6.z;q]8&4imSJw~<[E|ܰ}X:W}/HO\ ]U?v{o=r+U?tytYL=^h0Gc[_HWr|QcXm##_!Ww`kb|}1~s`) Ur;u2Vt@#;Bs҉9]!hE_C9Wb΋rqfsR$8 @qNׯ.N5aUq&3†cm8 H񏔲h1b r$d{i]68/#AdJV3fA̧z9CtKAn:?rnkvā \tW -Ȼ*$7aDTc?c`bs>*@+? -hteiiW{)殢>"~ ,JN*aM##W!Fz D̂pES=?EGV 0JH aP /s -04.C*&q.yO _q4jR/T8F*b8FF|J=:n{)tLjzrws uMW=n^eeΨ1G^?0ON jQ9擈7.i+sTKn>.ےdh;ɭ(B؆äԑUcvF+P?߰%8s6O+FyW!pT^$t- UO}'rB:U=&TVcI[GIo" ;JMV( -}ļrvAAOϠ(0,}£RRV*-ݽ<"M%zf!iRs%{_JndB uQP;Ǭj;nY_j$}t}G2o _—hܪn?:c/68m"$й:ӌm.Dч#e@ Wٲ Z(6}g=nyϹKd/B_nq ~&~=-o -/U}9@ڥhmBC_(WR:[Bjf{TROSϭDCOgt}z+ƽosc?Lj^7(j6Z?ߓT?,M.R/_AN#~faTf s!Օ/VoDŽ0 -B4n4Þ{qVrb@BQN]4A++E޼E7t+>ᬓ/}flCLULbh}^ pxzW}Ofrr VT(fmyfVNO{,^xԥ1V=P:kz"鑯еۦ^ ӧ{zn xA#A;0y)1fafzH۞^V7-;PDo𫊨Dn>ΝrΚ'y[!$>kMF=Q0QDŽީl幥<<`&gU A!%%aRP" א`*b䉘dl9LjݷୖKfiԩ]&J)*3J)\`N6۵hGBᔯ0P(SF%ًtm2ZY1Q\xK@LُX:{;ɷ#}S766=;8F:ļ5?o3aY| -3DAtX]f ͺgiHW5R%T7;o O{l?6ߣMJH:(a&oVe'`Hϱ/FxRYF\|i :hl#G}L;z_ (+]½j"x -A|JxFbhr*Ju2O'h"*[4vE ݄Wp7tp=b0wX7a_ж],M8dwA=qm1E-gӸrˤo}BVt벙3guБhXMdf. Di?FmKԈUϨ5`=@Pn?uWP0"4q ws1Lb4D/tU Fim(AwhjPyKPЅc.B8Jb1D꞊ޮϽU[')5fpD~(NEo`W'nr67B,j9|I9}Etn)՞IMo]]ؚLkc=Vp d"D. dY,a;xEDO0 `P6rēAT D"ʈu -DBq@\mħ9erYhp9 -?VS|D&WQpEP0_"r"Œwֈ.O& -̞̘#\Ϭ[$G{@ - %`$.+:@8t]D_jsf^Nx2OfuuRXhG -1aI`㷂F29bc{K?KWRs;sGt idzC&)`זRN?_ŏԷ:Ryr86Xt-Vrǣ7_%UaZI .D4BJ+Hk.k#Sjźxy+Z+9u$бkŻ?q;NhsHb9Ch^In" a"F4anܷI*4V*d4nx9Xɇ^|$Lh0W3Ĥ]fKAنfJ[.;{g2e>Zܸ PqGhvbC=ٛmptr*|@Uf]F/ JO +gȳ}ZrFA'W1d,XxO5.`̕AѾ4 -t^hڔ堏+ط>!W:Q4 -|ԌE,wY."A_$2-b CZБ&ETmu2`пf3rFtY:wZ7, nUI -TSV%n-VHťa+/d}]=nt Ѿθ W]l(<;06&{Ӭ+~dsN#e+(3;JzjXg -zfs[1n}s읍R&EgYQrdmW -=OG^m7iaJtkA$M*t"RErG%*H;x@! `Q0̔#z e򊰃Լ&bfmWi{єh[{.>a{ەї5s58`!,/7Yx~[ONSH@ 4K8%S;[On:P$Kq)4,[:d|AraBpƁ7Mi3ߋ_. |@ŭM{u|!MJAxC1P N\!J ?C Xh4ߞsX9Gy"̥?iEB(-jEcq(mIhf1 G8hUWd+Ӣwq[(b Ϣ~& KS5  -m79IL{ -M\h9 ]4(̵k܈ol -˻C-X8+:\ɄQCB& TG"ڨP7l+H*U*uۚ@S̔Xs)n]@Kh&#D"$m=v]0BS{ -f#ԢV6 -` (:F.vC\>Q5Ekb," m5F' ߡF/$/aN]nD}nBl~9f5d>cJ0| li5$hhl3-7c9X'O3}`7 Xe"Se|$S,x?;yʥ nIXg’߼;/xJ *" C`)iGe )FbXljžgV1'ƉED:lwCqמkl* p"l(E4<26`@ao\.CӴf vȆM /2d[lG NnK^;,&%F-Q)kJ&JCIߑ%/4[Vxr[lّ5) e -A -u; KeەJѕ<+@ MG頞W^Wpv - lQHXxM$Lcy1"3@)QjFx u6u,c֊wq#Iu[$q5?[MvLf胍aiLS0Mf -ֿfqƝP*TcΨ, >c=3wO<͑3odS̡R ^FD_}S4iG-AIp~2aId)]A()8cY`@^ -ޤOF3cW 4y=ج `0򙗭J*1sI]U7z*}\ݰ -" 3+sL$Je}yf-$M~X_j=t߀$vĜc9z5㼥ـ`hY98,0'D˜o״F1,_2KJQЯX'=`ysE@ #W@)eK2On-+k.ōDMs :#]TmZ%&x?B>Q`jE\#;Z\9?wBnLzLØ,ixa 0p1&]>a+|]PI6AREpG&-tGJ"J.DSrB=D-pR!e,|p3\~0iW4~ZfGR;?T!;h[ k![ L$ "OXMmq#i`bF/F!\6/}Idxx.$*.VHpr~8Wا-̱jkbl|'rA*O2P$1,]-Y$i\@ia[U~206h{r NqI )8,]g=wLNJDe!@2 63 ]:/6pੑYS?+\m/b$2F -_B5WX duݠp-OӻU 'ki\ob p='=bkhXAr*3JB_: CMyAmwlel%1U26D)z39m& 41}̌2+ r1:Ro,b̑Hfjď,n -K$]kg;-J΂!8.Ġ'b0t˖6] -FI^Z$P'm^{tH*IڿN#_U0__Pac]õDo(Lp)0 0jN}>W>$]m .qDYǯ€|2{Di$Ytj~,t#d2\I -r8`dQ*@*& DfW{ٙ50p=4@c̮X{Gc5:RW5kڂ9Hi CA$i9س,<;B0/c2E|%R(+K}Il/Ч&swsMnh4OAb8LzW Lb:#zTՀ3(HPdO`QՕ.6Q=RL)]D0hroi!l(&1L*B).6l(Ql b $H'M] O;%( O g g/WZ]~by%#-aQY$cvl$?;BDcǔ/z n:Ì]qN$ؕp!2WGH@Q&( -0 J㳣w0ĦD#.ҫOZH%Br9C"/%|0W%i9$+^ bZ.j%2 oDO׀(ek&d(&>9(Sb?yO_f9L.! 'B #,xRϚ~Ѡ,\Tv<j( -f˻[/i12fm^({> (b]!>$!+`o ^%I9uaHݥ\srPCChV.IL)wqpc!q>SF1pQD;O֭G܅ a NAxn(x̥Xu0^H.<5ܟx6o,adxanF|6KK ]w -ApC@L}̘(p@E>yMܔb|H&}˹hiY$d2VN))ҎL?yG0=R?SJ?qdp^NcAݸ%ȭUnj֢[3 bEMENU2JaI|s-9IJخbKLyiM~YV~.PX Əc)kIHD|M0)ҖP/)TxAS=hšoPCCwq5 P "LaMAz2P/PSP'8.G XAkߘNQtC#oҬ5{xT&~_h29(c[qB*"nF\l{Vw| ޫmVuX3'X\|2N9 -ru$HMү!kcB& z,pxbȬħ81'rN@d .ΞI<\K9؄PKnsFQPV)5x8H< EN)t|JFx(yg:P0o&Ǘ\0p&ٌ@ax wLR^ l` -nWuEiߣHԴtg(pk`YIg91>9sK7!{KZWg;0}✅[%rRb*{;fd7!LA=Z"ñHHšuu_&߮^b8KKJc,}̣Z[1K߫L fN&P1q&k]9?Dް`DAfF2+ $ -wRYP<+,yg(4OJnAK<1r|U}5lUХPkaDPDӦ~H:XY~bq@=lEHC~$tL`40@F -v)d^3@G8Rݴb3VsCeә~0ǬIۗ^eNDu!wAFkmT ԥ)IRJ$"*G>{9/IG5iy!hmy:BIM8 ]5^xV(=< -PI8?DԊ[1GLD&N,OCj -)YRͪV%!~Ƒq\Bcd覎Tێ 2Z -5fblE­h ;~lR\4l.4 -V3$a%LDQ1TĜy 14(cQGW';x[%x噊U?PEeO$N W3^Uկ}yUM $K: -~#UQ=ZHD|DD3cFL/S1~F<(I8EUQ{e9lǹjTflV3ϫRaeZn|JU5lr9DZCKq9Bbf\LN]2 -!$DC`l)U|X/ -/yKXpUJLL / m RtÆ6-Z鵥|Uj0wL/Dwp ->3UD￧l#Nly}tS埪pcSƧjO5rHL"s{؇vxU[lj@*Lqr +\byx%aqr0!~XS(HѩJRɐӤkr!ޛʬ3}NWR&YQƄG^"ϔBg -"\J )ȉDwhH&j,[Ņ+qN,cKYՈI"IغdjQɰ,05 -i(B!EZWKjý BO|^XݩѴ8yo"Eu(D6eH:"}:E+d*YM -(DT$[6c r@?fB{DT:f8y7L'bnqM -媂U  )ŲP.ƐLG">H~+uS'm6%36q:i`T!;cm*>i`ڇKap;v o.FNw>Qᡧ-J]ƞxz`UY_n -$+L'kP\+*pn?!3C6'z|(Ns򵩱̋\S}jk5cW?|3?B}y<ޜQ$vP"ř@Tlf? eCȦCc! Q%v|yJV,SY<2oLzՐ+AyZRO7"\lTA$CBlBؗJf"¸_ M,"L(hb>s9k_ (0r5nR{dںNgЭ^, ->ܜ q$r!'F_}RX+Č3s֓ DFߡKFL|2wQ9brΉkf2 -9h (v٧hCy)5kqG-FPݼJ |+q1Ng!A#=Lx=:>j 2cƃ.hso"jsw{C""Ib[!E1E*P)8hG6UW({Py_HUS@!<xE$åqT2 k#ȔLR"Ę6eT?剭' -ThšD~RdH5y-W"CU(Gd)uB-Jb -zcL8Ac:`~?!x<^jdG4UR%*B3V&Dj g)j_ugKg/mB]K s`MkL8,I:o2xHYn;AW`>Q4WI\F+첟f?c}~Uȳ|Ds HiSWkIX4$|$.f߄)u+D@b74;Ȍa#֊s Ryy.x'tO\faY␣$_,K2+VLIcҖjo`GBy-M@ʥ*[JM9JgS -+IٰBGVd-n|ګpk62)ܑɸ1+W+f}Z\M 9&\VB3'2],2U寐1 499cDq.TsCU?hNRwtzipC.TUKZcσ0w^D!,ٔ\:9 rաbX6;բijMt6v^ 5,ƺ-i`E;("$0߄:}݃~%2):j&7O{1roʴhejnj# |1#jy0ؙs1["bBN9B8gdC]wBfiRIJ0F0=`=S86J>F~6WѼbj쩹=Sjfu%9enU-ݼW%&FC/JPic"Gp2H$7mh>ZZ%N%uQH7+4QIXLߠoVOQK1whYzIHSsBKEy%lFH;$- ѣʻ( lТqBKݒř(]-|SF LV57)G8)}sY QOUWMZD լFF4i!ZB Ɛ吩(]QJPp* ^[oJKZ$q|FKN(XZHMʣjIŅ( Z|eh[EG"s2w̩kAna4n g¤-`EZ}( orRiD}ek*rɯ{MVm]-qC32`WRIPe* jU#Xq8$~$g^"JBNHu[h¤*~tj1R$flHRssLH/od4VI6uB*rڊ*(4y elXꦸ!ē'"5һ[FVv* !Mrvĸ1\ -RMHDmE**ԥӘSrkOIʼ>RCJFuZ,lCHj/ -yКF<4j.2FȢ\';fPA)ѝgKT2ݨ -$N% Ȅid8;̇ze/Hܑh&2r"9#k,xZR=6}+Pcu'`ag,IIhJ#_:XfzG! -Ea9ʇU'P:1YTE#$ҁàqY4Qv0fP#:T1< V k AE4ãItpZT_њ h KU#s!"EN> & r. -L}F경!E0CVQ * -A`lrȴ`JDH]m`f -buz`Ԩ:%)Wm:MU"eHx|(ZHYE)ęNШ"=`) %'65vK`$/O$Y[蔉z0ɗDRrB! .Z9« $eyUM.!7$AqK4RCSU4ȱpOi$PDаCQHI<9jE)m؆Cah/QBg?N+2&<ohkqCTDoQI,$%vQjw_">Gl*973vޔ23gb8Js<#Y5Bb -4qJ84-ay0.fD(ʃe+-j|sx) -"z=)M=zȅbe\".D xgoAkUr6࿐a)SLI sG2MdHQߪ'I j9$VQ\2O2/*.,\NI{ZiqY;,~<bٟ L+ ]zVIJUe& SMl\c;+3Tt̺kDBgd٬pĪ\e&*X"|g[Euxe\!BhEb,L_6R\qoS ͌N  LCr#/:d|(UK3pU$ '"꣭{ΔW*ZF:%W`qd =LMLܴb> kƥzy5r^QcPdc8CHսRpj.y6D&ZN4r<q\vUCZTTQ[PƩ$,;%UNbY:xNoThqK:I(NH*D -f#rq*+N }N̑!ZŐm<tM"fxE(@,SXQ#T1TX&J:,J~8]Ve1*<"#QT!"WTn)2QE+@&M[5GWP9,X܌'-&K4 {W8-8î"1Z.+Oİ+2&RbW.XMu1sauK?QE>*SM UL9\J΍NSBeK%ar.՘4sWqT)?e}~LAD3U&J9tgC.CQbfy) i>F4qMB uH492ԏ]XTAKmt9! I<;(.Da|8~wʫ70A EU$4* I5;ŤuzՕjqo!rD'BсT@HyU< (ntiVNS=E_9Ki :(' Ez Y^>rU0aoԉEX.3 cVt` ==_ }>\:##4y@SF;Ha1`J:TsyAba8[8 3}~{;~W#ޚ8k TO0xtt -㵃#x.b],"t㦏M Ilr6 ;H*5‘;ƨr]> _St:A4[:cbRDk2if #+Vbv`QKy&jؓ,JXqpKLNv -Koxnآw۩~JխJ]шeU$[}HlI*JH!R34cZ_2K %oiEF,%qBEr1Q.D%H0T<J/bGWQ"xX+4UEMyOSv;LyމOqjbt N'=`9`08>&H+oX̃P DSHd~ߩqƐ/}FÁLlࣈX1DD&q| ?5Ls7Q^ɗ єfA%QP+{NW?Bl-nfn"%H%DT'W*e%+TdzIʅBf}+fuӣkB}y^t0G&*@@D`J:>0@l|9GFcԜQ[pH*NsEw= >i~ԍNVWl1S\?uOrrC\_X Ҽ -eJU2GDrΒ7;ʹN -Ŧ=UdvW%/7yviw٘Va[8rodu'暡{^+.E,Rԉ?PZ2P԰]p$mTKi34mlf7xeZ)a,gSdOD~Ԓ3ȟ&*v}n50~7 C?ui;LnZ]A,!Uf\e :ocVy$&:rIxCS?#UAtCX&ut{Fmꔠs[Yx\eRP7W[oLJ-"ƃ -IbYm~bA챋?U@⁨݃=y+01eXjȲX k"Y$GXA}"lr҅ KD!5j3q)2sPYĹш~|b-]#@o2I.pagAhimnVԻ\ȕj -JJۄ? -k*jн[^*QN[([0c9m@5&>} m, ];Ӌ\c1M|,o}CU&..7m,UV//>)LI2]-øxw: ?\ww92ODߴ  ' EЬnk~4' -<>[˻欯Uu7p<60LJЛe*TIcJR"7r5Z`]fgu0'#D/W׽ۓo&k{|I nCDeW B 4'˘n.TԘ؄8uGqMwi}-u:7 $Sq  G" W]mj_It'.u`{Opby HEyFABJp'1\>GSrOQS`1yahA(uHrovK>&sѢm'2z@j\dYQ&ogEB{8d U$E!h?X<(S?Z*'B0'xRvRDΨr8嫋V(`}<2۟I UBhϔʁ*o<\b} ԱY&\b܆鞅;)L'EO(M]šrq\(6py6[S]ws4^yٍE~jgvك6bsgN5V#Y]4/6Y^tJ {mq2BtvQ |V]Ca*@z -'{E(Bۄ.b%VXV¹o1aB@j~ׁ)9 -V>M5. cE]F}r%t/R -ghaJ 0ëꃥ+ԡBjl<)}ҷW521I\QD8X,?ć.h {\r3lj7YTi6 BXI]]HD;"ы!G5F6SsQ"xi_ -owP$#ĉBK@KFԑ*US )AcQmÛ×t<Vx=E/:hG51nbpark'aYs~ -WhdH ;?ּ抸AtMq ,pё?#zsl%9niEf Z9c HQ -OM.I9[InneF>K*YzbZUl_MazkRҙ眢Cq]]9Ԅ{b"}5QAki !|+X.WU}f6-S>{OY?aנڞ6E*HS3f}W+vv@[c֨k".-ZS'ϮBh-$Nf!;^8KJ,_x{r.'FZ{K΢3#"1¥*ፐ~ĸ}1ba,)G/=#ilB>$B<"Aaȿ$BNϚ%W({q`8 낣k\)`@l~ -< ։ + M8h sZ˕ QXeϩ`ze`αW#~(j98cc -oGqǠS. )j-WyTPK X^j yj+0L.&Eic"E4`b8譫)ERxa/fuK>'EH58%kS2=ޚKE\%,䠕jvI:?^:Nh+$s,Ng"M,rԉ$Vʅ=!KTh&*BܤC5փD%HGoq0WP8A0hCj9J! 6HDFVu M}3aVi"7tVyKdSIhI[B]bmB -T Dz=Vu2wU:86xx ސ*AECF]Bw`8x5ssCrW)8jϯxDS1Sx٭e.L/ѶMHDC)G\#[A%sRʕ_P .TnS_RBRٍK aLzqvj!1}.CHSZ85KE$ kW4)Pnp ~9r -W0[m4&ՍI⟧ Ġd=^uR[N< -.3AT̲ғ_Vrٰ&{[,)P؋1aY\H tw&GFzVF$~cDL>k#(Y#E4@u-y[?jqe0 :n@;*KDWl8I/h` **m=x"֦{ZMPpļ۷Voa埗FL]˩H8\O\;"6X2% ˅Ą -Ll*.8DGBAEbK^IF`ߨtcc@Vӽ`-{㯮t$\vpv4S("whN-E Y {ט5ԆGվ$*O|åh`\1w8U Ce oc#y2K"#{ϒP'Cw/8v!^Djp*HnDtI,Jr"dAʤN҆ؔDH WB̂2=( =QtU;xF@gF uI-r @.=\6q6~;D(uxYe#n*3nXP0! *D Fߏ7y/V+8Q.޺Y3;}D"T"!Z:R"E7+ue}w5 lJ e0X_8J)KsB>Kkh:YJ@rBvSȬ$'4s΀%X.رm[%Нf ȎnJw1+uܵȍXZeF-dÂ3<D -15Ew,?h: cl IE>!sf兡 -,lۗdAgQKO-=_p+X{V`^: kH'vJ55~͝` b?>>JfAmHI~ - Z]\%|U*H/Q9 V 2]Ķ؄zvYP>gI,[>NXy[_-|ɔ7oS%~=69YmC(q]0QVTe"{ ߂̪rf3wY%y)@=c?m[ZfKWwk(zl˼quzǖ!w -$q/4lz.v8P#DLGt)SIV{NddwPԍ00ozF3[%ZL:a-өҗ# -!//_R -$b1$pf~v.4G :{ -G[6*A85?.bJB-kEr,1<'?7Xh[Dթ 'dVyd8Hf 9 :ʓe{zWɳ8lD8ޒ -l@;APVp=dNž1`ccՒ5UfX+\R.JxIlcְh*zb)qCCGyQ#7hҩ{a.҉!+Rb>26\`@zR/j&T9fZbw8Q>~/Zr[\bW|tLHȢN~tD) Q\a:b^}9M訪 -ψsٛqF"Z)#r.d$1) 4$sF5Ee𛶙 Vz5q2kLq,JH[}?~FU/itt6d&goPk 8}Rsfx 84R&O(pYW';eBƳ"sOJw|\L, "&]b#6~LW4>B -قz*\<^.8@bF5ܴ?ȿ>"i\n2&]v#;Њ˸0 -5)_v48>Ay$/Z~wn53GSL BS0Gk_]Eagi^΂ g:$Ϋ-UԜ[X%sH~={Iɪa5h -.= 6LJ=E+C{(۾br Q]P qO  s9LQw۽KkKe#o'@G~Ea @1#޵CƋ02i 8fZO<rqZ palt}0),F fVd:#g$iȸHL/؁F/ (N?oD0_tE+8G_"]`q mCO-Ā2iGhwUd W|Z2NP{ɹ߂g-oQ8\kws RAXŝ(*''Zq0ǓęoyA3-/v<LJgs]iИ?-V6(,T܀Lg3Y@>Y3黶Z槰-Q95.w9dܭ`d #PXī^|Cx ѮbcunXA< 6p }T1ܲK2|H_O@`6#VtpW]{O)I} GowsCNz8Eb\2 ps-|wv`p4*==PKNZte\ĺ*)_rlSIiޡvDM)}ҫ'cJ`< -p 6#sȬ64{_NJ gk(.D-uܛ:hT*W9kݞj߃Ji@Su̧Bh$HLE׼=$4(cq6:ꄇú,"U:408`;$O/sASVs8ڃ׶,e!05: -`D yw9BBy[9#-Bf"ׯ׊@> K_Lhw*F*^UcmV= l1d!!pЛXba5wI0_V e ŵIeӰjwEu&}'h -!Qb[ -@ 2&ѐMݖjn8W -wθ2M2b'`^;ϟG8/0COEΓZ -TƑVG)4#Jr܏o1~qk Ԡt SC3EE3;L1+dUwJ*"X`W0;[L;Q@Û ?Y.>M ^GA_mQkr߯y[dQDo$ )Q_*蹒.驆nq#JQ#l ?"yOe c{񀷔}1WH$cۅw揬줁On5Bj9L02!K59x2dǎ<#4,2\fYY&/Mq< ju:Q=K$Fܛ fm5 .3zN`$GB9!>ACWwZG+ qQd㸉~!1njk+_4o|=3D![t짐)w47KHǚ*~$lUּV!32@.4Kh@( s[b'p=ﮞ(`x¹MC<.<ʠëx0f:$י -`n0נF[Z_\a a2/IbS4UP")kBz%'8%VVWx'O]r -*"!a\Mݞu٢n@Ҡ,G.THNUR5o(>udե5G{.lbbcry,8=*(nOvxDd-yǘ@m8Z2GeB8X/(;n!e:4bxE%5nq3ag=ǃ<:!sfyh7亨hl69E#j1f5}&FJO9 v0w=pkH/{Î-Dk%{Z[l>n1pQoo*4Aᑋi{WU߿d (vERe7?ᕅl r}e@Ti 2|L"׾6~N\XbsW4;ckT'$Lyz%jD7}`4t5RA-"8Cʔ6jeHѭv>yyڡMzMY9.bK;qkA{D\*D^p ֭< -L|C;10#LKX*AE^H.)v+*kpMhiajfڦK9mϔU%q_DЊe4ơ< "hݘS]%FSjGE_Svfmlfv3XZA gCw,%yһ.ٮYVC 8^R3E5R^+)}4K!+\(^Z/t20<쩈仉.Q^ (s5i:; -]>$g :pWf(jێ:qa>֌{犧9YIc_HPp0|e:?Sa1A;!~ҜQ-i΋ -ĺgh@߉Î5a[gxCh*2ŰO' Hj)c8\P6+6 s 3Su*гHՠ͐7xT·Q&wƦ).b)i+ -j&^yoG'_!>s -5G,7ԹKw¯iOlpҶ"".BݸXJٵwARxeĽBJ(MszT -}~JaځxxoC3 -wn'UZj :CN\O)8*9GVמ%^485OװTӥJ`WAWBCTyALSҎyCp~l&YrpAKo9I-ێ[FxS҄8%?*~~uƴXds$\c&: 5MB҆7r S@dA!'U K"R66r1A6x_M*9[cc+;y:k I=AR"IWa֢h:a"AK*Pt0LtFYlv|36.tu&sYnOjXɪmRggp8h ˁ=g"Iz5/EGiT~5iq JqHdXX#.$gHx,A/i@"y2B@uSKяppТ| dp(&K\x,0Fԯl@0Ҁ0dQ&:n"qUč X?J"X0{`oMf[E&nD?\A8&wz5 %y3cXwպ!l!!5J˞R -|깝;maЯ+ww -@7Sߴ.?'z)vHaK "q*mV6U?tJk*b۫Io* -vo~] Vi\ ⎰JdB+s{lq8𨪭FHB>uJ—^)Ҋ/x >z -4)mq3Ɩ†+=> KB,",}A\fEh\~7)ʣ3fX'u9,%pNj*L-ӏ !P 0]ɈCA\U"h)1qw aCIASpq;nM*#qݽC8_8N%7ੲni BsJ?_FBNsA%3SA_Ɇqۙ>$B j%˂+2|r0l ~  ǹ&E዁= Jc عl(F8SA|_8Y%;t^ -D2MB0a&' $dx E27'b>;{/)TTb{dcTַjKz8:NAY'㞞O)FYVoO/e2kZͨ YIZw5C/Sрwve/;Sλ$h8nuJ+r)qR;Y7ȳHg{ A|8N֞Q-=\yw&5{2urqblМ ϋm S‡t(9an2SC1(yD}M97n\mFS[4Bs_X6:[kɍCs [ͷ26x?37$ch Ľ[7GX4t6q-GNvu9tm_ DzqYZ8jϕ/T\HE8b$r2i*25QM3õXZ i#bWcOXKDKz:L-hjPpqFZicLk!r-s9~e8P? 0\4LHD~3Λ5c?lf;>1<(=8N~)s`pNx>:2r,;"Y00s/zRzS,DӘkRKb%tF -0s:>X)e F}`TF Ƥ;՞bKZz|˰ֽ%^]J+|M'B޲uu'u;Q39*JpHD 0^u-H6n1jBe}w#zBeۍݿ]l@;Iwê $VY |xJ)cY_2}?}ηxÓj/;CfkI.8e,гݓ - -_XPh7gyڎi?lz-Ψ]J % -A{l jK& Fk MIfm~y1."rlϋ!k؄`\yNlW]ۏ2p]WBifDخ|8)=[zYFdt?D~ȷcOf =35=-I -IǴL -a~T<^2HK!1)a f@M'r ȗ~hQzg:T?}Ll% pְ=Ǯ ?QA/pLl/ 7VlGŴh-Nh˘!M̏PMJ7C %mhͭ׳6Qf;eֶi:80;wT T1k9m6*pv#[̚=f 5=-tgΦ=[`,ټto(h,ݜM }+ }^?[{E4lgu1 օ -tRr745ZCن(#`g!dWf8G{~&< DYdgX*OX& ptE**$sO{h"'W2KCh>$;u8G &;҃m1r2s䇀Js4_!֑b+zjo(Dc^H&AR8/,l|-[')Z\3E}tPm 0+hFڦm]tue{%9D3tʩ#M/.3Z8E>hwx۸ns#p]P+/P_ A%ǝs@f[aOig]gziՄE7}%[,or;?lg@ᘁ14 tJн2[rȸ3;#>+p /" &xk"<_W6D^Goё2˰L F=yU‡yk+vAd֗j:u S8r};lGDc}/{oQGJ[C'rac=NM|yr'ߜ|?+I -}>w|] :o(}yv {\n~71P"CtBi6La}ms#CM y\\1|D|Wqbyg1ƘQ)?C1͸[Jd ! l增%{x17e@%h#- &iIM I_A\ꉏJ%N|˝բ3'~+8m- bo:rdKS ?[v&۲R4},޻][k/y3E^ts.h.L!ivďj?`!Vڌu~ܧhB`y{*/f:4$wקvܥ;q%Ї6F1E7C,O1*Ky <мv+/u'$E\t.#CxN:]>fR LL&S,r!ё&Ah 2(yG8y4eVx uCMc$z =5 @i~hz9+ɏXV'זW *5'J4`*lS ~-Q DRZ+Yg89=("/k -dUxq~y^8ޔ"^,s7o^y ?,TCI4B?Jqc6&aZRi>f#Fjhjw\ͥTZ)0n?SO=ڢdb 0ME:!gA!ar!is9 {91J{*Ak6K'F0HC*6ht&L %|,#3at+,FM4 8b sax#Z`·%OI̺ty[մa|ޏ7nxKj.>N]ӌӀ8@tSOLثӠdv55Wц6= -v(.ZիOM]H`K/l){E˟#U.ʫpvQ1.sM˩+`*6NF*y897L8Dʥp,!Mҥn~wƌ8o<+@єxN[X!.NGny#~t3BN.3vzJDOp# 䪖>5ͩyۈs|2"]I #@nPE&CHC 0!#`NyH{ր{wMӝ@?e5fM-@-w1dÂ%Tww,a??;lOOaw82<ų5ҁ `|C"X(s:sBGI?y[]1\,&0u6e̋H_ &dU5[t{,*u9i"Ya)Yaq_|Xvamwcx:gH'jΠ6tBm!6\\fkg>D_9!Bm)[!r`㦽6 x3B^hc,@앝4eJ^Dފȩ*Ou.IMHhܶ}Q(C@|9B)*n0)˗Pe&[亂QOT=tף2l!R/Տݻpt`|]B&!CKZ9˓ƪ'+ {W}3NC1gp\4H/e\L <))VwdEog)TŸ[=5v>Yb^" c@Sdg*,lw^]IO -|"1XiՁtQ>)e1cwaY 1Y$f\t}xg|V5/x{D6̽ Ug71:=ŷOB0Ŵ qQGT(7GP2&m6u ܪ@ -c%ȱ2gF`S XD.窱bPMRA)z7(7`u$*$xl ,> V)՘}oTspC];A!ZۂՑ9"Ѥ8^ -^x lh8ьRi(aL_mY(깕C10̓5J-E?\Da1ğeU $|)̿ 1gGئ#RX@AYā ) ՗ /#|H_~l?_D,>fJ[7<$ZL}QL5WIɹ{@y~T JH=n`4V[srN}W.~ώt7qwE)5>\]IffѨRo N$Bf0Gީ2WW#j6 Ip?ؚ$VOT>ŶzDvߑ9;@isȚ<{]ʒ,&QE -nKBUA>zb('pE |k Ҁ\Dӕp"ØIo~nhZYHv/]~`Pt -c]a?}3Ytxj%ynCһYBĀbz?jY,P aZ?z<c?GuPx&j pO$Ŝ>MRXWr[JԐJlgwP9+a@L :Go'؋t>W2b) ٳYgqx1d$x4 `3Gl˩96 -isĴN|nTb6Us6um{ XЫG}T=kҜl TAqU K/b%edLΑ3@~1jl05e$γMt -> ][UxGҺSD |RT+JrK@;^&}0h+ Hm o -Q11NtOXiWʶ|wuÈ[u#V3L ==GϬ`bKP *i=k*R6x8{{} $v<m59 rPT=I[ -XNw%|<{ g[kNo=O=_أ2 ?Q  ]֠-#**9ERbT.7C 51x~T%}ƵM)z~EE ZG%$XxRjR`Uү?,~: |/(dR^/Bܣ$/`VAc2Y4Ms":O7$ ՗+DQ&ì.<ѝ3> 4x @3sR}lF7TDJ D? êpU)YOG/'b-r0D%bJ?e1MW%OXePi]vp+֚e92\퀦%ӏ~ĉn 0b4v&+TymmjQPU6a'O ewhL$s-Y2dw*MvEM|bw_0)'aUu4:R,:XtwD*S;_G`$ͤz({ 7QSIPOw,1raS?|3hŅ|k>fw /|!1UAXs -޾P'ʋ1# - )4b⤢[b)ԧ/JyhjϷhFU -FtvSe -4>S:Ĥ0[pTlVEv?1.%oc0 ccqbiØXlNs>*UUCnE_}HCО! @hU.%alڐ ¼8ǟ@. w3B&?Q ?26 _E"Wɳ<-!D(DL $B^᯴';+}I(΍z(% 4<͸hX"F@)t', CQvC>akSkۆb"ypJe,G%6݄Yj j5ۄfݰL8u|4>#cuz{UG'i² UO~9-º$zEkDA/_ܧryt?$AJ!zsinPmsdQ]5{d8a Pz# -ebD?0ui>R2Ob,öK]q9V^0$p!sFj0vHZ-MXYC`WM̳/uHN/(C!cAY]b+(ᛛ0Ku7][) - -)kgcQ -`lN=9w &&| ق4ī.-W+tbn eƀD]9$AE )FbT۲@z8$M{MuO󦫵48a j3UʏKV?+!4i|_i1`pcu -E[) u?aDo%H-Ma$?F -W/SXjN#0 w1lh ½.^Qr,==K_,lEޏsǒߏvKQ"O}>ɢ]#Gv&8bѦc~c;Ӛy&2p+CUjr)je-YCaRjN%Ǭ}68o_՚J&ĥ}'boc0B= /u cRl:1::5< 7c@T 7 R3i ˰Qgm@@gF: 5*`Zp 0+eЊ-y[GڔX@%y]=nly =9tU׸S a,#П:㒺5\+tNur'kbZ0V7Um`{e쎐dK4 X-c;` -J MS(SR|HTt&oNX1䑒\{!i{^9`]wr"[ep AW%ypqk+Ηpw,-ʢ{Hbt I9"RBwbhn ;5Pڈ9x?077k6nu@9RXR\KUh)]MFX1#]&gP)E֡eZ0 -d&4_[z>*3Ut5@kFĹNw;Tq*ܠx/B/BdlH3!02jh.&Ъkbps)`3/5'p2p)sc"?#  Cj+x{086py42E"60"H4%h^eD9D/:4p+ZuFkmq@b?Bo :l{&ã*QbwT\k9 ,ȩ`,Pxп@7.F047(wAPnPz:<4r9AgȠyEu3l/'{@B dJLj4_-`*Cм_]ַY֝e];'3<ʛ9(gqkQ’+`zљG Qqh 0d]# CyvzH'tjAH>H ^ -E $k_Bb|F#QoL:B MATi[( Xw+-贐ltQ+WhC$!YR6M~\!Qt#?IQ1,HXk.HKGk.q -M$Uޒ1S Ǖ&K1DwUkɞ~M$KHR& !D0S`N$ - D2g{)|AB.aݿ$ZsVdf[A%'L5ӁQ"VᑕLK> (R=M`! tT CeyӹNWk6'WcH2G#\cs4$5wxȽI?E~LbN襟ZfҏM\סee1FL~̛~2/q -p?q*(~N;5[~Zm)'Zf N͞lZ7ԌBh@y`&r9EtPL)8ຽY" #XE,ht)" ;gR'& -妔r )R OS`OzmYV,wՐ^mC?KqcBH=݉~k~? -8zê 9ɬZI,},ƹtg9Ȑ B\Xt=ʈ6M?JFF^e)mPuL>Y3lpvI0$",!i&1΍Hs#~$˨Fցo7ss(,$u%^xZJ& -KR$0]{`bĄqpsBVF;ۈg߄|2㩪T4C҂g^s&vB|P!\WsI"%TwAŌVN>!bd0SH'"8X} +u@ȿ _[7peqP{G/B1}`#d.p4˧X$9SԸMyﷰ>jU@ AwU3Xߛdk -#^< }  ] -=ܙHLՀ:4@_+Vg> "|)VSwG;6L >t%dCԒ(8H -%'ș)R|F,d0>iWX@43NI胰diU9ƦS2[K:WfNK[̑ |d &}뎃YnDeWYE -|>k!՗LN.dBaϑ鋱ߞż3!ffPAg"X C'Y%>ES3^φ1 ]O m5z`Oocr$KtO?P]nCΊ;:Ad3X/Nwx- em趽}u $)36J=_1[h8deY,huO XG -lR[;SBhHm[mӶ'KJQ>r˽jRȞ=WbM_9L'uRb֓1[Ns5Ti ΥVJR8x^멞oC46H$B,ڛ|+rIU^`yux-PT<ي0{Qoz&)zJS~w@.3a/>wJ2з}[u|򵣜dZ>qFK#ro= ZVdr=Lh8)I~TS~H10_G#JbA8.(P x ϥc:~<zutG$ݠ'̍EtLUg"^GzxzAX9^P|zГR&Ȕ63 i1MOƜZ>&ܻ:o{?c4/.Nx7bML+hek}y,0xXlW&>JMd5k‬_WשyU+pTj"&30?M$]MSҹh[O!CfKMGQ;i8͢ 7f6Ho`1zkѶB -޺ qdv{A:&OuJC׋Ms6s3fw1ԿϙGfݓ Ɩ)&aсIFwdK|7fO'/6OI_HM(z - endstream endobj 19 0 obj <>stream -Ω[u0YI^Jj31b!ڮEWlι+E !]]R旁KM[taϿXO4vK^ -Geu')`oe!)a&TZժKnOLXySG4Ҋ>Gt3/턟#'*O=iHB|!ǴBZɉk~C S){(I8|)=")d|9\C'4Rolߒѐ'Ey %:J~':,iwbɶ;Zζ;kb;m'<;fؿ~}"noı)𔾐ZՈN|cY"q j"\sRqm R~ү߃׏" WڤFh3!Ard±!IJ,;2g>AUO&A=l_Šh/CLa X  &PmZGoX v|lý_^u[dl_D%* -Y{%Ew4 뀪ZlC^*cPd6 RMaRW -{=5 )%a1P[->59m+eE3Z4+_\$4Z=$aMyt!,g!8II YU͞,E(DEP'KXB!rU=`B&b* ӃELUgR %%%T(At9!! DT/ŊVUݪ,M; n9J~ٰ&UQQHP@4ȩꭆjB>i"h`[#}13c2:S*)K(Uq>u -8{^3CiD|RøqÅ\4ęk O4'bDC)D#ӆ,&C$ <*phQEL 1D$4cnnhFjT STgvU՘c?4Ztu,c+D"Lʟ)/YubdSJBZZ)ߍ屨N,Q$W[JAUyO' -reBD$.TLY~<~z[aO?zLũRtjjʧʟW4?QYGym|φoxI#y}LhTu5^U:~}Tu$/]jv_kZ9=9mɥrSר+S1yczfًxB#믌2Q+]Y#WdsDM ֕{tvWXft,b1F4pnEbR4_{}(zVS7ړ8jg_K+iU2}nm-SL)>ӗ3kNwhϥS ׯEݚF;)4-j.N2X9ݟr&9_$B3kF94?Jycȕqmk= =Zs񜜞BM}x3r2Pf 9Ӈd3O3J8>ȕ?ԗIV7үԋY$HTCsyFk6G꒞zA|T*-}R{%]"qKxct2Mg:BBRy5p>H9T.3OhWQN>>~W3dmOIdyUD -k4T*ꮪ1ŠwHQs/~]VK4`4V-n3}_autn501Cd?  pe_zKDūLunqjW%8fHaίL֘hd/`n\#u܉sU;%mfVjTa o?*jcJT_uUƫZ UR㤬k#jR,Zd!sߦu&R1!YYIХZqkտO9C1Hb-h pn(@bzU(/ &L 3yhUq+)Fk(ăn  pk\%U\HSh* %\$\Vr" ##$TRlOd# -繣S Ҧ"ШrN% 2*1k¿0אW#')Yꢟլ$XT1I<8)hDŠ?HaRl&/8B)P< b -zh4ڽ'~xgR+&M=_4}Y"0(R)- SJ\8B&>JڃiuzīB OdQMWcbȿ$}:yJac\h̥='lB Q^6<8#ExFv5zX$pҮ#^]Y4_A`/AJg[7K?3J2;"b5ɄV("w1sKqxR?cT~#PAEԗ1$xbBKX>`ZEi#/IhU vloodq QfObNJuBϼy긎Gf81#E΄2F}"bgpY\JBjV35#VKM!j5{%CLd7Ng7DfID7A ՜­5p\ҚpQ;|i=?V̅ f  pfB:Aaf&8,p*1"Zp[cSGۊF״&"jaqTDud/wm,!>kB;օ JVsw15T8 cLsiW3lsX"_IDҍjJ(*%ފ -&HKKWz\:%'-6yX34MI: -9yHs:]Q13P!'ZmNi0]1Oq^~FJ#-W!/ej$/B4DgO3D?AFqˡACsץQ~+ N,IɉDZ$ KY(T>5ւU>]3)r$<HG'ǔ9M9F,a%)/ -"}Dʹ1!R'1ZQ("Q87ì;JSTe3q0ٕ>aHδvřG; -FqҐ. o!ޠx% DigkZE&&i曵FctQM AUu vtwl$Z#o#tZAV"8x]yBgrE5^K!Mm2U*)JFXѠY|A\G)ZZĽe9(mLz D1JUnlXLBVh#$Ne+( {F.'kЫ LfE"!D k.{㖬 é/E:B`IXY)Q}=_. ɑ&r5žW,P* AY3I\ "lvF(VT*JhE!-.ų\1y)} yOj{i.D.ҽFcNVp.U"~H2::3/8EZfkyGwi9ΕV :98$j^E9x+AsDEzw.DD*OZFQhÎGxPm~+DqYdu`u*6RŦT"8$K" މԞFxBqEW HF#q] yzjC{MIcb:Ԓ/VfB% jUԴ$5˘*[јHb*HKJqS!#bM=MgS -'hժ4FMj˴EZBsW|Cm6ST*5\HZVv'lф%I(3ڝANuc>*>BL˅I'nnWg2msvA;MFR,OtɨRsGOLX -21beizjkpDX<~܏8MPۘErF+3*: -dDM 9r\4H0qkɊ$z:JH *Sy:Y֭ǐT,ME- O7*j-{忥ȐR5b3!RmԢLq.ʔVxD BH֘AeD4&+R2CD!E&GLJ:,wr&Q!6zkr&Q8#IqȢc.UDfڙ(BGQUEc?SIsS|)CfzDGo䫡 Ae3_S{"%r7Ouc%wJrvaܸݸiUJ /9j8’uI+}'3;iۙVI$r|~e׈D\{GNh–h4ai?Rb+l稚,rE/3ˈUlho@ߎ@Bj_(,%Dp\}J I$CZ뢪&j44k&'?yg2FV>1uTs,\LMGb Uv!"eΩPO":6/! -!넘 PW>oTq,h3:QmDlBIVթc!YmjDlLudœ2 !!h}r(`Pf" zsh P0f/>?{@KlPZMLGpƎ6d.DvV|i&*w JDMiˊ>GR@_{l~<+M 0t.ѓ@@ E>rg(<8vW }Sp8Z͠U~0|o]N ɚCc/)qL 9#k:M`[M@@`ڟE4d[%65 -עgɵF4wUlR.ɪy҇nyXoLc @ . ]5~& Fïf }XL4 -hb\l,9 \hߞ2{hW;(udpY'W @"j mߟ ba|[ߖӄv347DIaPl%q @ʹrh3QHP#& '_UPu/܁yΰ "'V.G01O:%@zK)Wskne$BEK͉! bQUL7#Āϴ> ? 9uMiZ%kW7=fD8.|ZK_"KX.X֢+vX - M -[&_|,=K50<F/?-L!_m}O_$>(DNɿ!Q$ iJrQ',Ì7ãt)K42 Ur Eq)r$GLyɡS.oV*o!=:1/[ ?A[;C_6eMԙuD씓(W2 _?Fkg-Vea^r/6^2K2*C++6Ῥ;^:K kz#/{24{'U3MےSqB`}…G?NB_hZJ I鶍~NޭneKޅ=VU 'Y}W!s| W#6?ˆӣ)9CKJa7|{=:kxͿ|y =X< -do9ODX}9R#= Upg>3B4 w"Pd{]}) pJdTԑ~?M5*BtB?ɚ_1x,z?hV?7U(iuM[ubkiz%T1~U/P`F[mX$ GoU/T:z"m&J)2o>a/#xس<gէʫQAo`h|P@Sz*D+?)cyjig("xCKQTջ_W1Wm6.!4>. vm|l= 3J`|YpNQlD,ҵ.C,91RB%uyd5'mOinz4ܦ,=Md!FĉY~ܭ:*?QObgY(vS.8Kɟ`ߖgOr{4 3c+#ޔi T!/vR0$R^8Tj/-=O^pgȟV|a>AgUg3%XBt*FD* +f:?t׭lfP(޳@!CjEG6˥>Ct#7gcdMԉ(ś~#4!u,NϋM?J-~G?7Z~5߽3T?bDP!(cA e -Gٚ7fBK  -u /[t6V?M6b 2U[зtf`y$[ͼvΝ1s8f,x f39M+ ] -{z4>cYL([Ar`OԀ -r _Btfte/JU1 nq@ [%16w}W8dtlK"ÿ$Db@Z9op1N x^Y: ͋Ꮜ{Bv*J$KI)M3GͯKȍ8F-^O4,mkpyYNUBuN z ; (R~ Z#R{+ha̋Pÿ(<⮆ժi23:j?QazW!? 7^ܼo)8%ІRTrj?G>ǣHN@ZV*iallu|W{{96JEנrɽGІyMރ$1~ﲺ,ksBL75[[_+ڢ%F]*>V?TGˋe'i~E1j_6%~%Ef^a?|U`I'=Gd(F(oDƜEz0 y^PHuCb#lBxAa{hEIfƇ]ZJDg *{mdpߪd!HaczVߥx~^%[ h7L)V}+\VqoH v5Lgq-c_&3 'YMC(1oIѵX P[~+,9cΝZ_5n7VLg¢v/ Y+ "M7)"L~E't =8%f-Zˆy1RYPcVfˆ]}vՓmvD ڶ|AL7";_7_p=x;s^w{mhdA8gϧ1X.(~>- jeߋ&Jm*]ʸ+{q~]Ho~#b\LPozl|Hk A\V-tcsC韎h.Df> V фW;uLcoW%_>@F,4Nm@ߪL>Nę,q(WEP,~+4|9ⳀOʟHâ%@F?a=%rVn0$[Z0j^XNOh9alO!x{Fq;5 {I;OK?n %i?Gɶh=u g v{i7m[Iޱj?"&'OWFC7,zhþDX|c=ů8!5oR}aC'+ꤡ1oZCe7N|Y=*~X)Os+v}1y0>^}I\D$C|2d׿|['vt -Dr*ķ;/'5md$M`O./qHkERYC?`Ҥ^{'ԧ&'>BWt@'WYI 79?yk'_+j??]N%8zΫQu$2؅ IBʙM6?/LzKFUW0qj`D͊OFA3x:lѭ9iX1|j -K¸;'bP fӺ,FJO~(!+$H8oc!=[nR¾ZtΪv@3|Q>@ >C//=>e5[@~^ᄲo z\ 4~>KW!)+| hܶxG/_xQz-ϟ !GSYNBĀaL\UEIuRWpN? 𝶀~|i^"F;s‰'=$UNZ ʄ3R7_f|ME)A[]}C>#D)6T_pP~N3Nﭞ4JRc5v7S)ӡ>v=IFV9ߣCX5F|M B:=EC {T9'-L@Q|_|(l'\{Q)g?6gm@o{t.%y.^^9غ=eP 2i8ː7)\X8J,]qb۾,ߏ˙fWcJGД|*Y#&"_s{K:ǵK3d盛QNa\|/a={׶tB\a(:U|\½zg8˧n|4ϱR\6v_9nE[;?9R!Y#o珟˛b1%IYXD:\rJzf@@럼%4c eLދMX !CXrJV TO1ד@M[j0u|X;2Sk[xviyMJhAb0[☤ hz0^e66|Vl9Z>D`W  t(ރ1@WH8ILcyퟮ)Okeoܻ\0er`( p0]NOIYLK(duELCϽ|Dsj:T`v@Ŷu=_'Qמ&ѹ#6Ly,j$zԞ{v^y,xNGk3@J=[aWQqipCiRs Y'_}CZ֪rzW7l(a,!*8U@}ߊwl<]V{lW&BYE^G?6)PI ԳTv2K>aw:RN>oLzA -A=x%k`eǟ>aVDBg'\ĸ P^9Zƻ@*ۜ8ЏUzfFؓϿ֗Z -5cG/JϳtJqu^u JWRRڌx%"۱>@9ה O8 ^&洤6=; }E?L2-ARRѷ .I -t0KzMB^dCKXZA2Q` = 7w}&+Q鍕Ƙ. 7@1QySCif5lvH>TΞjA|VJf@` 55>wl &0*沝ٝۍ<'Ri­J)aRVSrH<2ˈ7{"鼍FG%O:*$ԇ#u}Faa%Rl11k'`Dqżh5?q -pXw.**4zG? 1}>L(2<& s .ts@`~`H^׫5'W;uy94c .ZXz!D/ቘ÷;.fx -ygE/SxaR90ѝ/ctŃG& XJ~L B`*C <UzTbTp@*0*ph|E?XfH_ _El Tg-(YArUB* <1 ֭*z!&Mz)n <FkV~E=/63~ {vd=񿗜*!|Oelǖ/!_'qNMF DA5],@pANg?%b7knᇩEutnچa+xߋfeј3anj_xr.eS&_Tr<:QN$X*֠jҭT˿w`]17R_ɣ]KnRӎs-5芢yڐ]yhxg쇲'FWW q1nGQCvOM ]79|MQxEprv/vੁd/ q6V@=a?]X莇6r ΊbsG,_`e( V - =r |%_E?EԄ/Wy hMG7.t>4%t.x^DbZg*~]h5ϔUr؂a0ǡM5[N HبRs +:~lEFkcP 5_%,nt`yejNP;&h-ZނoÞ4 ;I(rmU@`}xNGNlJuXJvg<|3U?h y݈ -EC {}ڋ Dڞ31Z{dmQy(("Pe1n5T,eG͑ &?w8WfpTyuFK]_ ؞r3 -2Jn u 7 -)Z)?lbe-r3B0sbepoI ތрj8@~2e5T/ $Maei ꍩ)F#9j8 -1c`^/j5/hgx0Lj8z%Q@ěѭ oF컺PYr)ֻ;bG"*.~8iuvvgnYWHBx Fp>IpZnFu2M9 -6p[i {^ߨz`$?DFAd˫(זwx>'<Np\>b&C2O?2oG*[zШފ*}P)e$P4Bl$qKI8{B!YJzA?qp{É!׌L-t?RLŌ,$CFBkxO 3tE1#Y#.AW,g#Cb48ŃPpEe `α{jE[֌q3bLB#kJ [29pRҋ%R!v p|k@@#U 8n'`H*2W䚥h .8FbdqpvFkp4߽F! &GMT`7Y ~s _lz/M #XE$zሊY|Ɵ:< B{JUHppU;-\z-}uLH΅+˸X>v1)5$e,qMP.ZIGRb40x_+鐥SAW ӯToLB ޒ!L2Khf%FB\? - mMGr/e̍(%'FMp>cm8'F#ߪ?zI`e ;4* iXs-ʹ81L8E -ǔF@ANIT:Op_>r-47PT*Z5M;KgrOf=H5cƥ缃UoKS)+@ u9>JT&}.qSK޻p'ٝ4&{&-(?a4iMKseGGФ% Ua>fTt%aȹO\>OggLw5AfF& -}&&n$G]GZ>g~ݠ>1 I 0r_FJ$<y+kϑ}I JԟLZr8h-+%f픦&}NU}]i,;eas4@)>飍$V{SeSjkYm%jc~7t Z-!#`8ը )w9h)xgkYK+3RآxԁLwm8Ei3?fthD7]Q%teiӰ$M$P1:?t@Zv?ؑ jB7PVl]gߗg$M2n$Z#`~6D)Kwز`_Cla\ӧ&ϯ1@MC.-n>⬮w[?ϘӶ$qEM5 -rsb' UT<# R6"ÝHkL '3er(\!撑lk)ր׊h}Q%?48 tNTΕ{ȹWr1sb8'0O{ZRE{F+ -3JNW[K#T #l-ZN:zvW0G -}LoIgFNt@Il%IL4~ rkQ.i_'90~BXlC8)`>|*iv ?ibc@UƟ$W{9xn$՘~g{$SfF@ #,՚o#{,σp M-$:z򃤋Rψ(v: !?9;A*},~>8:9iMz1KWY[9G=X01}a'ɟO*s ; I?IT(֏W+<֜!(s W{Vտ)vO3H8^sÅяM`u= oB3m2p\̏ڶ-R)`6hy0 84{ډBvr&Iąmdž<0ӓIe iPg'@~T!C>D$‚@)k^r`twXLD ǝg$e~Y]xп GAH#˓?t7iLv#7W)q'y븓mf-p%gЏR6:"}m5bb dNWf:"HkǏg!5!l?XvF[ -;Mk!?}ak]Q2#"R?b6*;i_K2ROj`?U`߸pmg ȱ$jڼ\eCI8M)4Ǐ>~":NbTMԝOwҨO;iPOPv.ӝdRRAN4rj^W"T]+(L<NWӮ@QI<p$MڀU s&$ÐSđ*ȩs2EEJVq_/:7sԫF4%jQn4w?Mǖe~nr8hoP'3[h$J(TV:I@zZT;+}%cI{UI2{6c][맼Ie| N:lonENP:;?crgO m̪ӀQ,j.?NJk?[EkAeIďӎ,s!P34WC!r8+Wɼ-R>I6?IM.냦a:;assN'+8h!_*Gu瑟l5?M_?x٩=Hkx$l -.qkpCΏ|gM;Iūz+jۯW<鏽2awbg`x$ݣP U'MڭƻI2> -?`I߸]Y盥_,8T& TU!8̇]+D|B H (&  -$j9 ?{_ -*~*]f]=mj[dk;&4XEjE 2Y͕C,5̞wJa=EfbX2\ F"C"FQ^,}OnMaYl ܈| ?jnMׇ(QicCG4& K{LJK0M-I :<*L{[*[ -Ș!p eLf%8.hr!([@Gn.5qywKBU@ ђ6x qpw9 9"Ȍ!*N3{ZKIMf z 27((¡"h9$2!!x;LEjwP*־hy1ʡ48I0ըJ+:XZZ x1L -1k$` k`w4BˡIEwstv?< -{5Cdlŵ1sFe/48TFTe1,!`(6Ĕ -7HQ}״: d2kSxz~/hK-*1{Dg$>}728i&LSYBs"t-P7=l'pI9+l}n 7DUEM J ^UX=T}w%&B-E(^qq]tX5""G9R0򀔁ȩI؞<`<(U"\ rF!ET.X&76Εtn*F{}x* fk/6X)8eo9a>ǜx C '\tu4U#߷.Iݜ7wA8Ҿ3ڦɆXkY\6QZiԠV\ڴr`ٵ7Ѧ\f]eĈRZ}o%Nz9 IO~PIsڮW8 Trn^VB2"`N 6-, Z:ÿ*/vJPL(/-#ct -=ATR)wSy@_1n,*V)A¥ݷ/RD}J'KXS !ir^ dİUE8է|IHid*Y VE9#A*d,ZO?`+LKd*m8=MA\\A. 7Q>xA qJ'$+O))ՠSdr(l T $㢩W)eHy^tҒѽG< GiZtR/kF^eIK( QyŽNZn{.g?sJ$PQPULّ~ItH-v({DB0Bˆl ub -OJ0Jy⁣H샦Z$#X@k } )>ό$ nO#}d 1)uǧcD:J,it,HqzRF} gR2K%V<(EUdf 3~c~'ΐ7IOt Tv#UtNdRo%=tW)+-sW yJ7!Qzp5UhBv -[(h1HIjW21, $̝pXmg qSMhBw3vH./,%E.qrRFuRa}Ri_.(+.,6r/@i0L PSLzj%5`@r |12WU,Ay/Œ'(!9WEXɏi`IBSd -@Df'6M0ҽlSSNx}.q Jp`|9uq$hEөOeyYhWZ<)w+= &\! ЯE2h>IslUUzl#xc$7eM V$x+1/5 %.OKYQU"E[sXe⽯< ߽QɐmRX_+ }4;h| *suo5Ur9B4$gIǬJP:ն*];Nb4a|;n?wiahAn*iE4q{b~MSiRJ) ?q#Å0~ -=UJ/评U AOF!:nt6n0g#[*I1SWʕ _JPZG2Y%uc@M=D&/%[גSWP`ATXMv)/?~f^חx=O4LU wJyziy] 5>OE op)t\PE&[ ry {đ122ݨxZ.!Q+ ̰#u$aJ[䱔adaP vdۻt82@#،}8WuqIYHm\B0ԐjaU(@SlEcb`Jl2L;ec^۷=pT栵P3>&%ԆTV?ʥptidVQ䎙PQ0:#5r wdn&ؐjF2#Ҟ,S lŢ7bk%ʴG+̬εpgEEYTg8[rvfG.n#R˶t2f5/ k]o* b'B1ɶ=aID|C.)2D1VHI1Yic"0q,<,[Cbu6{8UzqVaL)$s<IJBa@ r&Aƭ٥oI> «i(v(5@3LP0R)S6!ֆ!Vq72/]tcrL:ASC}qy-a&?e2nngroi24˳|D!S&1ooW)13h Lq45M&vr{ы:ИfZ -( C&厈w]Tub/ -+̤0*u&B0q'7AϨq(F1* JyHqѓs2bj]:[5K-)Zi`0\`v -i>SjcD%yxiDjnB*y2y2hITj $>ghy0 Gs>c=u(HJr3ѯ+3OF )5RQ5~:NĸxFiKYם"Uɍllɴ7RSkz'YOE{ ty;uQz"wL֑:!ddΥi0ȑ*z#ry 3R6=}Mk4=;6N Հ67S60$ND)GqeUO➠~  BQ*tQPOBfcW2jOB3?i:Nx'*850?|G/)%N-v(CQ2A>^i -KMy9赖v%/Tc[K}8'鷔aT(CC)yEYNbaJrNrn|}Lm1`Q&)Unsğ[~Q|H4kWSd Fr}Q~b{Hh}Tƛ55i-rEҒNgH훨HAb~9%CcT-J)QcK -oRTf&]v&"YN\꣛|K%Q=S|;n(* )1읥-iJ8o^S H`8%(kmzZVf<.O߾WwN%J@y -+|6 R5!DهSPb ۀ菨߾AEI߿PςqtQWcL -lRR@h~0*C+&@&-`0*T20*-_.6P1*bTzyĨٴy,ՁNNH~cTzgjSQ}."P@N@QhZ B;aT hbXѦeX!9讎}¶x F'{}e g Uyu=+5O[M)kC[x*Pr jH<_F -ZQ=$MIjXF;RX^U]QW@= -_}.gQ3PHBA;*oU3Sl&G\Iz;ό -$? -+WkT|R12?A<%lTxkJi ItmQ= jG>.G`iSG[ -%mg/ z/?XI޳G/^ ,`=* C&GEq&Ё0Muu)TWzidh/=*Ću[&+ bO)(urK Dsg"c̺ps.0+7vQ=0@9pa ZC^SUpt, r@'ڮN -2=]83c҈\ѻY?*r2'A< Qvep<*3yʀ1J;J2;*z+dސPT{.HT*Ѫ|Q CGqUqpnrd"P|54.G$St:Q_NJ!r$LkGY9*7QQXJ[QaLgw81]$fj7N|UL7TԛrT5hr)vAh߉n&3*{zRk}qvA,q*d mݨNooᇭ Q.oT1깆NG7*͕f̍*O/(ގbe0r_ ,Tਲc82^2qTSWGhx7B'"7*olF>QjBaڨ!EW -7j\Q~! p'^e˂7W!i*OZQ!SR%!zu s{ԓQqNDnT+"9pܨQTuNl"F߃F@屹٨;NRk٨NjU\,siT# -34*$P Oc4( UȀX ( -[hT416p d%J d3*H Nkx=h6nF5ѱI-/F֨&`O͑[*Se~m'l/}UFeIFΨ J`x- -%Q z -mgkR/4!)x,>("u.qb|n+颎Q鄍tc eTQt.yF,[,kmdT*F2"!!_veTu-Yi)2.$$ -FDX3ӹԭp2Y 2*t -2Qٱ[ъr~EUƍ̲eѨ9=ggTkF؇&[/aF3WWi* &߮Qy<\rYtjT%q%qjEFHyBΨ.W2fTKg+6@Dm ԯfT00pȨ|` &ɨSX[a->FUQezU 2BKu]Q !ß Qy/;["5 Ϩ5pEqV™&$_ipu^P󽮌jUۿ9pK_w|*owEKrbT7xebT娰zgrp2Q -Vn,ԑ]zzq5#{4ӯL|obTj3ĈQ '>,dW&ֶچvC3bc+r{¥F[s=kaҟմYSO ?*m+xQ~]ɋJmX^WFTUh/*cXׅS>|yxQ{z!}QY$*cwJt".aRW -t_s7gJ?Q]R*ˢHFhBYۅ F_$ؒ1Z:`Tݱ0rvS۝ - 0*y F)H9j`R+zfHWkї' bh#հ' 6'aT߁a:TF}=S {s1=Ut1CJ z?K(?)*qՋQn`G-- X -Ũdr_3F:u-bkFUULt92~Q-9iGjMv((Qo>;ա|ö* 4*+ ȳasW; -~ƌzIѨ"x4b65iTqdNFZQT!5*IVFŧĥHp"¡„ըne֨5f>_ ר Q$#CReQ1(*LhTz1 x %뙔,Uo+R67 &š٨oJsq7)EAM1=Kʄ@`4Ŧj{ GB|tyHثٹQ!jW!r/rZyG{A(URj^GGj`?4:!2+!=Hթ -zXVXb-EAu"`DϥR]V֓wwx=gG{h2>D*;TaS+3 !NSƣ҄ ~0@UH򧽐bi#uJPMLJBHFiOHuPYM*Ԙ$e*!/ S]Y>RjUh2-e>&٠#6TtV~5B+>R9lB/ H)^TZl}T-Eq эTcv*B&iLIezd\BY4LO*@:ECRPN~Idb~m)'U7PE5szB֓6o -{IUAO*?eEc6*'U&dO[āt WQ%Q'O0Yg!žTY{O*r^'$0,RF`Ia5uvI"ʾnTQIug疺jI0j?p}hrT -> I+ط^5PPp.DџOK4N2A,F!$1X)TɑujfT#+ETYNF 7iJ5*v+S :wTODZ+$Fl_KSA'5@(T$’0:Q*ei͞00RduXTy[;&JVdyTh%kviAg.hc.[Rd燰)̜J@*m!OK6/JOBiHJ~&Rёog.6(UjKjt+ARAns)ȳ#(UIz%DnRp'E3B/Tcél7KtbT -~bW(UCz/TUPs'%.1ՓΡ=T"ĂZ -6oT #:=PތW$A>x.pR$"N*Tcd625I} ?oŅ/>И,!*cR*h9$Rc0RP<ٳ]V*Dg駕 - Q]iR,JGij(ߌ~OJȇu~TٴV*- H&;TlБa7TT}R[!W8b\xZ/*G],J@-+UDN1"1W*jEe=KTe}tRm=dLW@=Cv+0SŕG=`f<]ZF%uJH+U>vGR!ՖمR9XOkbT"۵q -ܠDTf?GW[G&4_4DBɯT|:Y޿Ry69"%+ʎ)fWַsbzj^gJ!@(*kG) %W*Jo ɰ) `('Ǖ@9!t2| >܅5xY);\TmaʻmF'0=@O"BӒ;CaZK74Rz0U>\JL\ASe-1ՠE*Tpjb*S S=AǩLL5{oVdڏA$61S )TMK|@ ,{hQ[Tts4d@2"#Cc i)uSU^w( ʼnƥ+V0Uu3dPa~Ef eZTh7_\=Vw3K=%e= -|Q(L%\L<'*сD* *SM4 j)U510՞9% ,vg"Y:cS q S)ȘEd[:qa*fF|+g C!1ղ:"qԊA5!"lom,\Lgt[d1,Fw\bJbj3iJwFI(l&Tu7 -VK'3$G5T.::ڊΫEq *5xC*@K}I -?2r'VC:o'd*Pp,M8FEfwu,L)d7o)ڼ SYͽPK 2xyA1%`T^Z6e*}= &SUƕ&SQGm4PTLǦ˘y0SS$0)İ3}{T -aQ7F,ʗ{x 4D1J\ CU1>0d*)'Z=ϒD}d*2#UXQ2 q7qc#92`]] @i+ -Q2U"SӖDELuTL3ˀ_䬀`ɀN51/HT7 +wl ~ X}MuBʙ^ɯkdShiS)DK -UgSU 6?`St*h6 hg! -TK.!zM#PkZSL5tקDzRq)gvjI8t*ꏊr:UZYlia=Suy'sѩ8H2t( r݀?CQv>h1 SWnʩ=Fr*(,c% ~so5q1/T?XxЩ*թ&ɳOt6a_S;:UJTszߧz:]rۋQ -U:nhh|MAR~"UOu9j?6r>h XT3,VT!rDb:('u6ا zҧK^y$ˋ[:TB(ZsI^^7D[?~x@0jlT yjD?ҳB+賿)L!-ɟ-QΫL_cTHq9T7͖q ={ ҧjA\;;}*45ڪ*2P?*e`Ve8zUJnk[EY_PuTXS(a6$`pJ#@fr)'< 0k)n7ZWiӑQD,R0gL9p -0SEHP UU@,yղ^ad?\*j{ٲ -{9(2-ɭl5 'U|zZ|d/D. +CToPQ*O"nET5DH-"UlR@q"*lP7dCU;4KC94]:K(*I]PP~qSPU1ifB0o8Շ^QU_xCOMBTem#Cc@z"qVDբ\oV։b*g$Qe܎٨ -#n}ITy#ɩDH$$VzrCu(J5GE4 uQ6TU -ヴJ**d9L$о!VS[29}̮Q[]DDC-.v*E"\ UQ \-)٪@D#p_VttS{GYT&mtg ENmdUuiUG1ˣJ"B~" A U>C:ǻ|XzHxUD$̺ψ̤ao:Ame6oMa@k=g0ଥA]pG*-ؾxȗ4N#`M,e99(2t+]vjK>SWUQu ~OiǦOU5 -VF/Q|H~F1K3Bl樂-JUdz[-Is -V@U.\x#0`oѪ5z/eCsqgvfF2Fp `4yL(JF~gԦHr@wɨ-yLT, -q׻} -"7+XqS -?gq*5􈢪}N7̠qUG&^=,'!zQEpWf[ -OU4iTef#'Uy8 ֨=f"0ؕ4L[O@R/h,)׻ 3  -g}OلZD9U9dj5d.NĨ !ғ{LdȞgeV/ ܨj4[iTkNaŽ* V?C|y>E_VZܞB0oOս2XL*Txq3D' -,}  Ah[B@ӟrI׀P#TP_ -#$TaW{q \ U캘{ag#TYǾ5 U _@)/A;(pl^PU%f~"̟hwB]xB+"T⛏ٝ4 L E{֥$Tr!Ǡ''[E;C@ZFWChXSJ:U>NJЄhET-_$vkK,UDu=HGo#u){}}Sz{ -hKkK.;8VbP**U8#xYT|r^ISDTkJ}zW-9,"X ? -s>yD"K|)ȧJTUURϙ[Eo.dnC A*Y$i%@bSAyeQ:\ÉB |{E"8/6a$v,;TI_KWGAM`ߏbpm=.2K7["$B Omi_L4ج u`VaQ ."xы7qYY5H$Qs((qW-W/UZ]w_by.ٷG`K(d(iH \jAm(̳3zNW'ˁW+cF"#s:>`3" 2*Jg{Ns$>)LmBes9J@o6rmer65TkQTm$N6aŰ1i'jDrȺ^oES ݷd.|e, .٠*c`'0V-3WiKSE !8נv0w}وCFk QHmfR#F-.0x©TZFV.{vv6zX7H],[VJ:s•#/ NLy3l~Gӵ><_iʼn0x^iEرӮAX+ؔ Pq_1Nc $\Q97 ->AU:bxx/^:*W %H[b-ZwL*H a/kgÓnѤ~#.rJcZ Rd`e+ &F5+T -QM{3lj}Fs<6$^,y? -C -bd|L<ɕn>k)8`9I  ۏ򌜨 +9p+P,2[\ya=N/Z_➾enJS K)NîL[Ugw=$ސ ,ڄ,,e{%ˣuɈ#ӣԵx'n= ?(b ul- EEn7 T#A1pIE첕e#qXL"AĈb ZZjWBAMZ\Y00B7tXh綈O 84쨷;CJ1t+2Q -\Gym1=9 @HFBܕZiԲ|#99|4ܻ!1Mvgb2%MsWrJ+X{dqA=󆊧ANh1DP$'Z/=;Y9=1j (_kkOy$x"vZKJֻI!PJ/ϲr0lvP]3B! '"뾁L?!6KF0SOcaYq@xkQA(7Ox6^J0 K1~ya='̝ <O9(,ߘLYf$7ђQ`Z,e=FK}J kr|44,7+U3km\JɽtJ1u<8+ r.wd=τ.\_!S Ӈ2&bJ҄Cݴ婟,<=Jp>׶Vn_oejn)x3Ze"4 o}8 a< ɘ\T?g+Ԫ:Ybcz`P< _h1y^H ت4KۄNuNgb5Nqsd4PjeP8NC8>JG QMKQQ8k‡2kF)<)%}ɏGCJc/oZ(Ma_웕1Hu0&+Vp'W#y1ԉeBA͛H}zbT$2b)3#f5' R -hE4Bkߛ'4zэ 9&Rf - bȶ6,2ҋ -9cg¿Xdzq=j.hmf k+mNs dU!c-p%ĠNOtcdž歳 s{Q飂FDHY0B',x3.f{Xl&0E$UFz,` cC|үFz7A;.b+}.Go -D +-"TjAz D,Ds]ܶJT8"EguHdxng}&\ B#6vyk"vIL:J9v A|DOaŒWF|18xZa! ""B ) @N fhT\:Y 2*Laݽ 5OT3cn^aEP 7_B\iIlߤ[FjPQ1I(OTJ~KjR!:d,MFEI/P R(W%7" ss3z)/w7*1A37faʲIÄ9s'GhInG%f&,+m3~zGI/ Jԋd>A.uHL !BDYPᴧ!AG G [-vG=3\Yi:_IJ o[M$4aDD/A ?B?rKÄ#ʒNsNi -QGoW$h u5L,1fN!(%LS.h%.lA>1Moj#)W +"۠x9CA^KBe7ސ_vkejA$oڎKtޑ[E?c'_+G+n9p*A>M˴AWe>\ޱ8ڻ-t./tN*9PY;!ZF:Pdz" a>̫ -7a3 |ҏ q')X@ ]r噼׊Eņb*jgDP|jh2eRDeN5au(TXvj4<* -poU+KY} WN⠯S!$gXej 5*d^ΰTriD!.GKS+nZ0-f_ - \, §gBO$66*4xbڨ XI~.D.1Q -g؄4hL\ -uRMmT7Nn.&̝th) XֹwoTWBE\\)'Q`.j,ORrԃLb]);nT(aʏEVIrR*QC(o eRcIDfUtJf txȻiuOV -á, *8(\OCi(nϜrLqEC*P9O -.DC,Otԃ4E' 4R`Gi)uH6_ 13;_ pas8ʼnZ.HM F_bGRKű -\P?ԽDZ4cpy1pQEdl1ո7,GBl_a0y_(; 3%B-̳ҟd Wr;;aM;>p%2{.rBތLAi&:+FSjd\lS RѿtŊ4Qy?8v"OZ'8J!0C -\|³45^ -\* džʎST v.c~nc ˂ sb›ߑH/̮@-0nnl \)0ET}]nE)Tt { -NJg\4\d O? .}h7U^#'!fEf.8k}|:UG.zOAp1ynT>;&w(rIk5 %+ǀYOm^٘P'j{~f\pkM7@F.AYXAAE|Dal7 ѫ\n  8_ A#. ͨ}~ʟZ̳. 9aY\n`% 1X C |2PR ?V<{Y3xxwW4;pe<Ҧ_Ny?HbI0Ib VY+%X.̋ϊ?T@x~8.QxDM ?J$=U[0LE~Ԇ~` -;o}wHQ`Oܿ/K\wXk= <\CXdB&,iFMx>FXQlU 0CDu$I>AoAx ODK ^"{_܃4rLI?=[X#ZrUigoL |aK10OK|q1B~ez PdGhA`3"Uf 3K1u(qxoa5~(hؿ4 (ǏIõ-pD 1M3[KQ {p bo )8dڦt\p - p{3~,!s#.p! 4gȤu6\*:+8 X's,`Q9LS 8$ Dhז/l!\B -b|{r*?.p4y=5Gxx)^\LOc,HL-6 - -)s MN˹Y "'i }݈X%L:;dWn,yAR -4\ ~[PzpwbP `C}Yhy \lЛgP,s =4pq{Mh2ïNu(EP%&o:\X ӂ!r\Bn%€^-otd%!|zA(b?IJsz{>k6Pke r(bMMk7sZQ'uR.b ֜H%d¾Lb>dp-K@ճ`<p!C*.0Cſ[R 5sAlWxÌ\mG8Y.!یYW">3>%Hus jP™skN}63\\R[7 ſBe39L-f)xpQJ⏉ʑցydZB|ˌs -h (٧`έ'1Jĸj#ZB0 7`b;Nn`H\4+’L-(DŽ,3{WT p.$f%Z[0 Lp8:Lui3p1 D&RӜ ʋ~л RLdbfS Qmtedbٛ+.Q!z<.+ %,)@si#x tUոz-l/m​H"\Rn^ ]pQgX "x[yn0=TGCE׷c/(<]ڲ?X99N꘻o3-w;BT\B<}T(nxWE-8Lӱ+:m-mؔʝU *T{̧?FK}/s%Qxs*)l1Z/tDb5Z:^qғp4\!]Ct7oM\Q tY!A.gFwI!?Mr*/wP7M[͌@忴ij`ڞT'%B;וN;ܲ ؜c%XB$!Z=c&%@|6V&H6V~waNp!Y|,'L]1[tK:[~LƁGOYVZ^s YƬ[ >4$THl3794(/ʆj̺EN # -swp19[ GN N["S趸lO6YjFS\'BG`P/   -!$q>vhoRzxU_HUE F負o.bA[w{ :pA#@,NE &Ϝ2u*5\4Ȏhs66#tszb6883f_Dp"L23RfƼOz]?.V@:k"VsVfVK - )`/ jVK'NfEY-okHڤj~ XZ~j> :Gbn-!j-l&Yo}j+-% YY'-=Dyߢ ZUpE -~wVC3[̦TwH$='} A.rH ϯ} -"$KzhNwo1_KM'x):EhDc=O?-HF[R$!8smRG6ӚoZCDrefYT %joB㌠X:}tI[@*_BV1#xWY؈ͷ'=x3/oAV2DSB `LLg")%ӢLt--V\6/_bF -7} yEq,/)ѷIzoMkTh`-Hd pJ EE肁Li-wQU<c І34-;y7dSxCS`q(UKi6ﴛ|]X!*5 Θ;uNH/4A[h"?\S`/"8IY>\#4fS0c7M3 _boL\Fx@4psjE-G`--/o)4q|ݧc >Ss@KȮT@[K|͎;Vj[g-6 nK1!ܳ+*n'D)kI:šhn˖,Yi%-jg\VWҳn'RUӾ] Jz}" -.&-o+wGhc{FMwbaE&">BI!hR2Wc0CX>f9kHK٩^O'Dd̿,5iH1A YP0A2o+|T(&!W"c hr -v/Dz3J!NQ7$! =oRX0p6&`-(ciUC?vnXtLͣSVo#i'(ZP5F1"}*~to)W$|2<*x4} Jb * b^,|>#σYAQӣJj-ճ^J:Suh! 'Nu&K=D+Sσ\ Y<:N0<\ZDQsy8Y6Nm9 -D[}MrMJu޿krcWQ-m1iʦ"4L7aL3[ɏyToaAPSܱeЉ"D.<(=z%kyx) Kᘢ"%R7vky2[@[})g[ߢ ԳGܝߢ2 a806gye;U+ 6e8vdypa@^҆TH7<">5) 49Dva<`G[((*Y"MIvܬt媲ǁ$(rGh65߂ۗӳ߂X{Mq[J??q 넄 T(Y&[.'NKwƳ1`yPDiTr!m[9)+3XV*>Z[ u,0eqQGɡ("hd -CY,X"#,  jłƂf:XvX$^@ }*,LVB,X|XX 00N~g!}mWPM\I -Y -IW)𮘝,։+Mҭ/W\`+^& kMv$* -aŭV_+0j*U+L+r 0Bg"f&bud1=Vh{ab.7R'`ce竐¼ëHHMYƸ0z_ w̭6i@]W5i\WU opUS7`7TљTJؕԌ=`d -S>FXt<`11Sݥ"M3Ȓ -B*9*Z% `T\f X4: 61.`\ptwǔ<&$f71t꫇la,z!!ٯ/c|AL᯼3 a -@>wK1ZbM|Fl)LLPTmJaJA O&E%H -vGDB -r? -@a= -:; -%,Q`Q(Q}"E3r[ LR& ->ID"1 /+P;ڡ@C1ˆm [(zPhZ"D@AӬaAa]9B\?ہ@ap|l?@y)@՟ 4:~bPD)NڡOڏOH <,">K;@m4;A 3Z<θ d ;4܉t@kdN\ k@Hw:1XtB9ẢPCNl=@3É6877sB &N&4ML 4*@0뚏DF q9?? m9&Z& QMMԈ4ghXC~&V>:=4Īh LXB&oh3MLX:L)LLѰ dnp~ `vԅ(D F%h87A[h%XM7h:3$*_"#ha%:OA% _Kd4Xy'%%"+<Y 4yZ`K/-h@3\"%`+.-=[BZd"s?W?Kch :>{/K0f5z7,ҕ&+eT6{Y% -h1VY%` *aVZ_R?7]%T%j5sCT"hJ*@N2B@ҩuT hTB-SMGd6YϬ֟ȩD!EΧ%@^nfڠ$i"7- -@45D-844{FugtP"օHdLj-|0$:N힐)=+H@bTm/ @ohX8Q="N(ղzęyu#XwĻմkWQGW39LNVm&GJ[q#Z)Fkk鼍Ec%&F`Ј^:#ydFyuͮ2|uP0} -]bF Sl`DEdc`amfCuu~mp "{AYXDȼ"Vъ0+dP2E'mḶώ EP'ұu"x3٬1ʶDhlBJD-%lނdznD4mEEmؒԦ qL jElm"CMQDN!M'ױBmt\[[JݹEqø![hzafddtƺ VqCn&}vzۘnc ol&c L↨vMF -X77Dl Qy dAD[>oY7%JߪQ ߚ~[C憈5p7ivvn #O8! 7 -}H+'MC,:C|80ebqN bB̐-^!(;*)šbǘQJ !.^@!ĩ DĨ>AAxă:*NYғ>Vs g-FCܷ AQ8~;>VuȐ\B˻wG38s>*q{b`𧸸^Ξ¹:q8%:8J\4%Δ:qk&Ow(9AK[A#GA"v25@%DRDwbb#JR4n] 0+pA|O8` [%np~SゐuH)':.n6SQcwxHT» rr}Kr1.9&sA~r#\7!."gcmWvrB6/$,i+ğhj.hs͙ f Ϸu.3uu -'Y ^e¯S #)_9U\Z/!T;c:T '=DFJ 6՝4&߭܈)C2`)zAUa9?xA(\ HAJ\$ Jkn 8P( -0ʢAxM:^ -ѢC+,2ν87fRC+n*|tuR0yNJ>'ܦ: `еBxDxF'>&H7?)lHxVC?taStAԉ;Rw~k<4?VЦVC~ |u: ^!꺄paaX\h%uA:i͇^9 ᒈ_>l[}I) J񗞮.o&·= ( r`= _VC Qkՙ^yئKa<=9ti"@5,C(PG| 'Y֕z`sJ0s[9<s.a'A]ˁ@@) d Iʁ<2<2!a]%r 7 fYtqiTV] 8 Xb>ū+8 B%` |ɫ7`{uFS -dHnϳNn*aS źnD7Tr, 5ymԶA$p'W1۫TKmur46kݻٰnhx:`u&_n(6xa: +v 'ݠZY0k#9~Xûjgu5lAU3mv;o&34 ;80k4`Rw !CΖO4hL(w] ^b?1~gd4ݙA[ %@ 4PO3^R_/^.Op^pѣ)աO|b'-UbysQ|QaקE|zW`|Y]r>i!q9^`V+|.Cn22ONM؜i:k~y7Cо0̘)".C$Zۯ #Xe}2l26I w2hM{%CF2Ҿ-UE#C&!,[ -l~ 1|]H5Pp &c c?uj@*(h+iUMC a0,a Tn -H Ge } j5ykSI  ` B//2*,Sivb/#y> ,o ' c ^]H[ dZ.ʘ. >i龅Ʌw\rlA"B@| w ym޾ȓDvq-bNW \-sZ[ó&knwhh°2 yGf=f),؝c‡fļ'$SoiRn_++}°])][rzm@D7C)h\+>V@}xE -g -qPhx4U`FTkv*f@V`^ھluTH}1{GCsJNe~"T\ac*Tl^ -dU}c7'S^Cr@H}k<ݛ")l!hKbW,i}Ӿ'k_ƿTp02DմTH}ĕ7F_jM,OV-A2a@ZB CQ_*>+0MnQώJNV&a*夂8 G UTp>2TwŽQ, ԾqHtLSM>t"#M@kB -).b@|A@)4] -nHA :#u}PYh~)Ѿ%D*<;eY`QLI^=-h_ -@8 P!  -qpiէOazhsO'WvfNp -5g -n:KNU -P -EL -Q#/!p)r\R PQ؁9 -F!mFA@D0ڧKˈ%bCpjXΠ -f -t _蟐=?>i'p}  .ld,kk_'@L< V2;Tpn \l8 -'8TyB dC&XJmB6a5ε>ӄMiB!W~ ҞL(_1f!d} 7<^-K %lھoWK2KH%+a+@`0^JX= ?Ih$$h@$a(R" 74  ,B$L+- XtAB $}E`0{# 6N:{;l#tiF`]iĦ -6O}"j_4^KUg<#/_-s: Z"`X쩜w!p}Ke'+Fx`U޷fSR슉GNE8Umy -S1ANdLy#kB=p>l"P"!TCC CyF+l!\J!|?!@>y8smL.1n}Hۆp%3Qm}+}X;B}\4"~gMi\Ȩ'ܺMC{ࠢ>ֆ&-$jkDϫ!}]f}5+|/m5aqknޚ!@bhw!e!S!&B0 8k<VP -;@DO# B  h $?XaƵVwH?|L~u~^W<<烍[N>)g$>?ۃe`z`Vz+?< ?/G\`J8x;?;trwrCnkO;@ v\: ~ tKώ7:PN~ r91 -F|T'ȗZ90r@~ŐqЪ1(888(7 o0(A4t[7۠6H۠`Zmma6؀l A]ZXY F5 5dsџXw|ܟ hs! ~j)$AWY_P{AO6f~$@|$ Т ~WA;YA `1? FDt~@ Wȑsn4?J4@=U; L322*- E<'20<hd0ȠWX>gj _/ b/̌4ۄ! FĀE|O-b@l`Sh_�&3 y")bh&'܈l(ɑ$UM.$ &@U= eS1Ko4 N=O@bO|_@qu(``pC`nn)?A/zʯ+]DN@``Q2L - g˃ jc3 #Q~ {Aľ4 (rLz Խ@f^l/`MTߕt/Kq:~{y !]v`P#\O [ElRQւa-lW`f!A#ςe fh>')Ƃ|R~4,7ÂXU~P_CX;tҷ*jUA(??*MWAOYHU`Ș -)?أ'V]WTYir")wS@Z`ĥ)$d oR0 _SrņJ@Z~5|ÓAϵ?#4 Nm9N.'(MP-6tAwku٬D`%LN[8{N<%e'JjM)( l= bM? }?4;hGFPF#Ahs+6B\R!XG n =+rBpl-8!^[" P 6+p@. C(0lR,G~r=0 XX y3<@@QMԈo92ʏ).^@> o`[~Co X7`  $l@F_&H?RMn 2#\pSJ.?x[~Rce~w"6=T0 /60@;#iO }aU. \|-`i,@I*6N -Q++Ps^~gTI=X)0.?@JN>zexhy5Ow_kkJ -`{Ik@Ⱦ7F!QH(򃫗ӣ]~Oz-8yuHqxO - Ozp -s- -D(  PڱQO n,/`H?8 L'PO"a! G~H~0~DO:0ՇkwB)`Up+9t'G?b2tH[z)?5C&PWqo=oup..J`I &%=&>+5/2Zy+?_7J Fѕ&&I!o`$H$A|B8 *jyZڠT  Sm3aW'/ߐb4)jo+Yez]:+]vxE,FF@PM؃ ]ќw%P=Haۄ8L N؃ {@:tP)1!df˺θHZ򛄫Vs!@bPhͯK1e^ -`-vF6`E-VҦ5ʴƻi,ĴWvd"71K@KP;a˃+'"[ֹ;@$ oayJ hUX^0 گ%j6" PL~½^^ XG(2:PѠ9kt0c(ƛRq/ @F ԍr>r+5LC1\Bb%y:*K.ݼwL~srP-`RK -GϥLR.>/@W W֫ 0w?=oxpgn41jGgr Mdh\GzH$)t7%`X -uӗg`w%à%O@OlBEʦtQ"tvH=6*,5NH#.0^OLX+?|u@S*BŪxG@t9ԟ4l>d3`K0D^)^@,#z 8|˯NR;I'414H@@q5mPk^?.2T|,()-+! -\iX]t zf;RJlv̽B:TA(獍p6Pޣz Qw'!z1v'qlZ3w~yQM&L)\\X(OZ L{c r~ؑ~U^$ijFMg1PiA!Tͷлi rQ2 9 9ͽ3A Pܐ^zF||P}rŴtg:P^r @'wb  qsYZ~. Gy`$2ͱ:k `-ʼX%"jRGxcrJȀnY3۶SO"A1IaV -/K.߉4hwݣh$T{MEO:ϱj"Ij3XjP| O+}%Am#SsCASvF†{' Dښ1u -9}rZ;bGQ'?| -;ٔէH5VF_սh|AdG`B{h@3Evm=@7>ƃ9b$8zog0C].it,>RV βhGC䖡<&܅9wcdOӈ/mxb3̅a]&֜)R[UyǠ GDE&ů>#!e#msDY[e>Er" 0`(?PL$8104 -MYc5 Bg0K$)E"leG - -xcv _)U$J?~VEF71@wv /MAXP݀.oemB11>h3oT ` YB_$Vbλ'N M^;F]jad\iEG :=ѱTKNt`? pGf4=|" }svpySsR+ec%±#$Fne@ñR N$ ^=*)3(6lA'\$h3)-r@p5P$|6L:~iAɏp#ŭP -F@hbWI_h@XV0,Q #E"J8:GMb\fA(c!fƗbI#e\FT*oY.3\B%nu!MHFLF2[XƐ5uKlFetqukS/[XHTWURԹs0(2x<8~ 6" }2 }{Km5m_fAKѠsےWZiY'$PRur8EʕH6L{O&PꐖDEStY=ŎYSۊ՞cJ_Zg\M|OeLTksDVTlqj/~rpv:aM/J31=kv?_ny#`Bw.NLh5pUH}hƤ9]BsC%?EJ5Cto闐ƃ"񐠈7:T.Ֆ3 -M7t 0u(Y 0X1aV {4 B?"AB;q@PH -(88zZ2"x -8dY 0d-_=T(震*Pb[`Lv9S5+qiUcX׹>㔨ߵ>I̮4X:e=% A} !AWA,0dh^ICX =.ґ: -n@I9ؔS UD[]Ȭ{uAO*HeWJP PSǛ rO`)Xׅٓ]t㔈j/zBxeO3kE KtF.UaF V$*~9H641J01i`#wߘqń?nQ& Tonm-`cQ=b8H2]Whfw2ca0(繿*(D8pceR=AŏJց~&x3tlTMQRyUYEc@-VjިGdvOX&ˡ˸oVw3u{d9/96K]Y+*>J.CeƷ+C3L,BЉZ4*M8^΁RB 9 -,ۜ=u[7 S1~<~ux(_umm~pW4U +yAVĜ`D0|6.4-2xL.`|mjˉF7ܬC D105[  "qoA|;ǁTc1]U LB>5O%tdrQH4.hiS+>JVi~ݘMmw_)k@u[oEb' UK/XM#6 -օ 3H Ubc7HqtyU"@D+ZzL'42Z7N=Cc^ J90$/aa߃~i- I:u};8/UT~뷯X ʗB"XZQ8n8՝LxT%$QAm C5n> %;\p|U. df -yTC)X"w(Փ%|p endstream endobj 20 0 obj <>stream -RBy/X,;3 nI,-n$ -RMG.hSCx )BAHߤrCXS bPwc'.&9Aqj9liyeNI:p`\SoQ܄= 2ZOh)~WPe+ 6 -vtfM̙8- ^4&ޏJ7Qdn[QXjn>qj#dn;%xHnQwo3`<{4F5Jm3k@chI]9lҢ cn_/Oί 9b~MpdQӄX?!nIܶ'h -M)Gu0p@ \?>v -{j ?'(D/4*i 55Ʃ38Óu>E Ebp BjҼŠӖH-e! )E -Q#*ua*UH Lr"ѩq#hvg9;@ͪOn.ǦN ś\4/$^psWF.r/@HxyMꕛ=S^'s64OKƫ6Ͼ~+h{N'ʉu)fƀ\n K&Ԍb /(086|WƇ9> -_ڕDN4+ԥL19P΄!x6Mbfs2{_+rnEo#Y -kjnP1hH: - b" {lq@ScCkB yJsSއ! EB:! s pa ^ƥ׸)Fl^Jr]J%]M9C_sTIU"uoW͖p|_|էZ.r$/OIaI/%Z2bX hoX`gӸR]pfŨxDTwqkL7eN"M'WJ_t~cz幅DZ89i` {Нf@``͐$sgXZ?\&)#[h i)uE}$l}@Ue3RkM0ܤx_ƎЬzNgw/:Ây1[;+\(0HRǫa8"c{B(E:/?Jx̰G\d7Ͼ9e5cmENWЛ+tbm:jZoCNw{2C"RԠ['u2)0y.N-B תK><ƇrjKhgpL0/դd|UD$L*/8gxP!68"I'sD" 4 t Y 5k.}N5ܴID+LIFD5|쟚K+NË7 Y"Leqž}'=xat/L볗9+ACKw&V;V\nʕ -.DEyo'a0uͳPR. w#Zr ,$/uF:qAJS fJ_Z`aCXW#a] KQ\QXą ,+Vq2w&.jaLV¤a`|4.618ű|K+  X0L+3 &. 08qVA}3otm}x}UXq^109^  g\a҅9kAB)vaZr@]& mإQ^nPO}ۖJ%ۨa\c(jüm!8F쐘UbgbX—STcA.Y^158-c kƺЍU pl,sOc-/yRuR ܸ(握qȨ!#-ƴ1F&6G2OP2 $Śdd e#(#%)m\gk\Lsm\Tn7.z2 -{Ыg0g٬Y2߲eyճ)3*ˍUAg =~19.FW:kYrE=7kzY^r [ϙqoܙJYQ|f1>*LoCX)XX{g=3(M}&XǍ [`Q5.GѸ4)2.c, -<_1\R?A4˸:O Mzo/_4.XQDB!+d`&ݓۧAM"!Cy_> -q" t^dh-G&pK-X5 Tz>#3 +ZC&--LhxH'A ahL ' q7I-AHE4̞ht!7.D{B; Ό gBQtfW =P75qQF&)DTD@2w-E?Ίht"DтaN[ @E_jм Bt o\]TZB'w7.ZqaftKm\кA7Z&Cn=h&4i"V2z=r4<6kCZ=Pɸ `o/nL:eろq|s*VȏؠoWեvZ  -LkbQS΀W`l-`\˱齸[x -.~ PivX\ BxNruNs1ϱ^ۮC@ bٔN5(c^"s:7%:LOrc{ΝȸlӲZtF?r\~U Z(*.&.I_!:LŅŌDq&zݼN;gbIJ'ݢ2Cq[AHUXyϹs}st],.te/BD3t --Ɖ,Ʈk#NM]L]M茞i+y\}LnIΙN@qwfj[\ 'W:}"GsIgEI -VMq!Q_:=X cY'LiAPjquVZ]ڲŅpuuJ',U:IuMep2Užt,Eu_$Q\|噸ȫ$/HIKBN"."ƒ .u'z$VCIAp1PA+!{]ʪ}}@_[!z".쿮'p(^u~Vw&Dpaᢼ.];J=>dy-ױ1ڏ̉Ux0·溑Z -^G Jq"v4̨e0a9g0 pN^]k;ƙropg-w ]3m';DOwt뎵oѨD &."0d{  JNk{#?OGqT/Iq!i -_M8T4B^(. yx׊xYiy;'p xPDEox&CybW0x(^݉WFO\=P&.T(,$ $^)8m6xuݯ=Z< 8qv|, /9DJY+ 1[^qHy*=Ѽ0A6v2").ZHŃ=u9T\X"Q3N\[4qfJ\0ثN>Ӥf₄`z%PmOm ܳ= t/(.>~ Czw^B{UP\p"|m4|r 6+OvOL*ΗbRHY#;P\̛`?Y}]k}_B5}H;g[{S'CXt-ԖPqow{#d dɧ-0iiZBMI2Yjxn 3Jp}E[lQZ}kN\tCQ } -bԥ9-2-4.^>۷(>W>) =<߾mޖI+DQy;|9nxKk9S{H+Dn\jp!=%4Mj[2kmVo_rE2R>}>D),hZ[ھfGӭ>bWh*SgFMb`9C!gT+jl_ *cۗ/)Pyp{#Od*{`pQ?H*=B'g}E]N[V}[D6vk=gႄ_".` . .4B18σ59hWdsյOCd3|͗L*S=\=}€p!:|pS٧{.j_ >(Q߃ ~[ 1[e._\(|"/s_i<}:]/ i_hT RR2^3]r}Ev . G-\) D!sd_Z;E*>D_Ǘ:\>3GT'㵏w -~BesibNWA굯k*_}7VVln}Q_,v[Eɵ})#oϒC86Nq0 ݾSs55YRL2ie>"hpq JIdk\ u4O y\\" SB\1kp!FMCZ-z%<y .:!ҙy_@/Z6 hmw}!)d\\j\$0(nša74 .øf> L~sw\"}}? އ3FQr\{Y-M>x(ާ^y{uE|\4]6CRnv|$ -\>lL`ޥ%MͺΟ _:p>kapE=^.*<ߗ>}\I}mXخ7? .h/A Z(h .X?%eF5_>"cEHQp8C\%[}݁_.\Qp0)sJ_|&h+IY(@pZ?{\C%PF: kk .n04Ts^~/ #>]j$n=aV.x?/7>pq$ v#7N%TNpAK „ .V~%nm/"X3B譀 ǔ'x O Ċq60g.8$ǁogm׾r>!/}~.@ז_q}zOn/p ĴJ-#p,~pZ_o\YBӀUbg..܀ N]$T>~Gx.ڡJ7R(pm.Ĉ.O?~_߲ >{" qO;B`.D:eX.;Bq. -l3ga۱ʕ -\ \>G7?x.2+-(xc%miVPۓƠNq$)?*?{`oU~.S-jUK-I\}@: /Krtoq{R~ -P:d.U~{N》b&R,?&F+P)h?)s8'*I!+ < @Ά*?x i\uO8tJ۸+ ._x5.t#Dka>C)9 \I8//-8oE~#[Moy ~{o!n c~W=- 1)E1طoOߢ9*`ѓoy=v[ _~)[lϽ(lҤo_Xst9} շoϭoQU3ȃ^߂S%ڷ-(a]/OWoaД$炳HYE/~]~c`A;1-} %-!mQxlYA[߂xp؁-B>KNWa~o+,oy< $ar-.υ2oQ~Owoq}3.?d -iK/?dn'\\p8?HѾ $am p6-oz Mv'`boփxLBleoF&;*V-M~ߢjo1­\&? -}OYzX ?-O5_zbh|X/@n L#Ohev8+ʊlqf`aBc8dԒBqADBMo"ϵ2&f\tfVI'mC- &eoAoB(C7)U;"'[ToZLj\C:Tm?Sd:[o;A'U'+׏􌤰tm]PdSi&T[|"2_4 -vdMb1i M)^\ ye]IM**EPܿZH{C ;km'Rv4Pgi@₃Ơ4eoA'J.-]BD5r%0(Z1]3-|rvz@x*av`?r_fnQK[ %-Jm`5~^Q`k&$dɾ? |#{vzfM-¿<g]o@[|-N$搱u hP챌‰bo(B|6$i^o0m-)&)߂hSÁ&Mr -.a^ZF\}U"C> -20B(n>x -dMi$D)hߒp "R\7)}Rفf.'/38r]ۿuG%۰{ڿ p!f*qAMy8Up1٩wl@K3L9#+`hO̢%ѹh8J&`x#f,dP=$ pAKEpՍ.Mip @F* #'nź<&W.-N1+ \Ãf\q$D뽀zcCd؞4T 38RVMmx&X)^(`$S%@8zM\xwP =u/A.&C $ \S "*FpAx5$ǵny;@f -|\Yy -.9tҬ`(P\pׂޫ&PpAK+ PA%vŬ,=\V/ɂu j"=Pil a#TR]@v4zENū$Fp\;!8_T\Oܯo2C H\.h҅J?'- L&hjl]ZPixA-!E(s1ȥ*К/bds1vf\dSiC` 'r>.8W^p+r.V`' Q_5FC .xMɲҫHpQ%\ -.J[N;(!\BZ]d#Vl\0:gDS.\]b;wݏ{`C\p-#aH7!L6.kO"fr -V}n . ~ErO҅p - .@eBPX>]pKԸۅcE s. -UDʏTò;d2@;b -Di+l>iy8T}ɂ5&Ȼta그/kJrt!cQ TD:.4x-K - #>,BdwQ݅B#'\!LXRK_ Tk! !"}U.] 1X҅{ ځf|'a^&ˉmB,_U=!壑 .l"]qs﫰cpa.$_<0 xV7dKZ}rۯUU< U@ Tq#'K#[`+#lpAςYzzop':ye* LI. -YBwq\X̮ta%9F5YɄ'PW@F ^ְ4nr5I BaB \qR#)J2sfxEnV.\UFO"2B;#7k^4j/E+ЅJx{{]e˫3/]5$ ny(I0]|65nPYiLTk#keǠB"ˢD(;>O-4]q 09J4tw})o>T&drdk@BHB+E[Yc$PY8\,/sx -{pXj4c\==Y\GlKt. !aVsԪjs!#I/kpΤx Bm6`B -7 8~Byr38qDTK*\5'ЊHQ`_ikpXEn\ALA7: ƒZUI' '|HÔ?iA -|upA偉 @xU$اR.L -Z.N$!1ZF\ÅVbFRNqKDkpijB,Aǻ9¢|᭱ nPI 5',Ngy࢚4s9Jh@wpQ@\PbP; 5e*y2dwBHؠ,ujT2 JH7P,M#Œ+$dK *t.HY@u״)o@JORtld+BxrOΑ5i .rxnuEJ#60\J\hRg6=gwLM*|Yi\lp'ꔂ -&oqj:(\[؍o-9 ڏY>MvF!a/CNs׍0s.1yoB kl# (`nyU)ػ͹"p\/CGAB:pH+P7 -5e=s.  8>B'5ʛࢀ]rPIR -)6.w9tQL*I;7s$-ĸV'l.S3"|ރi}R'Ӎ=7,*_}C* A:&dGIn=\EIB`Dpr'L+ -%>k 0xY;)S{1} qXWw}I1!>, ),)hXxOECP|T-fGR{࢞:tNm$!PWKVZ*}H--!cަ, O .j%>e-&dL0c_ʂC8@$ [DE4[(W#d{W:hZp1W$f\QN46؇} ?/`@r톹|a{#d56k䗵a]\@_WC{ Pfp1W<Z@WD%zM|ZnbBsi3J -DL`pdIXD-H˶WAM]A -|E -q} - .Y,o .&yErKӆ3L`B599x`pآO41`{1[ܤ犻XCB3V*(jb;?uΤ-\PCUvҀF4f"Д ;E* V W9rzUoGpzTSG PU78t"VATA,ZtHV4%e qWh?b7Fzx DnHt4yeL .uZ 5ghXI%/r]d~FQ Z~2U> fAihm+vt8wnO`fvXG05\ -TXP1C .QY{ Zd@`pz^XdYF>]$06G_|彄^/6\B\7t:֒(]z<wa?5PМ!o Z -)-^ޛou\\]ք=i! -$0qU*xKIJl`6*侔$?0#B*D|4־l Uy=A4&eL0; .rkq3 OP"b.Gչ .Mfs%Sa-TbLȭlԭUPT!OW -{ -8<a@8X*?ۑ -%e,''<%  rtϯ |vɦ#<<#\<ău "Y$`5[p9q"dV *[]-/TBGV$Voc_Pp19' ~ēfc{-@yt$*!(xW>NRLЈ2` ^P1o;Z蘁qŊ'/$ r0 ,+(Ì 4+>`eqA4`znT3^΢H/: 4X"~)$=w;mEID-XECZE,j][j,WMhTh&`@#,E`Y2vQ|~.IJ(i|+Q  WwzT2RB# V-'jIf +"$zSU̚\5%Z4uAf2>Pi3Ģ) *RF;R\0b(%+*=7(uHi劆mFt:cױg;AO{h!b -͠~"\` 9`{=z֫elyDUFjy`A{D>+E+X!gm[4엣,UDܾǪuկ]C"$UeEa:PiHiXNxWKD -S7VkOUKRӰD."? c(%+<.$OAZ~{ =g$zVEYZU9ޢתjdVˠ@& *Q Cn䦦WEkv_-}]-6)fUuiXMny)~V?"̀.>J^CtzeRC&~IjMvW.=Et(\qdP cX?Z渊Yܒw>3d Cs'gyJ|"%*hEq;l8HbvjU9\FJM\t -D&-&a2os\a(-{CiIdG-C^ -f_;JMansM7ɔ󓒠OrAO]-$v)Se-L5(xp!6[oQk4Gw #a̢`x^5'%*kvOĮqWt9ݲzAoъ]b(J]6 ~T?C9r'+]ZO:gG$rUGmuZ }N/[̾X$Q0zYIfED(mp -J1UM]̖JnGɏ!MUe[o;#4 ߒz\WSM _q!9Glc]*nU6>jZVԤ;74S -]{=,_]"i>.y.O;vi>)~L2,(MChJ.3ʞgm;~Pӊh)$ȧe!$g[KZ͑ZXil񜣋~CS_֗ ECirV-z,=N~:9p%iEG9RMO)].qxm2!|R % ESJr'zS(٣$>~fۑjŢ3Lv%>:"N~&x}!}P{zWZT"wgIV3Q>Sתw% -^Iz;tMU-CMES.Tgg=UӧwG6#qny-T/+#=b ;wFfsr:'g`Ozs,UЋ9:!˱ˎSj _MmK7Ǽؓeuj9tJ<5,I ylp掋d~̓EHr6hv8/ZVs)MWo:ǻzг;@$Ѭ{v}s͝feɜO2I93IJ4(ד(5]m}q׽-/ܕ7kz`6uY[/cmb-6@kGCz}NrĦ[g>ȂV̢\'CO)fFJO9`7Ū~)`b- \P 4MkzZ-b+UUE)JM~Rs/ϻIOK]R (5A|&̮^Ģ UldW/ۃ_q׽gn6gco\wr: -TM+7US9uI9dݺNg2ʜv -Ͳs9A@ ln.:pv8)gSwƙ)T&͒7TNGtdS;46{O U/ul?6,7O AjzF%0;Nw]n\gR[v8ff:TjeNcsIQtG;4Eˏ#u,2w܎Udٌ{-I"u!vG18^Dل]\qdO3:5]`.r6lo\qg}6vfqߗ^ׅ (T26弸LtЁlσlܲbX̿N:(EIqw=g'Nh:H3pRy&H pB܀| (,Ws (R=,s5ʹMfnۚe0ǹjuƕ13Ο:Q_C9O'Ͳӑn88XΆ6YS3ɞ86,+7qAPZAY-k?КZzʛ6w zI;$Do0G2P=$bBNZr8f/%"m%Dܜ 7 /5洖3M]՚7wmyƠxv8GoYm7Ԯו!7o]k$ÐtN+_c8{mI3ܡw`ěFw]u𶭜N٘'muG8iҟv6ݢx$miyWZM?P溳(@FӁ95bikgtГ7M=nyƹd%'Nt'N#u(P̞gZ_ QΦl,CնVΎw7W, 91r,+8نre! -h_vzP,Uaݲ }gnPGE*cjF`?ї|͹_Xv6*gSZ\CddUG8gF6V`%m0AݲbX`zަjT_aeUKQO2R^6Ŷ#4I6ϣ@)׺쀤Z'Y4`{JSW Hu^M;c]?tߦ 2A/Ó],^" $qS,Fjh]=jhep\ut?;a.'Ei-B nz`emQoP2bϋE6s}̽2Q;5U'wt lG{͔7'o[٘b APIwn6fcn6$y/Yvv:ggnYyNu8dk5mh7ex8[v`Hͪi7^WbS>&q6nZm-ǥ/Z6fuw fcfm_GZQZ帲!99,׬sQr%v) vF`?בR-p2 3ο3Z=?s{Ql ٴ6w[i7ћjYyuކfz> XTdeuXw[y}Pq~eD:c ߭Cݏ| d 5M2dm8Xg $| Gl*ZQ܆T? _?A\sd쉾E{LS96묜MiyꢨiiCnP׋`ᴚv!%3n6iWr828l@r8ha 4hK;l\-kL¿!(sijjZe**"5ő@v>(:V}#g9-+7(ɑ8Mx/'CPz"o٨ e} 4*S20ێm8= .b7\z:Xsa w᪞{s|ٴ iqA@E{tQR,+ _".`b]F'05_iZG8~D9֩E!Jֳ'=H~j^g6VjQce!i;&… tNI1ѺeS ⧗u!H!)s6?"$ι +ov܆r8Z֏biE=xr[,]-#A@\ ɐI2ɞ"ho ղ$KNz ZfI;Y阛uֽS29CwHΆg!f5봛r 4RA oNCm:,&1pםy/ǩN9-zΒ;Yp E5M{>+uEqִtr@P r,[~/GzGme󁠨07IFgiR/A[ɍSj#$Õn})ǁӅKՏz-f.(r8Ɍ@( \nVmCΙe  ACYv:f@Qn6jnۙu=op,[3κeqM?K쯓MEnմ $9wꍳ;/(s[z+~}\wo6XjRV[Fj^S*;%C'y?z7UiA; Sϓ rX",&؅r^%viq]L{rd#{epՠǣ$)v] ]kkLn;GOY WNMs7M*ɢz\m8fq6)iZ!uDuj8An@C82E7LraMGM9 xR܀ !5d}9ղ6&w]_u(n(PLJq:"Xz_>]Nz Zn[exrOղfc;ilX-;7 ^!2Y8^n;;\s/tNAAr@hEL/iUE)b֒YʞGj9R+mbU4$z]~Y)G>q{:pli.$1B+6rUx3˱O:- /EiW+>&{5 ' ٘qyVueC%n۸ټV`moJ!Xn6uztǹ6#=~3a09Aco,qIİGn==$Kl`eSL$*C^Wj_`]SzUdvK4O~$:]Å*iR%WU.H=t= 1./w':U{?&2k~=wtf vo{(4Z\iV-f%&Ő0~&8:I3i(ҨMQ#5#*|< C/8?SBiiR$B(l\QS܊VT9ƜF3*0Goj5{R/T1U?ɞ lS>mm(Pc9+~E(?sǽv8iv8ffٸa46^M9.ִ6ZMs5M6y$Y$r ,GC/wJSr8)Ԟ7n6h։'G,kiśv8v85t"45O܆jQ3yq$',=#ȋ^z|`feI_iZkm"o>9ڴ6Z`z:b`H=U*BKVmsڗ1C[r+S:ժ!fN*uH[宨VM]C&\m4^+~Ij(K~KkZ{5QkJJKZզulMStAB*R?AAϞ |M 5A/Ī=ԧ= -Ms",q隊=s~Ȑ'}EݲR<Ț[G'IB$g?DjM=؏_wwA(9 aŚXgpNΦlfNpםVSt$okmlnOIڞ7oe(g8av6֙=x`-llڬnuq4`2yzH4N'4wnA3 ] a퀌\V=kuoݴғ?]{q!e׉4ն(Vb {C' XmjFԫ)@=-RӈI !qƒ_zא5u)hEq|^7ֻ. }HEJvY3dĢw5=fɏ-Qkrz'su4'w??)JrŮ|\rAhWU+mueL!}]5S'%Em Q˓$i/ejUHgE]\0}/:vNǐ 㷊&+wB(b,BOIzq(Wr6㨋`}ICyeuϳ%=/:HuB" -]j>(f%.h9(~lqێJT}cx4m. T/KqA9DtR'pFzr_bn[;Y鰙6w4!H_yxݦnPZ6Xܖt?QjTE2Gղrs\.?)Znur1$j?"sT[1k׮E_Bx&JNزUUѯ8`tvL%ܛ=~zzNGd#O3赜f1GcV9^ $U-=Qr;dYo˓(vQ,nd*ln_[zW5]35 4;\ZRKTܔE&fٛ^taMMa,g1t65/Qǐ$J@mN29dL$dM$Ot&meeQ1b -ivdnӼwun|[w{ko>ogloɾkX =iA2=Q -i}47o7׵m߶L5<{z#3r|ik2LI3ïFLb%ޖyZk]uu{oٶsey}]q6_45]ӻ}{oseN2Ӻ-=5.466.w[qwvu{oue~圷e{sw=ZouYwyY{9y{use{zkYq{isokis,V5UeۂUմxU4IϷY99"qcPD =1-,-K7^mU<7մ>]yTÑGڪ֧kUR!zNr,K-3Ɵdn9YYq6l& -{aÉ2R5, 4r[h`hdDx&%ED Q"2VZH"SL@@NGն3I IrǼ4er<1zXA45Rƒ ~C2EL+-vh1erL9>Yymz`^w2UIj'ʞKovM8&BѾ47-Ms7,8#|&ϨQ+Eov:'@sj0>d\RJ=FB^V(և*0+iA:rٗ~~begsjxGhq RG - -SVStX@1Dk>Mc>("ƌ -e*϶,DB^E(n 0F]侯ׅ".Jn) -!.IGKO~b1N^>hB>a{?5S7ljy ȸ9 u(`hҢȟG=O۩EE-V!ޖ-P jJQ]VW[ 7Q3ʹ͟1;fa";b*&[bqzţ^Gb \JR~5,bP1ђgMC_Ѽo/^7Iy;60&*=񣞨An -ԁP`3RB!uinIܱINZVq^&}Ut zsBńCyCͲQ;3y,* -meN|iUP(y$ N)PNӤ?9{]8U"ꁘQI"G ,8^ym0.UW9>'L4Ng%m'qt` xĠİF)|WzP4Ͳ&%)#n2٠7*V%(1-[I+㓬V]c|D)HBb~Uj "=jQ-i1gygc!{T,ԾnZů X;BerQ Ȅh2 B%箛O2A"YB4'Q);P0F *?1TrrYJqsJw%Ŀ>sE녉X҃ JW'iӛbEgeA{ 45nDZd%8)2^#+U{tEȊefoS kk;._TR1 kSqlaM߸ql/E=5e_> )ԎhAIHpYF5zAB-vY' c0&8 $\|~ENfE2' \"೟l`߮ie$ )R@-Zjq׍xm2`fV1Hev)r HHYaxʯӬD*~MvݧU_T&}V`mW3jmEnjMz.\&*'9NHFZCo %t̤F)T$V-VC4ΣG@ʦ亨>نj\| -K-(\jP:4(Kʊ_zy/R#-V,KnaF?jUxrkש]ݤv':iZVٳ)vMp喎YbO%F 4$><9$jqᇇUEzUS8=8^PAJV Der`_"P~m0v$!lN4"*MY)BmL`"%(vܲ-p*XZપr0>!qd/QTܛbH-Uq+s}Zv =+ڧ-Z~Bx~FK 3c%"4+g4ʎOuqeeR"IE!L!QUݯ>ot^iXv8:Rd -PR +^~&>Qr'->jv]v})m]dĶ(?EMoKZUۢ 4$o ԪPڞ$=):O$#5(4'߄$F|A 'IRۢf24uV~Z99^ˆGEeJYrj,?:#gIQyٲHfz޺i%cW1ɠ@Ӕ:b1SŪ"-䷕ھ7`QB{$ϣ;pɔٟ)noRP.QY{i@HpLf/ѡ&qS2f`q -8I4j`8aQVӪyє.E1 -nSrۢEzC%dua+S_R͓pR uSWUO˞|h2+#;NF\Dox>G?mZ]몄<.{ˑwvҔ=^)P8N]n ~MG՘zQ$X,T'wNI~YFOӴH, ~=,+a xf,Ng}(PzF .|Fɰ'Eq$ 5m_<߰yV..Di=ZԶ֤vzY⣨rY F}FU74ޯE%~ vO3><=l{獚)^}O<}*~11pԞ0\6o-Y]jUӧ iHMhMsC_?uU˚Ӵ$v8,gs _owIeɫ'*@b%;$5CDvb*@U/=t@ 1/*&.Jս,[A@Xv}þ9mxn+iOC/^:rSݶvSS?G\d4Iv:)xy /T-눍㣘fYwƁPAm_&t(v] l9KgǺi.%5b(g]H=cHRî#cjHfmi\Ԧ_ TĀX5C[Ԫ5)^wjq<⸒c,I%q"cRcξZu5o趙Yg$?{RˊVOћQGVM0s=OOۦ?olB4Ϻ䨧%Ϧ*^ٷ}y/{VA7JnCi\[UU HUIKr;,ǒCzt}T h$m8*f9௮fvkazPi^hie1ɰF .R(@'`u0c)r24qhmEk{r931jR4'K4Bpܫ+m#KCt@1b]Z{^mUI'h;Ͱˉd$Մ:;9~N4Wj۝$ߎC. YW&pr$b؏OvmcV.>u$J}4QTC-ʈJU 0[,~*ljNLqeGl5˧Eh]Ҍɑ̋6ьP7P)Mmy -GT$-z(y-O&yjr;5i~j=Yg?)`քGx:n jD$c{͚^gn~?5}e٬DCF!rdfn]qyfq"w] kiuvwDնB Ϟ8R,#oL,4M2&bSv8/`-_WSGWXn6=ce9f9N>ˮ@&njuLGԮɶpK5dn|@0%˾wq£i -)EvdCbW$!=VTBpG۸(4)M9.ţHa28V|$Pt97G 5uk]zb3>M.JVܰ?[Ut=Tj鹩myxz ㈗=罞ǣ*2N93<ݻ;WrLmrGUJ먷QԺXN EK1r]]h[O0L&IV_U>MIrp:V =<5K6팦ڲdɒUy}ߐ uΤ؊m;Zx'IYh~y,}V)~uM:fm6vI&nMjeT WC JjeeƣzeG~>Q8 Cz([yq>h)1q(zRL:g;LBV6= -.Kw"-+Ay+ɮ_0yƥ鿯Wu!u֭~ ?͋|,,#,-")Q*d^9yLB#ӇT=U&ҍ 7nɶ g%O(")Qb. -aGH0 -VIBͷ}w41H;n< kHi=ò> x^D.7!=,~^Ph 9nPcr[=[8x۳I*_QCOW>M_0T=7E-KZ'i9]xFuo3OWD@6-Z+09ɞf--b`^FHDF)h;fh⍦X.*`D F X -d`@ h0 D$q,j@DU/G҃ƥ64PHJL3v D&%  @ (p$AHL`@F >IOJ~T.m]ӌ;$ 2N. |F!X!GL -,).%=?Vvdz߿hzvq<0, `0C/! -Q0 r0 q1 -񟙅qSOQuM?0Vj%b"CǍ  d C`- LQXaZ0ކ#y鶭v$(<7P.h! -UB 1z"%Z!<˵ylPϳO@(LA -O~,`D D0.nP##F>a52£ Q>ɮIE v $h@xH\$f.b )I!qBOVBM5͗u|X:KX2P\^R9aY9V1%y-ǯD1 T$4! ]5 ! HX ^2hxN e3G5T< IȀ ( <0B01 f-\A eAJhBnp4` xbEJ=J[GC!%8&X -GxB/|a b' g %8! .A -JT1FIjz9/{o?M$"jph Yƀ" RhB5 H`X + -N@ h`1-01)*YU[(p H(! -NBİ*D! j8 $4A - 0 Ƞ8X, *VލAl"O^]aD^L  N,D WB*@aAA`+` -KBZ0 lc|PS|ٴc_FD@;-A h)4 -Sh)\ -:f9a *ZbXQd:Y^iJDv9x ^ PPB04A p" GH@h8 7X(;k$ ?$ebEI$AOxP0A Y^$`( C -#* -8P%&P*87a -TxB~.t PBT8Ma$Ƥb=mja(4 DP4D -U5 a؂" !OfpPX -VZZV-P<צ~_*HI  \,h! pC004! -Lp-T X@@XPP$ Jd y@4A&IWA4Ѳu# Iؠ -TЃ da*v@]S5 L›$Rt"D"̠@ `ˆ!t`NV#j% H[Yv: tEYEF",)P`XȂЄ%p anj.`X̰X -q& -zϝ(*Jk2T@BlP!; R 8(0?x Wkuj5%2kC2ZԠ- d@ P qD<h@$/XȬȔ`#'H,q0nF1xA j@P* JBfI]DCqtDPxv[UixqAy~\ܲ>_3pIUA0d՘^U{6oDKHHQšQh_׹~Yv>EyFGDɊoo@Iv\-؅ܶay^I -3V"1*ӊi -H6.GLkrRI'˗~5*SKښEnשX^Xv2tFo*cH#QH$Ot<_rj~]@!Z%銡vI/ۓeiR)#;P Amɀ!Bh0gxzi;Аbyz_RˎuU) h'li,=O7H|tga!$|uU7Ӳ#m߾9ٳ+,\b%[&,=*Y$Q9m_^9%aZSŝ$y5Ͳ6Ǖ Ťd+$2˞[lٽa(`Tf-7PFP>iYH *dw%${>/߇%`ИOH9ATq$9fxH"2yB"@mZ%->D,"3^&LJBV2@YhN"VxR+O+bQXjOOn8*8yyZ4#:jj'=!a#nC8ze8 Lc%d -̥2 JģD${znI>~DA&飥!z}d1Уht)q[  +IKFuY40\$Q'|g%Ft&?s -(JDCD}1}NhW54)_&9Q}R3~qL2KoQx,Ӳ#j  H"cJ/;n@r2 X^dw7Ő%ChcUawl1DR5PJHqLVD!g&5"^YkIϑpZͧnYGLKxZ>;^U!6eA~1*F_|%!gM-LB؁d3(QWʈ4JXCɎV U)Xa"bćpiERT +`,Ɓ#@ V.Ek$T'WMUU3'ٜv%v&M]xc x -C IhAq~$8.yMhE@4 WSKJ9<0&6TB`ZJߪ 7- ut$u#.T.^"ϪJ2(.-R -S{,~\m&Xe3QcE_6n{Jo|rR,jGM+ VIųbwx}ifB\)zŊ$lhB7"WST# *JX!QdP)A;LeOx "bJzvrJpJ"`HؕXfF3*vEl4X$A;@{&"6`Pt1" E:Rpyw$%~~!=~g]5U@U 7m4 [D;4+-Ҫ3*V+ӚU&s2CE$'~y0b드fyHnCK#?cEEp9DS@K=m*sH2R-0 i$?`ZX>|1$b |"V$=X cGlo|QX^R,T$jB=4-X2dl"m132X i9$\ď4e?C,t1XE̴ד*C_L*ҌW -KmNwL%$H+&5 -{>Qb"RU%_GȋJÿp6K=k)fH"EbhT3,P -УNjQl/\#MA+8`XFH" 3ax >Ө@$GKD tLy6u>EE!C Ǫ4R! ^y@рfLʤ(tAyC͸L&ϩyb-nD=и̘>*R^+J O yP>{ -THk"r#EĄ"  I3f|h|<|jڴ\ŷS*TZJ;JV>HzM0!$dGzey9b=۝Mq}HXJIu#m᳉9ر *\NkO&ڵ!C dN\L.>Vǰ\O. - hRv~)9ˎѫ ؀"@{-HX5(\L1QB'5op\L)N_o4ϪƠG -ɣ5*N>N̑b!:5 _FGO]>)>u)Z0 -Oh^B>!c"-[9M%+|NGhNJ)RTTMKt1\V"ѰKf#… -àDP+DV'Ur|U2ˊԂe,8e!+`SU)T"hduH<9eW VJ -zc"RyL>C, fIڛ&kw0q1FGOO:@ AAL -*u1J`V?IRHIg+Q XFɫ )Eí{8`(xbN*QCһya=`- -vh)! -/f`F] ]RDa(L7JV= aшZ82TQq]_> -*cFI7nK3 -5 _ۭn9T5BJ4^%g*=Ƀ# 3?P`/!AɛJk{Z(Uc;}'Qj)Br:ſErZeˠU+;kɿpbT$\!揖?ZxE4c^ۢSd;  -Meڟr}9Br;/ɗbeS<;MZV8)`:90˟2LO*,KjbOޟdNFingEMCmu#-I%EHI4CYhy]NVmmMIkR͖UR>==2U'^8f]% %Ii9":V!ҧ?ŕ/trIv/:TڔE;)AȠ9b8FC$UD $dbe/}> j:xXJ(?߲e${Իҳ$"0Jt['O~B!ymjOWy'ٲ(Aգ_eQdD:mo)!Ԣ7UrEɋ :TF!W ذ5S{O'kes!Ipp0TҋhLt8r>jaMr4 TIfBEKDӺXeaͬD/$j 'D ;q6ъ6`Rm oyv4_~P3dSv- ֭@(_?{Ql -ie;6r679=z޺#&+a_Uۮk=&G>)~#gSv:t'DUP9nDߟ{_zN_·|P㣺>9֢)hMOs7Њn;D0n5AiI2(w:hUkAo<MK2di\5ӟtR/՗?UE:bUb*(&jSz}cݘuP{)9zƠF+V(خ{ܖVSW3S@ɞnH}ʛgײ}O7ۿO8Mtp9oĺ tԵ-aY~S/mFlMWۘ_d/PE;ľ<~^Y,]1;q>ٟ=뛛 2fN!^:rGUGPMF "xBB  Ft$j`LVYqrEkQp[s)/i1jqD Hv -^5HGЀ/O~R{\1}ږh+*&Gk/&%B - -P .($1& B6nj9,@O{ҽ(˪P03f= $ <@`cvʏ5E&lb]R}UEM \P1N2PxARL&(H" \e -:aogL㩏b+ 8FB6 !H@0  @v#2I -()5LVPRRP$@d!&MKR(֌"XH -% -_a@H1@ \Aj1`MKd>İ Z}L -`bN2S( ؠd@a>pB-!;6lŧdZ`1b7#`|F` -K ?^"ȁ0 @A (mAvYQLV~h'޽2P!FZ' 2@' -\@18hbC+CLx(vRދn>J?RC bRP@@#=4( Z%4У.`Cс`$bXj\8(zSP@ŠOtA\gvPl,SIY:OyqM#P%@FhGqBaа$^yL}^&R/=$1$V!a -~>PX@!dR&f/ 7-ۚo.ƔWh /@< @IB*E< C\0ɢ I-ŜOovadd@  IB4p `@J~,QKⱞQőU?rd6YO#*XoPer(D?3̸CYpR{A2l㘾Z,7|a 0hXE.z8b$FFifto=KԺLsdv]vDr=2QqCF*P!(EŒ@FHrP4GbJJA.W44<IRy4 -@ %BTdؤQE%FT TW~*E(Rֆ[4}c'?u͒d# E KLNtsLGST'TK( -oPpNVrݑ;OtlC0EO-\((&MchHõ4DXx AnDAP)^D@c0hXˌ:r'BYT;-1@m\*(@ K(^Nf6{b!'nל?2̟b -j3?ѯY##-derR+rĥyu>SӹlQ6A0QߖZм[ɞ@$TrQ(QYgr3F֡d'@>N% -צ8vkTuw ϕTyk?:#knan l'ΌӘSiSXm?"|QuDZqy1izA3-(z(P \eTa8t -IȋeRѬ\j_ Ey׸~~NcGS5M:-z! ŋ:^fOS2 MA'dJb˴PmsAB &Pd\#O:(}iLN CC:t6˱kY%=g";;Ǯ|vxX[7reD9[܉;gO 9@:3T=( cycg+6U;HfPlL6y<<:xqhon:l'@M&MgƑ-d}o>tz~%H~Ӻ,ɳDw!HY'r69e}QOLŒN_;mk_zMu4CD؇r'eW j_]]|?̸@4!PL+}EQ;?vO*FWg}t;OtCstSI4aLy&!ѕ?O,aX4϶yr RhQErM͒&:,* -/l߸&.V]VqܧjwX$YGr%yK^a\.DMV[zeԕMD7Qul-(%Z)(l1>~mFɁr(O.zLa e13g>?,W砶IRGQLp܃c |e[NJ#}3G{^.z ,1 mzTn׀y ݼl.~7"gRExC|:,vngmE58`HD;]t5 #jIJ,TMr٘#}/bqS 't?׫]n鈛MwE›jiS\q<̶mS ;q۫럪t0RLj}?S}iф?/QT@֕mIғ?zhc?ϝ$CjjҺ7n8g}G:;Q'cW%RJԧ1{Eϫ<-P R+n`&9 q epL7o@RļFL3sS%%_zח}XH~BBԠ"ťc7g1 -ɱJ%iֱ'yRz/͛a^.23LKJVIn~B"욲4yUU:*E~~j)@*˒BpFճl 0RxY! CpDODPLǣI殪!N6 ]Ed ym$Q"27ELFßٕWWS,~u=mV aㅍw]-!bHG{,C-äL4iqLoMrk$$(J~eTS,")wyuDk - Sr&z‚t}&QZ7ҫڴo7F?&Q{xEjIq?IB媚B򇘡JUC/}WG 7ROКh9+{~b# 2!G -o:t'Pt(Pey!†VN'dCzcmꖵfB -QIL` &cĵ$~<œÀvj.@BqmTȤP(hu&Sr62,b!1p\m=+D^)RBdN0C1Vy7G|i ŨL,%3^&OnMG TĈAC 00Xv^J+-B'$A -`^!}!J`AC#dî;j|-MECF&|Ll-SM=.u/P,,30Ս.1$Idķ~ɮm1RrcښXuN6f_y.fc$1 W%!]{bEr2DZ[ ?]CuBzigjEtڍs9n45Zr[yUEp n,5eݴID6Eٵ =療6'ɶQBu(Ҡzn'9^PN%xY*íC3yUw-V.J\8RHhB -lwHdDAݶZ$#5ա9v`9 ̎u ^e|` RMѢ%<`F "Q|]}8@D$:2BU j-`BmWT?f^/Dh=q9?2T$0 <` DP H/-⥉@ED"8!ӂWH+U賢B|jwi~UB:^wt瞖-ɉRH>TBiJ\Iqč0JDPu\e>MS̛(02?S9KT< `]D={6i4z1N<=J|?i!}T& -5ﯢ;jYun}XCZs;G[{}憣d vUˢX޷ն ]zjېLb#y]ROr?I]櫮u?P7OMb1Q<ղS8Q-%~i&s+"Bиf77T=xLw>7☇Ὺ%PH @ H#(#w. VHbGU !h4cSMQ&dÝ81r8ܶu]3K!Č*Zui|>`D%V.uϧ3'ɖZT0LJDl*F^C0plA @&"@<2@`uKr$!G$za#() Z5EVZ "S];n?µ"dò+Gh@2<+J*"f&nt#Ȇ$)\,/I$0ż4C%WwàU -6=, -u=dD`BA(=_ߨ}9.tMk - -e$(TC -,;ln2ZXhDHBj5ǹܦv8-`.&z7O,Q~~h\p9Y:j:#|Zu2(,D?\LVD.`QQDL~9Nd ժ;l3];Wy bvbF9bЋSN3,K)$ ly_XH1U Pq`k% ft?7{4LoIFIk|0?,Ħ~!! qFZQ\RU?,$ zꦽ^'!Z~ X5(%@ -H4DNEXABF 1b~ȜZ-e%EBt=,ݤCyS4 -&-:HNp!9Wwcu>^ @ĸZ+b+"n(Ƌ%h3D -hD>ZФ  … -U*hZuAM=cvϲ'yCOd+ndd5x@bd1ށ慈-t\9m!))ϲݣhv8zYR?."ҏeG -%nPHQBb$ $jYN ^{3CʬCӪK҃,uϺ 7@!1HA- bה,9/OS;BE$dL"D -T#oy2SSGϵFΆlZΣCrwbo[ăӜD0L)d V1j1}\<%F GMY I(T$}r[6˾ C"h8y(Ɵ~,e't@u.ӷg9/<ؕ+ֆ -4ǹ)x r, F`cEDbx$mcurΣد< 쟦6)pF6VH[Dhfz(2\ cR]n8HFK1ώ!f_eˁ 6J`QYR`wĪ-KĬjwZ,C:dHrgmu5M8iUk?٨Y.N.ϩuQsQ?T.&Q]BϪzRtH#huWE:h,F5^ Q,^JD~jGUE?{u8Y~ ~X/V}T)gMa -jxt10%$ry(~t]$qA0b'$)FV.VDTRThqvy4a[Mt sÅM?{a.ώ$1-P1)&0fEeaZJ~_ӮoRK|@ɓDD#7M8'MmK~iMYgvB~ԍ]gbG5#u;D0TTTȇ J-`jz`C^_BXT jՐb'>EҴQ:ѤH!q鶥F>z9v'tp{>sMwv^3 =t/ -e\&S9ϰd D&̈L1F*XX1bL=}42w&E|)XfFf&^A*lR CD3㔦 aE^〥 ff=)Ԧv@v8&hm'|REdFʤZQ8 mqUv[dSrU{y; &:T$nQiqD4BͶ>4 -_rZ -A6/Y1tNN'B[2?ţ&\r-O[b|_n{$Qﻋe0}RtI/%A+zݞggQzzJ{cumbW.M161ԓt=Z_n6Nlt+a")"VFRx栧r6x"v6DZbvij>hsf~9J'sǽYd_x|Ymtp[2 M/dm}98F)ZO [NKvK'"C~@l)R)`1 n+:0(on=ܾ3-Uf=%ȋ?zرbE)F SQ)6w]cHE_J/Y't b>?e[N87a)wv6lgKȓ ("$ !]e?J~y|IU)9lӳu%vAo:Ś6JѾ$፛=< ?XR%5IMY1Ii5M/:>iMOۛ n@TiQS>#l6/î5egRemEno-"e(]qRtgU-l;b(ʝ{݈X^z1<' Ո%{yz8NbYr1~CzWOZdxt%K[Wp۱ e>޵U[(5{2 '~}4{,厫N6xdqyU?͒:vZsd-+թ=

oe(XZS{yyD0۟kMp;ժ"t<^yˮd;=ZtߏI==*ڒҪ72C̉1)2I`oWWDvQBɘ=uIjِ96gZd8z==244`(y9I5lǩNe$x *!3jvY&K~Y1˝s1'm[<98]sR=:1< vM*!Cr{޴cDJNR;Ux{\q6J H|7MKC3r\aT*ZS2 ,$:bgMl,˽2 ~dqt+LIlZdMkj'B͒9!כ$>#%wX UKŰ -TewA] C)Z] -sr^]Y[j?=sr=G޶ʦZ&" -i:ߪecX,WYb!˞Zc(⠇H̤`^3qw)zRԮv"EWB*~&z11R7%ziU1!"5*SX%Ǣe_Wsqrdٚe6VMqӢjڪi7̈́!ZD\>y -NQ0J㢷IW=ǀ<&6݋`~Q|U5 &I5MmZ:ds9-4,W[9Kܢn/I-=ؗnq3m3R! TBt`B!y[r v"Df$?jq -/O5/zд, -S] :br3 ٴbwGhه_m9T䲟A:Y! -2^GuԌ *ĂyNg?M6NN8$S3_mhfxcs2\/T EϱƣhmQ9 D/7AZb{gq7+j=a0?q/IG:Va|`׊]ңwjnaa"šc,klݵ Ӛc9GBIOLIğ%uF;?!+iFЪ6ZwK-/4A r`AGjWPRabO#abb s5c$HEEP/ǹKs)Vˑ81K'}A(zWܖo]sΫun;˄x_ɱ z0\V{IMMu<ʞY$UyL$]]z2,Kﻗi=w vK&)w6kAQl5xs Mw1Aa;9,cGT`״hn@N z[o_Rn[ zR<4ڶbHE]v|(wS̟G-?/cvqI,iM\TD[ CjBy&9Mws5V+H^#ț"%U%:3J~׎Gp!4ܒқ~X7>U49vBir̖VT74T=5ltp Nkpû,q%ըEjtZ?5ws$쏢=9R+VU4Г.xZ&yYdbѪ%f~<)'ɓ៖v#Z{eljXt%9~>})`WK!hp?4^LdL̒29ZdU^)R {mƹWaGh7Ģw]1<8 W2_UXŦ+fYѰ=~>Z5 tUCi9rU En{bq>Zw ղEa{?¿V_]]LZCp/nkQ]Dk~z([XlI{f=;i~tѯN|)`vԲԌ2eqRAO2NhU+\UQ;bS޶A>FQsE< tKV'ſ$A"tA= a5-#7 +TҨ1ǵY&sH{ ā vL)xŏ܀_f&ä<(]_n[.&Mm6=or4NI|$,L/GIXe(]mкY'޲0V-NЊ6)PfN^:>lzjU~&EZi͈B*fi(dk0tС-TS"z<m({ZuW|fձN9}9"-ZS"`h==:Ǒj`WUö$jOo[uwu quY꺢ЊV3fhPFOؕGЊ,V&66I~u(_P&oYSWI"xi!r/"st,L#=ܵG}I陂+%M-{!uءSŢ*}l_*lr0,-WqdmzIh9QxrߐyDzmSa -:OISPGә9neCr@\-.tTpX6$Baw{ vd%Zaӑ-9Rjs7 4O+${gPZܔђFJ=KmR+&-uek9M+}/=BtǡMUE~?5)KR>4t#Rϒxg z$Oȕ=iZZS=waGިeCt}Į%쯢Yŗv s?US%ǦAݴ|_ѱ5MZ+^rYU[r=]I7ϸXs nM/KbSԻꙟ}y'ZSSˢZ5Ϸ(J<' Z>)?:IcdbU/K0XE>OY\vﶱvv8iz;n8pbcxBѺlGW߬fxΒB7Tkrߒ4NypץZrh]CMʛi:YWlHbj[˖=F+Anڲ˂$GqK[xiW^@%<ϟg=ht׫gu]Kr/ɕ_We L]0>ߒ+Ŀ:hX/鸍nwCAPYgYj$ -Y!-RS,m?ՕXƴ:NaB-% hq3G7POc|>7>;=jf Hq\9N7K(Xv~9Yn˶OfRiA[':N=g5D̰,e$mrnFȋţ7qUe䪦VM ϒ/G\Njirϫɱ8pfR.~; Ha\4[qc%CEJ(oU azkvP)\`I͒*ʖ5Go^8X=r4}y-Y i0(.X'R eϣU-ȗQr1j҂9Fr$ mxIRU endstream endobj 21 0 obj <>stream -(@>(mCP,fZu8I+T?ny-fmx40V%*ffYo$VMpLQ1Xf}0~ S4m#.*UG՗i=wc,%P$n|zSH4!M}X1Bc|Ꮃ1EkuVTF̖[ YncwK$4.Պ LZ”B# Ei32šWbQ|2 "vٜ SgM]mq6ǸI mv=#L/=(wEƠW$9#K~zjĦs4h /PyLlgMCv;DE?SI^`o,YF , \~t.K;~0PVv$GXE+, z-D̉j8 +N#.n,붕$)߾Yfqt8(84* -v}S8XQ.<1Y>ݑش'C8YƘ>?̨(a,djP"3 ՒZ蹢$("XPMN:z7˓*وB%{9^ŰUQ}ǖ %vU6NO&vʎ||?=$geQ EA 4v qF+!<JR -pҩZ,)f z] }H-߮cbUk>>k;+NUejUmT9tBl""ȪiPs׵Y鍕 ղn06, <&<^܂T'ɵsHfF {n%We/O9/'EgQOn 庞mm3S0ճ9}Xizzm1C$I~E%'N݈-8K jٳ9ɳef3wmOEy*]+Ҍ,b]Yg_YwkEb[ty;+} (Ean#iLsWVܦ\6*CGɈԫeItDaK˦6U7LBDAkXzltZ>-9gi_5aH!~uTb4J\)U -vnRdo~Ȉ>ϒ,GzfDkR6Z??)#%0F^14CIKE00f|`z1Ls\~{l^D -}M}E_<.>ފѺޡQђ&r]a6mo4lhM='V^Y+.9z~WYvLGg),%:9@+"'5w󜣨MKZjzIɱqxgn2+UQڒYV>ʠ'W\UeTU*czjYuENm)B$%m&&E`yՔ!yd@Jsq+&|P'yׅvF=z$k~m-# xk~{s$ieE~ -Uh Bx Ҳ7ǝ Q/P)1bƋGim UEHqr(qÅ+=鯦=iTZZ^qʇiuc5v?c|1M bZqB8%#TDgKnax,jURf8O/F}jcyH܀zL)JQxt,$.53ǩ ط6"R2LwHI;,HEMlj5$vg'50<9_E5TW (MsCķ`~rA烙$]C<{J)m:Ys,.[V+vO &,<^fԣ-]-{?6B<{Z㪾j^ķEr2n;UϽ9p`H!>i.ԌIsbr*(nvUC'YZ¤F*`.zzБ=m[v0.*݅ϡ5qUHԯ%u:D͑!,jOQ>P فeHKEpģYa$q2L7b)'?7,Ɏ~ڴ%UQFjdsׁvD4zz~X$Hes1KĪAа ?,z+HLri2(>]N]g>eb5B&E,#aͣ*%dIV8xFwY*#Iܐ2B#~9t%gN7B\+TZU?=Sk#d?M{dF˯ܕ^oqe|>4c3C/jշn,T' A2|w~]Q+HQYpJǪ s==yݔ_qɾ fF"̐:fSDL<)=I$$F -~wy9m7v 0*+ Oqa4-4/UqG(<퍗Pw-b)8 jvC1b~+V!&P^Y  2RZBk*c QŀjX>̡2 -P :qh9!3^*̂Pr7/,h>)ʒО1T JR.JQZ~ֳ2;\TV>KfShI(Fɱ  X k?hٟ$jfmt}&ɚ}1 F:\!l۾IU.^,a;UKD(KybX)۰E[L)PS`(.0qq)ʪc_P-;~]u3T.O~q1 ydL iux)䪟D _(/풚 }JC1C7O*i [kFjRl+_L[F!ԈԚ]|.s40bZB ŷW[qvAvMDY@2`%/R ?n(bBoegL!RH1Y/Gs>kY7EBi-(/4ճ]MJjSܦGM!'A%,} Z a̞1@2XB#cJ 9PY\FFb%:*mRTIa"P%c%1a2+*bxH?O:8fN&zx?Vzc -є@)H[oO.Oς2pu*!%%jq`P=- eq.g`)Y4yx1@JĘfe,9VDHr%#X' , lăj^Ԧ1ݦaXH]hZGO|ȤO=>j7I\$iH?ͧ/eZ:Ԍ^j%lOZŲ>9Zjsp6\*9)-1"AbM+*>x ?3M?"F=Q, -ㆌK"w hW1vX! LIu<4( I |t|h"Vsh1!jpOKTjzҠ@4HZ3KyYSAbC JG}&H "0,UJ~cx [̎Xԃ;Ĭ8 N=>N^5X$)@8cV,Ktċ`Gɗ+T%@ -&Kve@ ET.g= C=~x݆I 0J̠aM#FuR3.0-_!BQG.)+X'%$ZXZ_D2^%?3,gT" *#3\iZ{P9I5ǁS $`R_։K -<~/R\GKZQ]J#Ԁ!G~Ypr՗js}&uVNC%3'4#CEr"|]~2%ӟe*~n#c$bLzHB -;V`#鎘H=}vhB2X/C06l0q bddA"):>h%#iP}ydgT.>_D0& -h!2X^P4%RK sVJW~EcL!ҟ"/ZdI.r]Mje2W%=c(Jiz7=QM+ANAф!]*Χ! -?Ѭf&sr@s"/X ?IjGU@nBnu9I oJsZlMRL:D~1IY*=WU'Tx"J&zpbMtu"NdWD"MRDyb%*9j]*<EQ&z8T1':e"Md+w"OVDMRD%DH**4} -<\1':6J'(g"'r*sLTDNTRDhS.( -h2R&;H'r+sL&j)LTT}"JNQNVԉ>huhY3P99QFi&j*oXI'*~"JNĩD -ODQ^N4ỦuhHʝH9Qt?QDI&*>R%'D -MD+DO4W̉MR,ʙHIOyl:I(5WPUy2~J;nhE]ݤN$i-rUZ8^@SyъPAWЃ[yJ7/c86~kqFj1Yo3Fȃ{fSmQTKO5nt! $oG#p a=aXiSjCa00C,8,< SFMţZkqHpj$HCdd+{`xYRTk - -om)gljc1.9} 2.}GPAl2)o:їc.DڕgrL -jW\_D-yP;ǩC _iիbwOD92vfgc+CYKa3fb>zJL< -H% \ _O \lf0ɴ?N@`C3Rua.Gh$EGʘZM$ 5? V,7>` hwTbM=3423DP@\P/K8KrUt;7#f<ӋG8MgM8mRtټGƠWjc9|$Imn4.c+DKK+nmx'b6JA_QvcHeG@ +bx1^!]rGf’ƴ*>o {mR ET;).)[[;B/qf46/RʡCь;VHr@qVw¼sz0$V [TX^XMp%/%?b,i!6i^tMrbQ?q3&94,Ѵ[d5r'lY}8%/W )Gp}Y:=ޏjJчA_q[[]l ##qk{JK*P1Z+_eG>>5{}|!rWIovIY@9"]j¤Н[ !BJd H8G p$WON^8 H5Cb;eSo݄S>HȰ/rO-A+Rz_'Q:#R0fKKT6Pȱ+?ᢑjPnN]w"qSD2nP5!S:JPKcN4T+FbbXx˳sB r%Tb!l;W?z$/+hB¸bS_ڜiChU 'ُ^{7@e̊_*quZF 4*AUejA, ܞK—ka.-j5gHm{p͡ cm!ـ س<5KW8Sps&ki! ڃ%c+U%1׿ ݊3$\= -qNYt ߞH*L,1 /c4l߈x%y`|I514,B^f3EM=u\vV@\^OQR+ C yaaA;qiyF8q] -B6_ñ20O6br&rsUg3CK }Z4\Aدs9n[1doSW46nxޯ@ZHf1Q J.^P(xyvm4X8vw9Etm֟?"w[`US?gQ?> u805|l~--lHQ}l#d/:ͨsՅR+;@*H\E` m87䬔őD`ѝ.[R}=sF,AGl,}sܱ'϶!/3H QME5)EgK:h5t 1)„]LאUIbri'S~9b1Ue@_|SUg]$3M)!ۊ}75Ƽ4OXP4y~pCw>l{ȸ; S/faMOXa=c5`4\D%YU 5pN/&6ob%Ա`Mp<0&&0| qN{>$DI;A3昄QTK[&!Um!ub %(uj_MuJQxI.P;II~2:m~X `Im9">`d?&E*V -mhӁ_R2okjN(؜1 {_g?EWڴ;|, }+T -+oaƺK- 4:{W3'܌ -ldq4WYp'1`^ZMZ3ܛ 9<'m@VNrU<(S\L VXČeڹƌ'n ћP@W(+)X\Mn Gnn@=>m#⚰N-bmՈ4`QH1@7%ywznM -x(s.f̩º֑HOtE킴;iJ>_1aO؁+XHar|MAde"E1ZCTpU.ΣnmKiq3=-6vr竰 14 -Qsu}+B:3.O -X}Az!a_£7#*f˪] aQv2aZg_HYYQM iMBPb -{vJoZ"zB KiIpR% B n';3jVӥZz3n)p9uE!9;QM -4̨#ktdy(\g$dTЄ9b azokCB>)( DRAUBytjhkax[\zQMH.r <#^\}$*$rizP\$`b4vfH|}Z?E{8gFk!%^"=i` )F>aT\U }'~Y~˴Xr'%Z{`OG.ބ1øcJXL RY &*¶.6c%O*&g?tKN$4>_j=-;VHj skw(Wuۆ0 mٌӠ4QUU-pN;(ĺv-eUHנ {ܜXdע4`4[o&mYH#HOÅGF#Z/o@"+e`s1)9,ql:eBF?wRq@($>!î yT˲'G<<3pdE*aY(%T0sy 7[-;=\C+őD1z] 7-!9'{!\f-fɐH( -(6$( -W5YK2N>q`{-#KtA~p} <-1pGS"e Wϊ4p~N֝)+rLكy.HHTERA7pGĥF:ǒ - VrjǹO%8@EFa,,PdJ=gtiC)5,P,kǭc6(8Th#>q:柼TB&dG:)m:x# 5!Hǜʨl@ L5lՐ% lD&hpo}U01RanMB]= -qF,\!Vt+m!6E<fG=ײַQ>)#NxA'un-t}֫gA6zTV\_ǃ9njWS~4 ;h.CMJU}c֔6 @tgzPN&6aYKV2xFܺC,*r} $`` 阭(L*Jc<%7D*8F-[_c$or+"B%^}Wr LR(vpD?C},+m#Dߟڥ%N!pV?7*L7 HDžE䲨٧T_- aRCȬ.]մw1WOfqv=ڞOuЍ=m` q<I]ޥ)c& ҪF%  ce\&,dE)y_qݓ\*ITv|X#Syɵ a'kTk\ -GJѾ S`qɵ̀:ۭ.5Y$"\Ex[lFN9ސT툟k,\OQSH.oqOLδ[v'[]cy]7;Y@U3EniӼ!qCIͧC$kHz,ˈz 4@?MC;% ?=maEy pZ3 UAtv;G& 㬒.<,[,hev",oJL5WLj#D A$Ƥ&5vid-50in7vSBP\ c FGH#dD@3^0qf$cAdUFflK ӆ<.2@@ocx4O{ehfli^"E=43|w~Y1Ϥi>oxFc~F&u{O IJ _u OAا'@>%Z>%3'd@@H -SEK dD <@vT(  \;BS4xuRSVGs"x)kj Fo - -%8_{x~tN<7x -+pgT2Nx|Ll=S7LzLӧc_4"mm={Vu| U]FE -3uU41 ->Nx\u=CbMM; фICoz-vFt'lJaƟ}DP& {ksFPvҰh -D4yö,a}ހ CbTHpjr"eJqo[sIq_\B:! ק/d;Sg@&ǀ -E\xq;=+a2n334c0615-3589-4d16-a165-dc8d613f1996a3d95cb1-4d28-4229-8983-7f62fa8ecae2324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulence;childrenbaseFrequency(0.052attribute; ,numOctaves(resultturstitchTilnoS,feCompositinSourceGraphiinopeinwidth100%objecthxxyyidAI__1id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-z-5xy1ystyll-color:whsurfacespecOusConstant(Exponek0k1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.adiladnbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(77spli(1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 5PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre110001122nred=r534 -4b)OP  aa `aPB :5<o}~39vNGp Vr_9V8ѵ l=/8aGIh$qPk wlXf$~!g#-B,|KpU ïCE;ȋkWf%7'Wf).B-buJH]i@К =ZU&w+>FMP -\T*⁔˗2Y'L!r@}сEfVO$`}E#NF<\ 0B.<@Wt= Wʛw(Pٞc._yXIyTAo%˸5 -#XlJ5̢X璽@,%ZneZ/(&-`dd`{9e1ng| ӕPn*9IN>UXDe0,*DQ^B !Y3K%V#sfs$,J+{*ߧ"g@.$#"VFoEBh@(1ŋĩD3#geTVZ(Me3SಪIoyi| e PHѺ|HU >DЪ935DUy"B7'Cx(0sҁ:bXd"Y`GS$^`2PП%VO# XJZ5,$, YO1ϿHvjŠ(Ùt !rLxAA7b?/@Ge!wi]ld z)4{Z`?wحj7;ԄHáEy;Czt:`:u];crn.H=’]'1lhGQH7"D$fDk)/#3`YO -71jfP4f݀u"i1Ph NWC1Z N-fXLiuX ޣL`ΉˡiLMI!,>DM !tHI(*cS Fh`3%tw杭~ taǥHd9/lP5ePim) - -&u/ pސsak_zDƇ#CCJ"^,V lZD -Ee -NrAjn:m|.,iR)(} 6:UbaQX'>IfC0q"3wv<>ꀖ7ot(WC.4U1'P6$WR:3/A;tPTYQu鷣#EW T(y jqkid\UϯzAKtGmU k2a0S,rA&%A>36>| 0Td}>'W&ybwD&=` ZP \kBj6+BجJڦCo_ՀHI2_~(MK?#}Y?tϸp5W\H 8Xuڎ(øp;p2Ofrf7"Ru =b]#!,Q&\3. AtH㠉7L7 @ɽRRl5WR>_TBA>(FqK>^p#&JTm`3BL8d L$hG!WGqHe~ >z!?b(*7DQ_yތX6xPn DG̤/j&x WFK1 ©EH:kgH]E9}]F9 -,XF- -|ٖ(jK+_*kyD9wȌbmGa@uYhmF -mHhFGp봓<@-TV΢v;z HHKWG+%'^-Al*٢ľޢ yx aa -;j7jYd9Ujn{0|$n> Q9#G##qq ٷaKSϮ\: m$ATA?SLP? <`A(< -!oPA1aC1aD`ƒ - 0„7`pP@V*@P5!C  ($PoظάFѠxXfFv-  X+v$0^^45błYܥCK>4l[[,m=;iXKG|m˶v/ovw.wN6,2-gZ~ToTۺό HpjTm*޶qi@ #U"\`Ad - @'`0 -ۖluUXz#^D11ԫ;:b'3ZXs 8mjxs+|gJ;ru57^I/t⓻+k@憕>7U˼dd'sBb;.:rv\}Eґlέ#Rl"}1"-S-nˏd'6&xbک'HŖNҬ̟Y7K<<]~&lOml -':o3UYuQbτ-FU[- ϲ_PGڮVZ,UĐ76ȓڍֆxUn&dB~fJhBÛT_gwrZ'ƌ#!`r7F٧,4[*/idY7Swt'f;;գBՊ3;2K,A(DЀB.(,f%VJ]1k/7QމQ4DA[`muwU'CYi]W-$״tUE5?_`nQ=YX+nmǿ563+0󙙙wLCDEuv?SQOU2)3-iKyiOOzy˻"e-{[3/+>Rk ,,2,Pծo3PٸH۳f;ڻ[;BDN=k@MEyƤζLL)3QFw;3./Ϻjl;ruSYU!XGD4D,o;f۟Z2^!13sqȌHH<™M؈ݍJ؍h}I؍VHJxX,,ۺy{/Q]\m3𽧨׻4TT - hhc`$X*>d:H,J2qMt5uh( H4  $CNm{ыps\PC_iZIVנJwNk_Fg>D5To#Fҕe( ͨ -Z -"S 5}H$HSƧ:iHDV8Y4O( ^H**r-'o;#lC<šnAR!ߑ5VW5|"n#EBHFI%q 3Oݳ#0#Pf~TH& -FAR xpKYQl# ͋<>_5g@- -r4$J`:p8)0.}yӵIY{0z(3X{TK4&$zТ4f1S@qsĬN -Y?4n9JEtZ}7@H 6Ä@(VH%[v"n*j3z~F QCҁ!4qXּz -mGtY$b6AXXSBY.4Tk0ӬtOA/+:ÑIwkh]cRl&xDr K21Bo'?u)[ΡJ׈\6;pu'Yӌ@ǕY)p"`+xk\7=\iJG -Np1w:/HotF)`XTmߐNvڝ 8SQO'N5 ^y<7 vHH -CFxЙB'#)ZW}//D>\؛HӜcn 6Pi$GR~A՟OげzW} -yA/S"7K;@Qxaat3q_> -pYm+cQ]i@9CQ?zɏ ÷~E g:Ļ4pycjT4a8kHǒ&6%_: bO~ \B;WSr7ҡR', L=hYp,z\ʗXP#YN4׍4MXx"*"F ݍCFg&w8iT@ ϺOόS.sDNZp]"CRZ`5C@ M&wC:2[Z%B m63_cTTiTG09Kt;]̈MeE -4ڿv@ό'Q 7aQ\fS؜qpa5Un< 6q.JnIc7= R}4/zӛ/^3]?sk׮PT+ .t%N`=J7cXJ/8^8Ruݟ'p/(8_Ju,PxN1Jsi_0d]\R<"PF09JknsK q׉7Lt5J_ͦf j(roD~oyj/#?8)-b"o!imqN^u6-Fb[u3szʔg\b<r$%3SwٟUź]\': rŴM+;JD ,"vLʝwKK&CeֈO'@HL3:>0irj~ZS>Vip,>U>F?̗KuXHD 2%-ʔA/PRS_oS`fG>ެvw#jzcXM M #㬹@=qA}V[XfP3g~fAuR!h8E?2b"!$oM>03(OQMmo!+{zC1|7F$<17 s1(|ŇRGժ~JfNm p.︊BqAW7֎F&h3T6_A%.CXKvߓ$"5*+mH0c.Dc,!z|G5n8ێJߢ/Sa= ?tFI? v'njIk2W -A63ڼBo#uwEA)41@:#x EbJ".~~`fkKKİt-GMDyd{vE_3Vx6/B>m[w`( -Sև5@˪bFR7 3(aw -`Ш+7{BCe$LP*]`:ShRe'H>B0§ՄOi&8=e!6J *̩ -vJzlPF+'s OLS IIhwF*nZXOZQaDeֱ=*v $'9NL=#5DuA߼,^1K Zd9F1Bk#j аWYO7`b qL -k{ ;T ->?}H 3fB /Ļ1jXrXL;!ժ.(UypMLuzGd>JSWSk&X9ts01'>`%xHe:#(nS$* %[c7@`RpȦ=s I\ya<$(oPq&ANXP(RWt"/N돷 -|.xaFاi/@4|cδ\E=4Vz9ŹkwNG= .k4\$bj[\$Táz[tSnq@"Sj8k͐$_DPUFxkn%!!cR*yA/hXV#dہ=kU>˅(+4"a' *"GW̉ -(vg!,x-cy)'Rs2ƌUS|,iHݼQ 'Y2IW룍#I]\'*`m -X#qME8˭7 -:R7-2#cu mw# 3q r|4޷][T[/8Nâa{?3.i>HH-^il[E TYJTDr{sLQW,ϕ:lJM(ɘIt@g 0xYE؎>ǭ큼[O"If{y h(m6AG{l/xH?yeL @>6h 1A M\M:7ô~F#{x錼c`!*;A{<7MMX3=^Fdx Y2$;s=LYsKwJF"#מK,.Xa|+;%hC;.ʵÓ%yiK}(/m"cli+v Q%W噑)S(ڪ0)/!yVĪQ㉋q5ޔF6|0-Q8ϡ!: >yUVwH yO L bkE#ASµ|^ 4`z9f؇ ^,;>Xyܤ( fF&ۚib!4wfh"!f:hyzeLjjhEEL\ VvΆ!vQ'l>u_iW!/*; -?Pa} -o S<#e6o1){:&[("ZXr%͒GEڀy Xvm^< ZG:חY0+=X5)< \B[%qhB%r竦_*)8҃%ԲXe+*p<&(\iݞNRT+ ZFC) CQa6Ĩ]&k7NvX"LtNŅB -oaQX4`$&zXsO - .G$9E|(PSrTPq3Uth,SŃ#t<(nlcYƾLgN+إ4WG/(kJWm 㢼bra+ad{G%e!ncPpZχ;BvzTK'\T0]len`{ ӕ_c(E}ǫP)+JW0kUU}U_rڐW%G}E[$-ELu+8"S$eo (R*JaQ|D4!g+ R%,t8 1NMF KT=5[@W?]-1,yCoUøUUiڔw8oA97`|[BD\•K8eao nsqC/iZҊ䍮҃Q2]O> -/ ҋEzHq7/oBTpS~\"އ'DGLy> ^yY.N Lɦ6&E$J@S1cR6b?\0mW,LK2TDžkXDm1|\ w,CbO /dQwH$ a;w#Ȁ}0fl|,821v.!9Z>!z2's 6DHcR[k R4+) 4y PYCF C>]j$ k4McL>[U: -H*#H^3V {U3_/h7}d( \W펢N^aFϹ+4|*Xbm⯸@KDHm 9zrex =`}&i=Ϯ@%g1h.1Ay1J(fd ֣WaN^BK -P avHndMfXZh . f-ZL$W'zҟ8lg<;Yy49 *Ɍs|:%IP?|e f✋GJ670ҁ\ͦ8m"3z.Ad&?~fM܂6Z yq6N)Lb݊:Ƹ'cF~ZBByb8&*0e0.ҷmn@vCptaL Əo菵8[ 9T Ь8+X*sVLYGXFAJy^I bnt0`iaR0S\2Ft_iP1gUP23q/!1^@Vα抔v= _ܱsuq]ضyhxY ZUsOF3aI.L0hz:/{n%Uo`LCG¡[xWagV87Y{IpWVK@eϴXf}+6nVErwv|G|A@f2J.|++)^NI. Gؿ%# sy bF]IUюqVo=sVwԍh/#>ܫ 8Xl0I{Kǽu6krG80-veѐ NJUlO3n=EK[W<gR4Ժ^V=ܭN@QU9 sXLn4ku@g8>8x+ -ssăk;r+%TW~Hon[1+}jD?jđX }]AV` -g)Df)2WA(["ӏ!BVS\X44]hj2;k$kmrSkI>#1O-S`1DWOhUOh%r&UnyJɚeQ<3TC:-Va/ kf\fL{|Cx/-E"խ'7K/bUl+/I>eQKy],' -J:7B eEO (YƞT( CWF,+l`}H{/q2+PL>G6of6dG2x$ۿzV$Gc>rm*3DW$&Ŋda&4]ՌɞQa!'JEJyAvD2x꤀a`ooiQ˴~W,-q2dd$W"$YI\Vfa\ն=[@$7ʋܒ,55(hgjX' ڲIn;-x2Zr DQ*JCV'JvH0%[d2绡|7Fowː B ;JT$V9cH+%lMZPzP8pH2>!uC64VLgG - 2m➉jaFR:nLu7J7V|<Mwpur!S]RENQӰG@EEAX@W$7P)[W6pý{I8ŖTc[a,8i=X58Zl;Pn:H2A#EY&L %ބ2&(?|wRjHC8>VuE鱗Go֜[-5afeZ]DOyFyI?Xゾf60^dсGe 1:+2zӀ&*5HA;UFr%u[͓E-_l -}6T*(6W P>lJdp2a6 ڞAtw"8D%p;8[a7p2j/QCF3#|#w/,ZM+amrm%Q"qDsĪ$>fU4ok%Ħc -> WaJr6A57?ԸX**[mXD 3LQnhXL54oI| - ftg\LԝudM&CƆ8aL%b,UGgYs^2e&Aufu s"&+OBwU*qa'd `Y[ =_Xy17X́ڗ8=dEq).n"u/ReSii4 -wwэDFWg B,F}_Ӝ\}f -Wf -)ʊ™@ك@^:1.iZA#):j aنd{(s;."]tїN'Xb4k<.:vr'k>fՒGғkFcoZ"~w7X?Z vDB "O>*`bW7y=pc= הfUHW?djvV(T/O~x!K++*c<Qo"lQWJҦGBz__Yy7YAfHb;F5q$~1-P v-{a C/ |.lf<&3% -ØXJ+7>*v#H!_ԍ -78@Q-bׁXm?R)?݉~JD`KX: #NBQ3#0fb*|WB,'8J[6?.q a7bn~-Q"!5YI%p2*|?wvJr_M}e;(p뜸0b 2)#FF2MX]$d8ˎYFJ -2 lQRE[F(TRĩd 4>a몕v&>tdxźn6eIL:joJE AL3}CAO)+208G>k/ VY>$gBz[")&C@~|嶷(EcYxE$Åi --ӆ>- +|!:WcaRzYG e־I|?O(x;Cpyf8;4G̓h2ed w݆W M65OLo3i{X|bj=.6J%;=vJk%;3'`H^pIKPco4e'@2zjs9ߕ3j}c`g>܀;@m4doK LR٧HJIrf⛡],ݹ!K5SOe[Axmȡ9Ng B(;i}tWgljLy4wCGq}?3NZHFX$GTo@]vx66 1}w!ez^BL5k=\a ]4`eV}2~1qVX2[%=ߧsy;QR1aq{X<;낋3l|$piz9.Z?$o/u_zfO~ 0`&%=7'cHSbϾHe'1o,@o4j */f#bg^eSx@ClY \9\Y ?NAI9<+Cg,cOƤ hiIh'<xs2o}SDhkDpvLtq 3~b<ϒl ]af6DkN-CpBC7_XlqQ uRuyKƓ m[ThCj;eXT^k"6CжVOg;6DuT:.YXڽ'1dI`;"©pVss7َ=hddF4վ~cD#)=9񢵚.h]XH)ypNKW/BsOo7\s J !(Z!;K5%Uwqշcj8 ?T^v j$=?/Qg^4$ !yh]r*rXHZRKعR=2cW!ӝ-&&֌nJӃacZ@`݅^vo:RYHq1lOrb_Qe qiόJ*d S#v\7-4soL.[B`n8zW`!⎂8^+*[( Sl5g?=l2XL2}7{T#S!^B7eKGzJMZB[TfA7pjG0xΏ -bh{- qp$- -|Ssv1([#i4WcBIS|eqv).k4S:FvPe0{^kę@n抠IZnPU&F%2cVWWHRnU!7x zFG -e .( 7cVM -mQ;q%u5S>Pp +~Q6\*6^2)&O߮|&;9zvb6ŎQ{h)f;V_[=OpUy5Ug -o[tKCxi Kᖆlox<\X>X=V֚/7 bato{|j1(ί%K݀M'Qn#--}ߩ-&w/WV -rt'_py;fCVR;k|5|2*K;g(R/oi Rܵ7y}ՂՙX$@ظL~=5W`s"3O\#t>DwiKڻ 3Ux -1œFPvT'9n ̂#;l\Sá׏H 9baV^Aj1XMNLdr<`T@AYUGt"TT5c/J2瑼(wAeRȟ3')~pB)9HcpSVS<+z!.rO>wyqv M$,NO:W_&Ӫ "`l9 O "uR}=Px@ I3_Fv[ՐH,Bй#5n&[zJ9Rt$tt\m۷s3x,G3WT!|wsFWI[,݇`e=5'ɇNJ7vė/\/hXQmW^=5'@U`I"?냌k6]Ba)G  sdXD HT_tEv ed2V -4`T!DuG !EYnnI9:oC,|8ΫԁD1I,4Fd.Fl04hBsܩdtw*CeBYB!dڰz?f3͵>HjPKTli`9\J&/<;.޸UV4S >'@Uon <'Hj"748yWRXIxFkidyDZ1{=W5MɘVW|jyl[6J0е(0BlAƧrP@ʇ&|S"16RQzFNQ%!)f@_!(jrifܕ7cbH^|cf&(\4J̓L -̓ d>,kA:Sх؛7h|S>(LFDM fG 2Fj0jT[F 2@; lpRzubHt$|-vq)%G{YwiFpu&H4:M+5TEBcp$S(Y(T̯t$=сRDKIM٬mNvFk#U -jQ2iOA|U͆J\bu%cp@ dڽb@ƒ/6!i&iF2!}]gwX4q+w6,o* H$'A 8ο3 i`{WA)f B u8S}BMx$ 6_\8O viNt-ZwlyCZ1rz٣.r2/l髰aI@S~ s+5_-2OK@q4tQ^*`+*9F٨0O"1HvMןT+"@ukm8J`q8I%6‚"uˍq(( TX.bꅅ uA] m"G]pX\o!$ٔ2(ȯ;*1(0}P}J#%})J; ޮc|ɔ8>1l3LtXc a3^wqm_"\;pu07qˆ3Z]K שB`ӗy.D(`sBЩ =;;;eH&CT9aUٵ 4bbtX OۣЉzg7<*,ɢhԩsw%?vg!b4@..KznB(V]K1m.*mjf&=\4gqVF2e} L/`Ns[x1fHK]+r|*-YzlE'AR?6 0 X͞Uc뷒E!8b ܿT 5t4 -+z[ںhUBCfFa lfn x%krD wM.M[Ut\]jwg>2\0H pA In#d -'-83^#$VD=XmGn7EY|oh@@4艷?#mVz쪪ѯZo/ח#xOP8_@%)KVl9X&h ֳV֨`4tW]cppӯy8Yapȥ2dQCm(1_k@2+rA J&E4ʔQsǃ&GFu@J~Sfu ,9q"|Hԅ"a9-t(Լg*S!1-n(%ΡpF:rs9@6F[¹E9)rR(aΓA|LXgeuf߂|g6It $,:y}R/+ePAX -Iۆ#.Вӿs`%fv5o~&!w -NTa C*z0fyhj_%󄯽1O{MG雦 q״-JⱊcmFKiivq'qD34͟T=E"]7b_]r&X-S!aX= v7,.נi9BR@^\Љ(,4e Cb׌*z@Sc$-eQ _Da=m6I1j쀓m#h`!#T\ӂ얙F nFo|$ѐ%a7m%D|^`M a`6,d -EQ%2o|?Fi -4N3y2%,%ȨͲ0UHGD;Qܷ`SAXN3:1|w8 @X< N?07.wQ'CDӽ>h7R%hV%jᇑL?-݈bI%xOǚMwՏ#$bLYCuΤgkgX&G?"J[ѳqnGt -L"VtdmAdEd"y˼/KZ3fj:5,@ -C#i1v9]^j<ɈexRO$Vbfe13h7 u|L,~ժ(-JhU -w)Gdbj!nP@8ʒ8 ʑLA(.҂/6 N^4)U!BqP*{r1 L0^0#4Tmqi*`LRnB)Nt F -1:( o洱^1J.d ˂WW?KPeV,fZ1YcHo]& *-DEQc -5HԐFpjWbOJ01Uܢ/]ְe7FX!_';h),4{$(@5>!"-xџL" JUD9߭^N^f@P*1(<#ߊGMHsH&XFE׾C -sPXН..c;H2x*C= <$D12Bǿ-MVHfEI$Cx?B>#(9>֮gt}4qjkJ)$_GsD&a6'1? T\:}h4L<~TH @-ɛ-t%୸3tkB\_ }륂yW@ˀ ]j!)t3]ހDS轢ҡ>[ 4 ILW܉uXzxڈ$qHhaZu -kxI!{4B1O3%f̬ 8? t{,|4:>O+{o89`n-AQ~^,8' dG70Fz30?khdWis)$OGĭo*v}z>s7֑ս:OMqkU߭ysP{UAb1FrjؓҾxFls+h nOZn-f_<ڋl\12b vo!]x!9gAtq S/+ڟ&a`(m=Kι,#݄c>X -6&@P"D 2Rk[e3m8 :+qa3Lk 9V^\@:ѥlfml{).!Bb';Žt4  h6D\8QЋunEF-z34Yr;Ҕ/Nq/shDdr{uƙ'}49Mt-Sub+X`R:j8xrhP49T&pRlʏ'ziktJ,Z1?Oe;,n)ЯZ[>|8.Kh,7 FeE>-LouVv$ʁ JKQ`b˿:E\4A -l Q 0WA]SSP d,@Fo_'R#~w[%2D=h|sIYJdiLL_gʜn1q!" ,EŜ : ?(P{܂[> \T u翂/0ӊ!h]<@Ƥ|VN -;Y6MY.f\ ﶲ!B;BYR*;(jx:àXjYQCD:<ɩ"NG*`p:m#\]"pܝZ |ߋDayR!#Zͺ -S:LȕBz$olxة2q (l_%D6I_L,79;I3sgխN 7: ⶼ$f[F0kq(Lʭ\Nncn+_sq(K`c"kôV5Ε>HVD " i"fH/$ bQBdņbLmaw¯B;gZM+]06ٌAT*'m֕k5/c[U3[k^IyFtV($+O&v+%<ē-lأ1c>x[ӵLPy@ak:-1?ڂ 32գ*pbzS*h@ -1>1/8-p%Ϲ[ A zz+t,beqA$!EX b޺bt*Mcz bAW`"땎rp -8k*ΫRòJ2`oKhUhmÄ}}ow7YŅr-D#(~/~ wѵ3QL1N:4~nf\$*La\Ma[']18 DcUt_ -xlgaOJܿ]r {oer7DzJ9v=5@j[eAkaU͋$]@L'H ցy(p4T1vCW5]^q(Qj-[[ -eQrUsz Lv$z/f^N_9`!lqQbpò}"AEnY[ZFfdl%1,OXaXkn1AV.y |R6PXIrU Rs^4\ ŠA2foG+"kUu>`z=P^D),"|)G d3I<)CjO0-v>g-6AOMG8 -֠[yl nmݭ[aea;ArV$G.˓+Ί@ -%o߲zhd#ŃX(@XVh7PGLV{N zE+nj'e9p~ [2;!r㔋X 9\tn װHB+(0rP]PPʡьUs2y S"yG]>"a< ϯUaY銊m}7⢚+!!p>ni{;'9͎gu RNqdZ8AzPs%^MIFV(}LG -WD.ɛ } HG&.ZMZg~3ESfgBSiOFPeqCШaDN\8nh)BO_đXXL^M*PhY;%^ 8L`u*oPf⫱!AIuk="6n,xw$nyZeK-_ -ߠ -9tYp٥,L6 gfEq[76we+ LAlCUp{kT,٨@/dDR~E5>0:+ƠL}9"A` q7@e$}IJpP#[[I"Cpk -~M=DCp.7_0"&grZ3>J&g3h;c(W-ƺKMmX_d7~ QW+37 +l"E3*;k^eNQ~JPdzBkxk(@ лD -a@(Є(3,- -  -J [ 6c6 ïcc-V[5]16`]u]rQ~u[wuYrٹvqylZ %g},ւf2Xg&3՜R{kQx>2Xuu)˪WW)lV [w}X3zv\[9vZηYX̭۶ֹ}M9VԱbVfcOUݤj^,FV6o&0VC{m YWnݶP૏^7B2gYVr\ZJX"c3bkkYVߋ+_@]`̺7_ح>ڸzE. Z}x}[s Wfё8"TYrxJn77;ѭu?{ksߣk[,4Konh7Qs7Ϗvskݘe6<=5:ꍞ9~Qk{ynD˯?FKy,K]~_n>5Kmow~;{ߨ}ϻYޛ,ͭ=Gݙ(׿ԛ{o77Omώr{}7wyz}ny!͹׻h׺(םsȻ/uן{_^zz7TPo~~Qs^O}{F\s.}yvQ?=~47N6.M}'7rN(>ͯw4]9Oo7{ol:6TsOݺ'Zr}OG樹KG$(̈́uLt}DOU+`?'f ]r0Axx):t4gLS41Gv— q3ľxeLIf;ySCZIKmnmne&?N^=75KI<3FS3¨kc##UETYn* l@")1ҭa2ʬcA@CK )3~ 2 z veq&nJ(Q$07#l(DXhIgݓ:)h)DA -΅ -T| xn -OalڔBW0͒ޓ9Ajg *=%InI̼őIRe@`M%-",DIŘA[1*"hL'TILdKqA y L%41(p> DKЄFk|X]4Cx*a:`[:8R -u.f"8)?HV<%p(!ěa,Ij իU  -P6 >, 00>חg`a --x}L=F3!'*_#_j|!d.p ? d>qcxXMf -V ,ւD -X*4dK Bp`[mBA *,Tšst d*F / B10 b@DИ4Y GB(=0K v' 2$JA9PCB9:̃x 4j€ ,j0p!cէ4 ͫ3XP{I]> B :@`=Tm9, -huOڡI amx W̞yzӂYa+4 ` H-OE,~T925VDALz%䵐ǻor3\<YC -a'I,"^k/ 9&M=dhx7\ OSPoWn+̄F#= JH*‹ >722 M^dB^8[ y 8cb.& ЭI"_&>eYgP`!1Ȅ_V=!S39 fFzɡh&r[ KUILYv.- qDړx-fVT0iRIF r18^ h쑃#􉘠VA;.Li22"z>pEeŔ#.@ oEe~\W[FY0 К m"G$#=rPZԚrHT -헢G㖌G>y -RDbVLy,FɏIܪ<Ι}<8y2*'j <σxNy?'ĵp bM=d -T΁y<72!"y޾|<Йhq yC$, 0T 96dOb0"[) !%=MO*񠷉yb%\]]$ʲyWZݰn++k-ZXnga!uH<`hUl+]8l]ZX;U{Uέ+e]k-M&b5fk,^715oxV ָ"`+ָXzkFw۾-g 9ޘkx%ۊ>s8EpdVH<|_ c omVur {;VuZ.v2M\ k7^ۭmǺV޹{lS]]cZ;/]mu -`eyԍvڱn jkV2tr3+w+;6^;Vfe"VOmI-4+eGDVYQ$/,nVYvg4jm׽}aKŌuW6u_׬-k-e݈땰[oK ƒN@{Js1 llc u岯ѝβlake5ނcvz Zc G,Go}lи -~lG,C1pZ藂 -"LNq^Sqtf2/w&C7-9UQiK!tNÏ)g4?R"Ln߈αɂթR UҐjtVy:ǜnh4Br4!*ie>2RH{؄ih:eMlDo5WF~\ZPX78ILE,/a5J@ Q FDr;&I1Qb' -~@VF j>Q!0@pG*"RIVV'>0yof"hǁ+6?VtVj5ZcOⶲhϨ񔆒'aed HbG@Oin$M&$zxi AM@8U,-^ZMj(i, -~4QevS^*e 9#H?= Bq$e@N[QqqQ ->!ǹZZbe`0B)BZa!āQ. 8y'A,[<@j$a#0㛩ACܐ X4ʭjXI -(<, @D2wB1+̼z= C>NcsȍpmXqmڋL#,YZ4pj؀B &ܓ[tSWCzaÂuSllU$fU1Ƀ8K@")njdC >ab;/HB(J -٭3|6.k%i4PEqFWh -r橤a8^:! 1:!Oj׬rj3hF.ˆ1%l7O&u?n&,o -c0g"? / ڴHTLwz0=fl2H}8.s>x gJ{P: xJ(]fJ W^8b@)Hb@դI_H+jgM2 *|8D"Ҟg|EcM(~13p >.q;ZRM6' iyGě%ыFj -lP⩯*`!9ts>V@(?Ӿp(#h7n6( @"ponql028DzKOA^jyR>*^eF<踟"zCu!8O2c҂$˝pk4.X7 T4  y>B))(8Y(_&)t($d_aEzh|<'A&ȖK|gTi8aFHJŪZ\SGBMŲlKM_LYCԙE$Dz$'K* +gAAzCʓUve7?` epmHǃѩJuQ 6{HC]^J| 5zXM4]Cp<2fsXY|oX>e@bqny[H8m`!I/ LW -, ,=y. TLHb!`"q/)5d!" C2 A7B &)M |g ˢu -Bz)3e4y\^L 0=dDB(j j4L6@ˬ$YO_|<߄dMOCnu^% j^ rCvA +5 uU(D oIvǥ@aBULJKSi80k@ڒnh*ކ&]5>Lj<0BZJ3 h쾝3pW@ ir q*>%ΌbhRC>H$ JE'i,cOcYxb9BTeIɰ-xdړHNQ3'lF;,P~O $xb\LZg=@V? Kc{[j.,GŒtHJW[觡&m΁T-xq # G>5]2 $b1E? E/"x! ,&Ұ~ix^M3xҐ4 ѵ#E0 4XAޜ"Z~,{|Ga|Va^uO5RRTּ4Hb~_:U*e iaUw|=g> },o063112KeC869uᗂ)W%XӒqqt*|q4꠼%HbGB@3xho^3` ׍s{؃xe1\('0* (BW}Ee NN \Fz|Δ'`9)TWQeP P?ZMzNԜHqV -Rx!I@7>rJHZ3Rb˩TUJ^Ƀ!?N\QS90=}Taq&DDh ֽ[l.% )AMT jLçvӜ n&T>.D<9z|#G_Y82=gchoC 70`fc Plch#[IK:[H[dYbXV+8D+NxDq┾  UY$Xkd#q&MpNi𩔅`ŒpG(Ǖ2H!KϿ@ll]BÔ:8d^n q"P98qˢ_S 2d Q(tHB )aȈgQcPMd&!e@q&fZ~ l  m^ P Ůp1!57rF)ΐ[lpu03Ez -V%UO?lS*i"^+P6TD"L4=lm;&Ilud2 g2;YMTY@[E|HbO$2LhED,Zy*iȔ>I cCo@(aEchf;]&%\ - (KS<2EǭL$gSnmn):ߤ$q Us+8`e[6`/oMTdwXq j'D+NqIpFB| >%-5܃g,<łY1z`9+9ٗHR4&TDQ= -(er{$Vd4eKL3Vk˦1ۨF(󌰁(fţ,6?}7Ӹ2EQi2B[U[QQ> &M&S**iW6&6Ll U2J&4X*6,l%D> -gU9hD@S łXУ~R*H8:0*@a aqB)e"m'kpq/Hg2>`R'!,+Gv<˗(gc8WE!?g8H„C|Vm]&@2-|ͣ /qmsg~4~5m,= (A)AN>$DK ṿuG^qBI%^@dayq~B%x d崬\;h e~<({AS*jDwn DCJĭ:9L f<@!RcDhta Fa"وX*^y|KƬm1 c$Z"R%op-x(vK*1is -[[o`Gfmm֕ev^w} ׯ7>$Yn-π;՗屻Ox`Ӛ@& Wa`hNݑ)T`(B7I,zhn@0 (0~eu W.fOXv`XB*!~] -o}Zdz\>Q)OO?ΕgI#qnRW\." -2t F]:5=,sz@oWEb<¬cc- ,F1+ŎzhE˻꾳]wcc=&+xi)iVL΁ZsjYFY8ħϩ@Ϯ{A?-FH%^R?lIP]JeiVܐ3{ynE+=(]W}q6%$U^+ē:r1AX߽ ;YjIPt!:>{N"v`JsC蚽8Nzy(dMT%PGf~DWC;+1ټeWL0auFAԑH:Q핬ZÝw^^h2K\CN:J'\ωE.n}.s)fa l[ r9qqԹu"+Q L$'5;S'Y\l5S=z!_B4J|gIqI)ehPB s?WOcݔ!7Z`ʲSxǓ&,rƓA,a9Vi C=`xH{lZz#ɔ8'6}*_uR.kU1+ZxbV!O轀MOVg>G1Q."Xf7?G{'a~1FW44no JK -M -b0~.KhHRf+ƞ͠'8n5|If"ˮ! -ǽz@y%Fyx͹(U? Hakx.L\C77dʕt}\%77dF(s]%)@A3"3Z'GPmsf(a񦵻YZ2j:ppNG/zQ%$KMcr/Z{^♫ WcMvNz|/25 ]ޕ#Li'  ?&s|.%X=mpiɒXg"r`| (Pk/YĨB|o]f  )|/O[p8sLG<{פpr5Tq3@ bmlf7A,TX Prl[},;nU+!qvlAAJu ͒:͟NN%9XR.8 FbV=rj@/ #F3KrP ֵTJP{@RRN{H_H 4G6?u"dX'Ϧ"]#oaɜ$ʡ|6O-/&Y$@ fHA U΁ga"o_8竟e^OnJF ,G iu!°,EmoIcA>_Eɜ7|b纫Ŀ’20>%0t #$R3/,-kEVbmZ,K+9՚%1^o =Sh¿f0~Q_FܹC*:Eп;SʊGw[_m0qL[9xLW(F5yr1ۄuJD2^x˲~fbvkE"wJg;"s\aX: f1t)bǥm_8 5l)jMD%0m:UR REz`s%] *DJy2 -^%=ssmUWHx= PpQ#Z`"͞+-.7[\0R1L]Ց)WVC!*h - 6Tj ayX]Z6=zэЦ?70 -Rf #}n1l 2`W/e%Rdq] ,$^7(}8w[C?)Qʷ([m DLdא*Ktox/ !=z:C|KM].BM;C?+YP/:U3R$Yn'[-/")€[Dv(ðɰa-}j| -82N}/A#26Af+o/~X]p%+fHP}wd%5¿9sΊC2{.¡'K0j5ww(6/~b{wݺ>zwC r&xM -.&b]sZϏՙ;)9{2#0 )":X>=py)b&:3} my6Х4r\5{aҾWz3/zn,"Kڽj57[kQ g^f.8₰ΡPglL{Һ&*W]o-5bjBWaqTD5D!1q!k)|y:85٠@DP c}\HC%B!uL -.'e^9M[ 27Sm'[teSCopeKU;Kvi,_[Bs&ٖ/5`\cأj[j$Ezv2 -)4Cn -z<=|i> Lm]DLqT#%ͦ~Z]Tӣ;&[L}tuJ˼Cj6]˼̮ -NY1X6zteFTt6L~<ݕڋ5MMe@f֕t]$V邑sپG\t<_LWvCBTLWOq(տ>2 .-gq  .z6CM֡{`]^2ܛ|"U~抛Ge9դ[`aF-u &IgWFܮ,=9N2b(1xhy>ǡypۂ,}Nʘ\g.+ e)K$R2de֗$d6“weJ2Љhbu bv.93aTXl`i2&BR_g$.b GT싰{NID33˗Df˨JҐ$X?A%Kđ@BdCHS^)+-/pgg]j@m]I$BlV_O5gȥ3KqT 5%Ľ|ږ!6^顫q9!ѹ)A$]S/oRos $nW -Y|%ޫs & -1 VL^U.k* LDpK^M/R:b S.(D -k:)p^xDy 6U9?~ AΝ.C q"Rf$ģt??q?t?j -UaM k*CθGQ\[_s,fȿL>-Ogx=Q3|%|ήe|26Һi&f` 0a槀9޻@KA=X2=!oՠĞ.A/i+ ^SjvWƌ06ewbǍ2gEg{W%Yn,a͘G[PYh6Ipn3!bܠ'0pUj@d -Z?UQzl0Mpl캅Ik2^&7Ű%=9.nQ0n}Q`[3vȸ0{#K3/pLY -H”nvn @ xp~}RS>KB;FX Ĉ56*J1/ۅ:^/ N53ЁA$ڽRu,wbڿ%:x=ʌVZ— u8 eYy1҄ZжԦ=V5U JpXt+BNKDllcjIP[\Ms{ T-6?j51œ'+ʹyֳ -lncBTNu2noeYBT=,e Hiܜ\BJer}#:2$P1p4OL"dᕶIC&sgU|&SyZ.Wƨ2?رVn5SH\\ cU;O)*JO7"t a7 y2v[>dw=?"hÄ30=o֯:$}xaN :)5p#k gmB@JȕaP"K[9 4#'R y;6(wU ؇/ா,&2fH &篫,xxB,Q +9m_X}*5B2~K# P(H2rR\>5ClI@m=+2O0YICPf[ƩW6.C,+ `Q-m>-#Bj:XWqMT ']M -*. a25J J"eϻ]F @|9Ss;XC&Oi -V^aPŌE;~:Z[|*PPTY9DJv&~ter`3jFg"EY439ЇW1<XEb꾻$J^+ǾӾ9F@B;y 0k!ѝT/%>d4)}Y /F̒JY!&*۫Xe -V3#)'_&Y94eiBmeѱK+m?d`2?ĺ` ӦKأSbXN^3v^~y|C<hSJ`arsiy[äTUHQbǨ:NwIoY[$X$1'=ЀqB~sVkඛI#fy ֈ=#2}KF##x)Fj=F^"'܈8k/mu.q l1>EozLe%dbQ6 *WoTPX?q7%<L~^](ɜ:G\ߦ龑F$6tχosڱ8 -̰ht] /Fd7;?uXO׼=0@ tf@UGbDs,F3Pɒޡp9$~`R-8$0ZˇyYISiK?65hgvzgFp։;2V^0+WfZ )%~Gr5 dI -:p%>lba"dPe\[&.f5c5:+sr ^\ f2쵻/;B 2;.PՌFtG Qp4T``nRk^;͙Pu}˖z Y+ılҠӾrT[.9sJC۟xp$YW8j^y1qvU6qH2&`9ࡾw}uuM\C *-@`$z)E"E.v 8af#  xv[ܾNU- ?$я8!9;N 'l -p>EIHRջ&̴~IhZHX@@6۝j1Ĵլ 6~j Op5hyp_h <>\q TO`p:OYH4tuЍLyhpZđ*Qb} $9_ҷ5 $E@ -鮫r`i` -m+dqRi(WIƳAb cMmk_\ Mzria\'d2Ԕp&$ȇ/އrq -2G8@Z8cw85gwCO>4,Pɫ*tSl>} o(^/v[ ΟOşr Tcn 8r=qs8"oZ),k6 \1`&]vSZ!>b̸C|H㸓`AlA⭅ݬh(Ԏ-On1O- jzZE,;S>w Mn+YK.6Q'e'!p_r@G4[n8y%h *W"yPbι,3vQ@(d19o/_ d$hQGWC࢑@ʕcUi.!tr`m(Qoz$YfGy\侨Rdw㭷DTSp{hgCwʾݸ'B)nΥ͘҂禙 #0duȐ ~Ti^-`P?GpH^E+[= -Ļt8 -!$V`Ú,._sAj$Mm5i5^Z= 5)W\C'upӐhHB;<c96 -O7&>_JA@}ռ#KqIlV(^*vѢ\Eț* AY.杒A9$Uu(y&Ƴ)VӰP -ɑ|!*R,S6?j)\^=O9t[Ʉ:g؂9(*Y^ >{mjY!;ƷKzS:TԘuARQ%^4%Nܯ.ɋ[67)_! xlMZ endstream endobj 22 0 obj <>stream -|U,@&1c5%Pנ8ϵ*^x'Dx`DqI zK7w$e(\WxO=7ubǩ HѶ#*wGBz J0*"趽`(01M$WB%wT+j͔SvXDx8 5Q0vԆ?;`w{a%-71%A E9M弄RL+NziZOeGgVo6N,U(^M`ZySk -gaR+ZN8ra:AfH@'!ACUOb霓yP{E1}L. ٍ]w6\aTU4<.U U/T5W+Чs'R0Rx_I3]hioK…7WNm{\%(YQvǥ&yx݀yL{R ]ϡ3̶?%HEq٘n]}ஈMˏ - 僲2mBЏ$6n=Hƺf D1T -pre&5؊zQݙ '!z_.6`.RGm*5ps(p]5vG [ ц]KS8p-鈞=\8Z(M[_a5A5WI %\<{Tj Ae+xHϤ -"[-t4?k bť ʚ) -*5^U96Tr e"b4T1ms/,]~\kr178@'mYAHİV[b%S[_dE۳"!t#:'elna CHcѓ(kGԷQ)MH֚BAڟ} nd_ 0vs?Ä́?X p+_jsBL rASfSC!fk^l!8!`FSk=m -c <C} -1P gi:Qi- fy:|giɢ?NU#VRN -!q^IZ\ -yl Mxp~ -j-YnlXJCGDz t}QoH-,Hj*-D$.b]L^}&L54.C?VXx.=wp6̯eCnJP&=|֥.䨁[FA694ń㻚p3+8&tDܑ|~l?!g1(ZD2u bheV!QLLKAututSK>Mob ZcdS7a!Ys -ÞdXF_vRdxv}6n3Fsba75 ,<p#` tw?RZG|yhDA:G%hTm1[r{A39b&XiBހDGhlH78\s -XUNgΌ2#45Z E?#ˌ$hAJM,L&#<|T]Wmm=/'g坠I|m^-QZC!{IE<v]yKz}bgE<9:, #{(םF@REc!]bm NEݛhDnB_L(-}FKbý#s@m|zyt>2p>t\0\I׉8SX+1.'G]a^@ĩ# |LFi-&' P<5=EyM]j6P>m1u`=,{:0 ADJJ;T2OG wTQaC IG[Tlm x/SdmLŤٛfb&䦗h\|!^<S + Z2B+SA -N[76p=?$5nS7P ~Y1Mdk}zv8"Y M˥RJiZ_@؟S3P̐ -| /*Rٰ̿If%gٽ1xYź mhȨ(" :^2 Ei!z{ޭϓBK3= 4kjՁk*Ha{2j8dmCIIoJwTbh7%R3"ۑGКǹ:}`*_^QҫMe_Y`pcbGy&5-V$n(+ A> WgNfBzk`UdTxd'cȫ`Bz@IZ1y1PDRٍ%T -f{Nf^H, 8 -)7?*ATg!g`4T!nHJY"h]?.ޤB@@9ovgess虅hf(˭'@*?\@vh`O8_ћF<:'6!(% E(Bw2C.|ޫ-n`(MԞ(uLUw3le[ӏQo sn 6 -gqO9lwg2.y[iRJUi3 -ɬk AG['{^VR -I٥̹ҏ:!RbRZǙc̜;h@r? p jV >OKر]>0*O"7L>ڕ?qP<ԫ ՁLZm"^n1u1nM)̀k>āsD2髒2\]j'T4M -:53D,(i3 -[lӅo18ʮ&?*H9}@K抮/P -@WCW$iW:3^S8G5.885QD4lqzeH!L_>kOVfp=8/xJʘX J64E$dN Gtł㑱dbsN<.pHkq$\=wm2, TkF'%+-|Š D<iB:CsYq+8 U3Ժ@.U K6&!89|ߎ}+_6(IG9mZz"s$f LǎҸ;tNcޮLRKA 0n_&xlib;He0GmD]lX9z!Sieiw~31t@K0jxG"&-Ϧ ii<yĚc8c:)xUl%]* 6 $ܪGi`Z_pcOOm}=ѩQKg|E`yĜ ˑw< ibEzڔJDo@3lRB?*,LK ,$j6E=K܉9_YIlmnq`)0@XC@fʉ͆SHe''ԑh:3Hpc'+wV!ґ;Aqtj6 Dѯ2c$P|f I M n5byoVk.5\A+XQ8ZbN\2W"pG2*)=A6Ll\ܺF[mDZj#-7*y<(GDS*ӷ5(%J)wTSY # 0Z~>s g7A ]2' -n IZjU1~|yF7R.[晍~P=p2JtmyPomTb=aƀ 6tW;dPؾ7"c&ghuMXOrYG$:C0vOѾև~hfnH9\_W -(Ğ7+3š0WH@%E/n|{؅:;]d?ҩ͉0U p?s̹~Ű=T(2Pfj󭤇]YVH'HXg?&j(d22!C|&dbpITYXԮ2 !tRdC=Q @ id5Svb#4FDq1|+*+t&K,f<)q`H Tp& -q n!CR#N5}YhזDd"Er^H/*l\wDAYT~sh3N<^=E%/O6/+/bR8FH]l"[JB,S@3ː`K۔&MSD(ثE7+Pn'Ȑ-@ZXP6_p~!y9]R;gnטsxhHq\ryvuWTH1}E= %":g*%306!ZWV/Zmqj/hEh|%![i}}KbG!PU+,@+e,Z&V1ńcm$Ͷ鋡1 9qϫ ~nrr@U# Y?*ɶ&bK:Wk./A6s7\at?ˆ7 -$I6*+IְDwDͷQc<\tjHgs8 $1*tbx7x@ 8'Q4(k `r !r0R],c/2FMs P%zx(|-,>KFıލřUCi$Ds"Hh LjuЁ}<%OXJHY=yj@4#BF@ΠX短7nfzXWq/fXB(%%ӡvci~tƂ<Ѽy({`N+5m#i+H!.b@\oDH8}P@W{>Bp yzÎ1)xVIQQpE˭۟MژB#㤺A;u:0Zir(p!lZY+!AqE- e9q.OQϨ':(zFs&:oel,|kiPaƻd6 -,5lgN02CO%d7D` ʚ86m$3M?y1!Q%^Vl!UIQ;p0E qԚ$3nlp*-<95%}'E,oZHvCښrATkA)dx)mtcLJUl`rp?N9Z`vݢ2\1hM_C(0z>FKԇ h$(*̣As!N縧:㞁 $(h@lG&iCqՑa1i|2 -{MISQ$af<`gxMnc 0Kkp5a`(YF'lҭ^޻'0m<#{)+O%NO5GuxA Bub{1s,׎@G" =̇`V|Yo4/CMύR>-ztr#\Zdrn\PȐk9OC ~Wꓲ ~2֚Ci> sU&-j82ȡxJ:j@yZzJwCc(K ?`d `Rٚ:s1=5=[pnN*hr<t^,N"ێhCј]p4ȥh㪐Ũ rR:M[}&E>q [,4 H8>C#*0B)nD:4}fŞ8¬ƘdQB܆2*bցn =T!!Uumdl0nJdJhةCam:{A„ =]Xνn!N- S A\4LcdZ Z.4<̍Y"D< -# -N 3bmH?r&,~>irHxa ("ҚCb~JL-Pr؀HP˥a N0r`ũe<,_HxR҈p襼tZUB  CWC[ (a8pbn1:` @0Pg<,xX(rm@V-6<[a 0 ӰMG4zX8Q|8U22~aq,gBߦ#a"(a: Cd. KSTT# -xB8ˁL@m2P8 } HzOú<q6.8&t2oxXoN(4 S0dEX'xCD¥4 -GfS.,` I E3FIVLI6(FN81#u҉¿9X'Dæ}dC {Ho( _xF$H^XԢ/D U`]ECp m B*c@&۸ Im) 6*ߦ !Pg>:<pLՊ&4dlta {)hȦ`B#hAWD<,i9& -oq1U<3ҷ%&yvC]Sa|Nw\әgjnC:?kS77UeL5#ܨ+}v0N.;v}n~*eK;rr9nq?)9u:nSA {Zgܗ:2Y}RrzcpjCeUJ -_~v -]naJ$⺜4)k2Gbi.bO&lK}2Գy)3vhjiNط`i&4MX y\Aeb}@*8rPBu#Kw}*v9?2e엻Vqg;.re'-:FS*_gn}PrܸϼSjd[uTmuQy]mSCVʺ:9.e -'k*|}| 'Vo+g|ߏP#Ge<'GfFe_(;\+;٭>We `js  @(0a=@pj01 H_[g> ?Fܰ*PHm]ŽBFCާwaZ$0ut$~dob -ZhLUvVq,;Et$ZFxYe`^ fV5tʣEA 1X#ELf+NRN:0ɧc" rq` K/F2^{{9qsz6tͅ 7RWIm]eA)U_7,%"OH=I^*M?;i frc7lb&K)zPU$3jŖ^ TW YQqNO_Kѣ*ְ09 -[IS5<K Df3~f*uODpv%CJ01fBw4D~|Gզ@x-^㹞 OX >T/'@+e#{؞RMHBx -9TrfC%;$(ʦ2ocdqI-ވ]:E -_ze9\Kn U;ςzF,~8 eZ!FO #;FPhE,@tv#Es!P3scRʌn`.gTq?  Ѷ1t/6 -3"\mvX*SQG{ <&yq?$9{-t *ێ׊J d–2?Go:FAm3q- y{<#kn;zCxNjJA=HLAv [%YADuqXOq$Aw~a J?qwDқ=`e6=~Mv|/NfYܙ,qǣfh7{M`FmuSGl85xvܦ+zBvVqo550qOf\v\wOTKTt~?6DydǙ1r'ܫ.,#{d{FM5!C9Yh8btS c  ,)4BOBaE37}vG>Crk+> u?(5D䰷&?_N`=HIlJ2Œ䪘LO{@yH^\+<7OZVPWR; LרyX1.nWWL8WH*Dj -Į0r -Lդ;а+U -eW+C~`vv! ؕǫ`g['ɠtwsD%/]Ɲ1dW~A|x3UX  endstream endobj 25 0 obj [24 0 R] endobj 35 0 obj <> endobj xref -0 36 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000046539 00000 n -0000000000 00000 f -0000046590 00000 n -0000000000 00000 f -0000051569 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000051642 00000 n -0000051882 00000 n -0000053070 00000 n -0000118658 00000 n -0000184246 00000 n -0000249834 00000 n -0000315422 00000 n -0000000000 00000 f -0000048586 00000 n -0000327345 00000 n -0000046981 00000 n -0000048886 00000 n -0000048773 00000 n -0000047620 00000 n -0000048025 00000 n -0000048073 00000 n -0000048657 00000 n -0000048688 00000 n -0000048921 00000 n -0000327370 00000 n -trailer <]>> startxref 327568 %%EOF \ No newline at end of file diff --git a/misc/branding/no_bg_dark.png b/misc/branding/no_bg_dark.png deleted file mode 100644 index 8766a07c..00000000 Binary files a/misc/branding/no_bg_dark.png and /dev/null differ diff --git a/misc/branding/no_bg_gradient.ai b/misc/branding/no_bg_gradient.ai deleted file mode 100644 index a0b90616..00000000 --- a/misc/branding/no_bg_gradient.ai +++ /dev/null @@ -1,1772 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_gradient_nobkgd - - - 2021-03-19T18:09:54-07:00 - 2021-03-19T18:09:54-07:00 - 2021-03-19T18:09:53-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 240 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADwAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUPe6jYWMfqXdwkC9ubAE/IdT9GLVlzwxi5kBjV/wDmTo0FVtIpLth0anpofpb4v+Fw06nN 27ij9IMvsH4+DH7v8ytblJFvFDbr2NC7fexp+GHhdZk7ezH6QI/alFx5s8xz19TUJhX/AH2fT/4h xw04M+0dRLnM/Db7kvlvr2U1luJZD/lOx/WcLjSzTPMk/FD4tbWKq0d/fRGsVxLGfFXYfqOLZHNO PIkfFH2/m3zJb09PUZjT/fh9T/ifLBTkw7R1EeUz8d/vTi0/M3XIiBcRQ3K9zQo33qaf8LgpzsXb 2YfUBL7GQaf+Zuiz0W8ils2PVqeog+lfi/4XBTs8PbuKX1Ax+0fj4MnsdT0+/j9SzuI5078GBI+Y 6j6cDtsWeGQXAgonFtdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqWax5k0jSVP1uYetSq26f FIfo7fThpw9Vr8WD6jv3dWC6v+YmrXRaOxUWcP8AMPikI/1jsPoH04QHnNT23lntD0D7WLTzzTyG SaRpZG+07ksx+ZOSdNKZkbJsqeLF2KtYq1ilrFXE4q1irWKtYq0Tiq6G4ngkEsEjRSL9mRCVYfIj fAyjMxNg0WV6N+ZWr2hWO/UX0A2LH4ZQP9YbH6R9OCnc6btvLDafqH2s/wBF80aNrCj6nOPWpVre T4ZB/se/zFcFPRaXXYs30nfu6prgcx2KuxV2KuxV2KuxV2KuxV2KuxV2KqV1d21pA9xcyLFCgqzs aDFhkyRhHikaAef+YPzDuJy1vpIMEPQ3J/vG/wBUfs/r+WSAeY1vbcpenFsO/r+xhru7uXdizsas zGpJPck5J0BJJsrScUNYq7FWsVaxS1iricVaxVrFWsVaJxVonFVpOBWicVbSSSN1kjYo6mqupoQR 3BGKQSDY5s38t/mZc25S21kG4g2Aul/vFH+UP2x+PzwEO+0Xbco+nLuO/r+16PZ3lre26XNrKs0E gqkiGoORenx5IzjxRNhWxZuxV2KuxV2KuxV2KuxV2KpZrvmCw0a29W5blI391Av23P8AAe+EBw9Z rYYI3Ln0He8s1zzDqOsXHqXT0iU/uoF2RB7DuffJAPG6vW5M8rkdug6BLMLhuJxVrFXYq1irWKWs VcTirWKtYq1irROKtE4qtJwK0TirROKrScVTfy/5X1XXJuNqnG3U0luX2Rf+aj7DElzdJocmc+kb d/R635b8tWOg2bQWzPI8hDTSuftMBTZei5El7DRaKGnjUd75ptgcx2KuxV2KuxV2KuxV2KpN5l8y 2uiWvJqSXcgPoQV6/wCU3gowgOBr9fHTx75HkPx0eUahqF3qF091dyGSZ+pPQDsAOwGSeKzZ5ZZG UjZQ2FpcTirWKuxVrFWsUtYq4nFWsVaxVrFWicVaJxVaTgVonFWicVcqs7BEBZmICqBUknoAMUgW zzyv+Wss3C71usUWxSzBo7f8ZCPsj2G/ywEvQaHsUn1Zdh3frejW9vBbQpBbxrFDGKJGgCqB7AZF 6aEBEUBQVMWTsVdirsVdirsVdirsVSzzBrtto1g1zL8UjfDBF3d/6DvhAcPW6yOCHEefQd7yLUNQ utQu5Lu6fnNIak9gOwA7AZJ4fPmllkZSO5Q2FpcTirWKuxVrFWsUtYq4nFWsVaxVrFWicVaJxVaT gVonFWicVRWlaZcapfR2VuyLLKaBpGCKPv6/Ib4t+nwSyzERVnvet+WfJWl6Iolp9ZviPiuXHT2Q fs/ryJL2Gi7Mx4N/qn3/AKmQ4HZOxV2KuxV2KuxV2KuxV2KqV3dQWltJc3DhIYlLOx8BiwyZIwiZ S2AePeYdcuNY1F7qSqxD4YIuyIOg+Z75MB4TW6uWfIZHl0HcEswuG4nFWsVdirWKtYpaxVxOKuAZ iFUEsdgBuTioFpzYeTPMl6A0dm0UZ/bmpGPnRqN9wwW5+HsvPk5Roeeyd235WakwBub2GLxEatJT 7+GDidhD2fyH6pAfb+pGp+VNsKepqLt48Ygv62bHicgez8esz8v2uk/Ki2NfT1F18OUQb9TLjxKf Z+PSZ+X7UBc/lVqSg/Vr2GXwEitHX7vUx4nHn2BkH0yB+z9aQ6h5K8zWILSWTSxj9uGko+dFq33j DbgZuy8+PnG/dukbBlYqwIYbEHYg4uARSwnFDVabjFWZeV/zHvrBkttULXVl0Ep3ljHzP2h898BD u9D2zPH6cnqj9o/W9Rsr20vrZLq0lWa3kFUkXof6H2yL1ePLGcRKJsFWxZuxV2KuxV2KuxV2KuxV 51+YfmAz3A0m3b9zAa3JH7UnZf8AY/r+WSAeV7b1vFLwo8hz9/7GF5J59xOKtYq7FWsVaxS1iraI 8jrHGpd2NFVRUknsAMUgEmhzZloX5b3lyFn1RzawncQLQyke9dl/HIku90nYc575Dwju6/sZ1pfl /R9MUCytkjfvKRykPzc1ORt6LT6PFi+iNff80wxcl2KqL3tmho88anwLqP1nFrOWA5kLorq2lNIp UkPgrA/qxTHJE8iFTFm7FUu1Xy7o2qqRe2qSP2lA4yD5OtGxtxs+jxZfrjf3/N5/5g/LG+tQ0+ku buEbm3aglA9iNn/DJAvO6vsOcN8Z4h3df2sHlSSN2jkUo6EhkYEEEdQQcLoiCDR5rCcUJz5X813+ gXgeImS0kI+sWxOzDxHgw8cSHO0Ounp5WN49Q9o0vVLLVLKO9spBJBIPpU91YdiMg9rgzxyxEomw UXi3OxV2KuxV2KuxVLPMmsLpOkTXdR61OFup7yN0+7rhDh6/VeBiMuvT3vG3d3dnclnYlmY7kk7k nJvBEkmytJxQ1irsVaxVrFLWKo3SdIv9Wu1tbOPm53dzsqL/ADMewwN+m0080uGAeqeXPKWm6LGH UetekfvLlhv8kH7IyJL2Wi7Ox4BfOff+ruTzA7Bjus+edF04tGj/AFu5X/dcRHEH/Kfp91cIDqtV 2vhxbD1S8v1sO1H8w9euSVtylnGegjHJqe7NX8KZKnRZ+288/pqI8mPXepahdEm5uZZq9fUdm/Wc XWZM85/VIn3lRW0vJByjgkceKoxH4DFAxSPIFRnhuIv72N4/9ZSv68USgRzFK9r5i1uyINrfTRAf sByV+lTVfwxpvx6vLD6ZEfFkmlfmxqsDBNSgS7j7yJSOT57fAfuGCna6ft3JHaY4h8j+pnuhebdD 1tQLK4Hr0q1tJ8Mo/wBj3+a1wU7/AEuuxZvpO/d1TjA5iQeZ/Juma7EXcCC+ApHdIN/YOP2hhBdf rezsecXyn3/reP61ouoaPetaX0fBxujjdHX+ZD3GSeO1OmnhlwzCXE4uOn3k/wA13GgaiHJL2MxC 3UI8Ozr/AJS/jiQ7Ds/XHBO/4TzD263uILmCO4gcSQyqHjdehUioIyD28JiQBG4KpiydirsVdirs VeZfmJq5utWWxjb9zZijeBkbdvuFB9+SAeQ7b1PHl4Byh97Eyck6RrFXYq1irWKWsVRukaTd6tfx 2dqtXfd3P2UUdWb2GBv02mlmmIRewaHodlo1kttbLUneWU/advE/wGQJe40mkhghwx+J70wxcpgn 5k6lqMMlvZxO0VnNGWkK7c2rQqT4AU298kHm+3s+SJEAaiR82KaP5c1bV3/0SH90DRp3+GMfT3+Q wkul0uhy5z6Rt39GbaX+WulQAPfyvdyd0X93H+HxH78jb0On7Cxx3meI/IfrZLZ6PpVmALW0ihI/ aVFDfS1KnA7bFpseP6YgfBF4t7iAQQRUHYg4qlOoeVPLt+CLmwhLH9tF9N/+CTicNuJl0GHJ9UR9 33ML138pDxaXRrmp6i2uP1LIB+sfTht02p7B64z8D+t51f2eqaRe+ldRSWd3EeS1qrCh2ZWHX2IO F0OTFPFKpAxkGd+TvzYZXSw8wNVDRY9QA3Hh6oHb/KH0+ORId7oO2T9OX/Tfr/W9TR0kRZI2Do4D I6moIO4IIwPSA3uEt8weX7DXLBrS7WhG8Mw+1G3iP4jviC42r0kM8OGXwPc8Q1zRr3RtRksbtaOm 6OPsuh6Ovscm8RqdNLDMwklxOLQ9F/KzzSUlOhXT/BJV7Fj2bq0f09R718cBD0XYmto+FL4fqenZ F6Z2KuxV2KofUb2OxsLi7k+zAjPTxIGw+k7YtWfKMcDM9A8RnnknmkmkPKSVi7t4sxqTlj55ORkS TzKnixdirWKtYpaxVtEeR1jjUs7kKqjcknYAYpAJNDm9g8peXI9F00K4BvZqNcye/ZB7LkCXuOzt EMGPf6zz/V8E8wOwdiqlc2lpdR+ncwxzx1rwlUOtfGjA4sMmOMxUgCPNfHHHEixxqEjUUVFAAA8A BiyjEAUOS7FLsVdirsVdirsVS/W9B0vWrNrTUIBLGfsN0dD/ADI3UHFo1GmhmjwzFvDvPHkXUvLU /qitxpkhpDdAdCf2JKfZb8D+GSBeQ13Z0sBvnDv/AFo78ufzIl0W5TTNUkL6RKaJIxJNux7j/I8R 26jvVIcnsztI4jwT+j7v2PcwQRUbg9DkXrWP+dfK8WvaUyIAt/AC9pIfHuhPg3698ILr+0dEM+Pb 6hy/U8NlSSKRo5FKSISrqwoQQaEEZJ4ggg0WoLiW3njnhYpLEweNx1DKag/fimMjEgjmH0D5b1qP WdFttQSgaVaTIP2ZF2dfv6e2Qe90moGbGJ9/3pli5LsVdirEvzJv/Q0aK0U0a7kHIeKR/Ef+G44Q 6Tt3Nw4hH+cfsH4DzLJvIOxVrFWsUtYq4nFWZ/lvoQubx9UnWsNqeMAPQykVr/sR+vIku+7D0nHM 5Dyjy9/7HpWRerdirsVdirsVdirsVdirsVdirsVdiqje2Vre2stpdxLNbTKUlicVBBxYzgJgxkLB eSXP5E3j6wfQ1CJNHZ61YMbhUrXjxpwJ7cuX0Ybedl2CePaQ4Ptevxoscaov2UAUfIbYHowKXYpe T/mt5dFpfR6xbrSC8PC4A6CYCoP+zA+8HJAvK9t6ThmMg5S5+/8Aa8/Jwuheifk/rRju7rR5G+Cd frEAP86UDgf6y0P0YC9D2DqKkcZ67j8fjk9UyL07sVdirzL8yrsy63Fbg/Dbwio/ynJY/hTJReR7 eyXmEf5o+9iWSdG1irWKWsVcTirgCzBVFWJoAO5OKgW9t8v6WumaPbWQHxxoDKfGRt3P3nKy+gaP T+FijDu+/qmGLkuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVLPM2jrq+hXdgR8cqEwnwkX4k P/BDEONrMHi4pQ7/AL+j55cMrFWBDKaEHqCMm8CRSO8u6odL12xv60WCZTJ/xjPwuPpQnFv0mbw8 sZdx/tfRYIIqOmQfQHYq7FXjfmy49fzHqEla0mMf/Iv4P+NcmHg+0Z8WomfOvlslGFwWsUtYq4nF WsVTryZYC98yWcbCscTes/yjHIV/2QAwFz+y8PiZ4joN/k9kyD3TsVdirsVdirsVdirsVdirsVdi rsVdirsVdirsVdirsVeCfmBpo0/zZfxKKRzP9Yj8KSjmafJiRkg8N2nh8PPIdDv82OE4XAfRHlG+ N95Z026JqzwIrnxdBwb/AIZTkC99ocnHhjLyTbFynYq8LvpTLe3Ep6ySu33sTlj51mlcye8lD4tb WKuJxVrFWsVZt+VlsG1K9uSP7qFYwfD1Gr/xpkZO/wDZ+F5JS7h9/wDY9JyL1TsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVeS/nPaBNV0+7Ap60DRk+PpPX/mZkg8t2/CskZd4+7+15yThd C9u/Ka59byfFHX/eeeWL7z6n/MzIl7HsWd6cDuJ/X+lmWB2zsVeB5Y+bNYq4nFWsVaxVrFXon5Up S21GSn2niWv+qGP/ABtkZPT+z49Mz5j9LPMi9E7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXmv51x1tNKlp9mSZa/6yof8AjXCHnvaAemB9/wCh5OTknmXsP5Lux8vXqfsi7JHzMSV/VkS9 X2Cf3Uv636A9BwO8dirwLLHzZxOKtYq1irWKtE4q9F/KiSttqMdfsvE1P9YMP+NcjJ6f2fPpmPMf pZ5kXonYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq80/OyWlppUVftyTNT/VVB/xthDz 3tAfTAe/9DyYnJPMvYfyV/44N9/zFf8AMtciXquwf7qX9b9D0PA712KvCL+MxX1xEescrqfoYjLH zrNHhmR3EqGLW1irWKtE4q0TirN/yquQupXttX+9hWQDx9Nqf8zMjJ3/AGBOsko94+7+16XkXqnY q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq8h/Ou8D6tp1oD/cwNKR4eq9P+ZeSDy3b87n GPcPv/sebk4XQvbPybgMflKRyP767kcfIKif8a5EvXdhxrBffI/oZ1gdy7FXi/m23+r+ZNRjpSsx k/5GfH/xtkw8H2jDh1Ex53890owuE1irROKtE4qtJwKnfkrUBZeZrKRjSOV/Rf5SjiP+GIOJdh2Z m8PPE9+3ze05B7l2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kvnz8xNUGo+b9QlVqxQv 9Xj8KQjgafNgTkg8P2nl8TPI9Bt8mNE4XAfQ35d2RtPJmlxkUMkXrH39ZjIPwYZEvc9mY+HTxHlf z3ZFgc52KvL/AMzbQxa5FcAfDcwip/ykJU/hxyQeR7exVmEv5w+5h+SdI0TirROKrScCtE4q4Mys GU0YGoI6gjFINPdtB1BtR0azvXUq80YLginxDZqV7Ejb2yBfQNJm8TFGR6hH4uQ7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FUq81a0mi6Be6iTR4oyIR4yt8KD/gji42sz+FilPu+982u7OxZiWZ jUk9ST3ybwRNqthZy31/bWUX97cypCnzdgo/XizxwM5CI6mn09bwR29vFbxCkUKLHGPBVFB+AyD6 DGIiAB0VMWTsVYf+Zun+vosV4oq1nKOR8Ek+E/8ADccIdJ27h4sQl/NP2H8B5cTk3kWicVWk4FaJ xVuOOSWRY4lLyOaIiipJPYAYpjEk0Ob0fyl+XSQ8L7WlDzbNFZ9VX3k8T/k9MBL0/Z/Ywj68vP8A m/rZ6AAKDYDoMi9C7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq8c/ODzOt5qEeiWz1gsjz uSDs05FAP9gp+8nJB5XtvV8UhjHKPP3/ALHnBOF0bOPyg0U3/mc3zrWDTUMle3qvVYx/xJvowF2/ YuDjzcR5R+97lkXr3Yq7FUNqdjHf6fcWcn2J42SvgSNj9B3xas+IZIGB6h4TcQyQTyQSjjJExSRf BlNCPvyb57OJiSDzCkTixaJxVF6VpGoardra2URkkP2m6Ko/mY9hi36fTTzS4YCy9Z8r+TNP0OMS mlxqDD47hh9mvVYx2H4nIkvYaHs2GAXzn3/qZDgdk7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq 7FXYqxrz55vh8uaOzoQ2o3AKWcR8e8hH8qfr2wh1/aOtGDH/AEjy/W+fJppJZHllYvJIxZ3Y1JYm pJPvkniiSTZUycUPoL8tfLh0TyzCsy8by8/0i5B6gsBwQ/6q0+muRL2vZel8LCL+qW5ZVgdi7FXY q7FXlf5laMbTV1v41pBfCrU6CVQA33ih+/JB5HtvTcGXjHKf3sOJwukT/wAseTtQ1yQSCsFgppJc sOtOqoP2j+rEl2Oh7NnnN8od/wCp6zpGjafpNoLWxiEaDd26u5/mZu5yD2On00MMeGApG4t7sVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdiqU+ZvM2m+XtNa9vWqxqsECn45X/lX+J7YuNq9XDBD il8B3vnzzDr9/ruqS6hetWR9kQfZjQfZRfYZJ4nU6iWaZlJLCcLQzH8sPKZ1zXVurhOWm6eRJNUf C8nVI/fcVb2+eAu07K0fi5LP0x/FPe8i9k7FXYq7FXYqlXmjRF1nRp7Pb1qc7dj2kX7P39D88IcP XaXxsRj16e9hXlT8upp2W81pDFCN0szs7f6/dR7dcJLo+z+xjL1Zdh3frekRRRQxrFEixxIAqIoA UAdAAMi9PGIAobBdil2KuxV2KuxV2KoRNX0t9QfTkuozfRjk9uGHMD5YtI1EDPgscXci8W52KuxV 2KuxV2KuxV2KuxV2Ksa83+fNH8uQlHYXGosKxWaHf2Mh/YX8fDDTr9b2jjwDvl3freF6/wCYdU12 /a91CXnIdkQbJGv8qL2GF5DUameaXFIpYThaFhOKpxovnPzLokXo6ZetBCWLmLijqWIAJo6t4YHK wa3LiFQlQZJZfnZ5qgoLmG1ul7lkZG+9GC/8LjTn4+3Mw5iJT6y/Pm0NBe6TJH4tDKr/APCsqfrw U5kO34/xR+RT6y/OTyPcU9Wea0J7Twsf+TXqDGnMh2zglzJHvH6rT/T/ADh5W1F1Sz1W2llcgJF6 irISegCMQ34YHMx6zFP6ZD5pxi5LsVdirsVdirsVdirsVad0RGd2CooJZiaAAdSTigmty8284/mY fjsNCenVZb8fiIv+avu8ckA852h2z/Bi/wBN+r9bzgTzLMJlkZZg3MSgkNyrWtetcLzokQb6s58u /mtfWgW31iM3kA2FwlBMB7g0D/gffAQ7zSdtzjtkHEO/r+16Lo/mbQtXUGwu0lfvCTxkHzRqNkae hwazFl+iV/f8kzxcl2KuxV2KuxV2KpVrXmrQNFQnUb2OJx0hB5Sn5ItWxcbPrMWL65V97zHzP+cG oXivbaJGbKA1BuXoZ2HsBVU/E++Sp57V9tyltjHCO/r+x51NNJLI0srtJI5LO7EliT1JJ64XSEkm ypk4oWE4qtJxVaTgVYTilaTiq0nFXp/5L+TTd3p8xXsf+jWjFbFWGzzd3+Ufb/K+WAu+7G0fFLxZ chy9/wCx7XgendirsVdirsVdirsVQmqarYaXZvd30whhTuerHsqjqSfDFqz54Yo8UjQeQeb/AD5f 64zW0HK200HaEH4pKdDIR/xHpkgHkNf2pPP6R6Yd3f72Kk4XVrScVWk4q0HZWDKSrA1BGxBxSDSf ab+YHmzTwFiv3mjH+67ikop4VerD6DgpzsPaefHylY892Q2n5z6qgAu9Pgmp1MbPFX7/AFMadhDt /IPqiD9n60wj/Ou0NPV0qRfHjMrfrRcFOQPaCPWH2/sal/Oy0FfS0qR/DlMq/qRsaU+0EekPt/Yl l5+derOCLTToIfAys8tPu9PDTjz7fmfpiB9v6mNap+Ynm/UQyy6g8MR/3Xb0hFPCqUY/ScacDL2n nyc5UPLZjbuzsWYlmY1JO5J98Lgk2sJxVaTiqwnFVpOKrScCrCcUrScVWk4qnfkzypeeZ9ajsIKp br8d5cU2jiHU/wCseijx9q4uXo9JLPPhHLqX0vp2n2mnWMFjZxiK2t0EcUY7AfxPUnIvb48YhERj yCIxZuxV2KuxV2KuxVIfNHnDTNAg/en1r1xWG0U/Ef8AKY/sr7/dhAcDW9oQwDfeXc8c17zDqet3 hub6TlSoiiXZI1PZR/Hrknj9Vqp5pcUj+xLCcXGWk4qtJxVaTiq0nFVpOKrScUrScVWk4qtJxVaT iq0nFK0nFVhOKrScVWk4FWE4pWk4qtJxVF6Po+oazqUOnafGZbmc0UdgO7MeyqNycW3DhlkkIx5l 9I+TPKNj5Y0dLG3+Od6Pd3JG8klOv+qOij+ORe10ekjghwjn1KfYuW7FXYq7FXYq7FWFeefPraO7 adYRk6gVBaZ1ISMMNitftn8P1YQHS9p9qeCeCA9ff3freTXNzcXM7z3EjSzyHlJI5qxPuTknk5zM jZNkqJOLFaTiq0nFVpOKrScVWk4qtJxStJxVaTiq0nFVpOKrScUrScVWE4qtJxVaTgVYTilaTiq0 nFUXo+j6lrOoR6fp0JnuZTso6Ad2Y9FUdycW3DhlklwxFl9EeRfIun+VdP4JSbUZgPrd3TcnrwSv RB+PU5F7LQ6GOCPfI8yyfFznYq7FXYq7FXYq7FUo8x+WNN1609G6XjKn9xcqPjQ/xHiMbcTWaKGe NS59C8Z8x+WNV0G69K8jrCx/c3KVMbj2PY+IOTt43V6LJglUht0PRJicXEWk4qtJxVaTiq0nFVpO KVpOKrScVWk4qtJxVaTilaTiqwnFVpOKrScCrCcUrScVWk4qnflTybrXme99Cwj426EfWLxwRFGP c928FG/0b4uXpNHPPKo8upfQPlHyZo/lix+r2Kc53obm7cD1JD7+C+Cj9eRev0mjhgjUefUp9i5b sVdirsVdirsVdirsVdiqje2NpfWz2t3Es9vIKPG4qD/b74sMmOM48MhYeXeafyru7YvdaGTcwbk2 jH96o/yD+2Pbr88kC8zrexZR9WLcd3X9rz6VJI3aORSjoaMjAggjsQcLoSCDRUycULScVWk4pWk4 qtJxVaTiq0nFVpOKVpOKrCcVWk4qtJwKsJxStJxV0ccssixRI0kjkKiKCzMT0AA64pAJNB6b5N/J e9uzHe+Yi1pbbMtip/fOP8s/7rHt9r5YLd7o+xpS9WXYd3X9j2PT9OsdOtI7OxgS3tohSOKMUA/q fEnA9JjxxgOGIoIjFm7FXYq7FXYq7FXYq7FXYq7FXYq7FUm1/wAoaFrqH69bj16UW6j+CUeHxd/k 1cNuHqdDizfUN+/q8z178p9dsi0umsNQtxUhBRJgPdSaN/sT9GG3ndT2JlhvD1D7WE3NvcW0rQ3E TwzL9qORSrD5g0OF1EoGJoiioE4sVpOKrScVWk4qtJxStJxVYTiq0nFVpOBVhOKV9vbXV1MsFrC8 8z7JFEpdj8lUE4sowMjQFlnnlz8l/MWoFZtVZdMtTQlGo85HsgNF/wBka+2C3b6bsXJPefpH2vWf LXkfy55dQHT7YfWaUe8l+OZvH4j9mvgoAwPQ6bQ4sP0jfv6p9i5bsVdirsVdirsVdirsVdirsVdi rsVdirsVdirsVQmo6Rpepxelf2sVynYSKCR/qnqPoxasuCGQVIAsN1X8nfL1zyawmmsHPRa+tGP9 i1H/AOHw26nN2Hil9JMftH4+LFNQ/JvzLCSbSa3u07DkY3+5hx/4bDbrcnYWYfSRL7GO3nkTzja1 9XSbhqf76X1v+TRfG3Cn2dnjzgfhv9yUT6ZqcBpPaTRHweN19+4wuNLFMcwR8EITiwWE4qiIdL1O 4NILOeU+CRu3v2GBsjimeQJ+CaWnkDzpd09HR7ha9PWX0f8Ak6UxtyYdnZ5coH7vvZDp/wCSXmi4 IN5PbWadxyMr/co4/wDDY25uPsPMfqIj9rLtJ/JHy1alX1GebUHHVa+jEf8AYoS//D4Ldlh7DxR+ omX2fj5s30vRNI0qH0dNs4rWPuIlCk/6zdW+nA7XFghjFRACNxbXYq7FXYq7FXYq7FXYq//Z - - - - uuid:c5ad04ee-9e4f-5c4c-ad25-75c4b89747a6 - xmp.did:52ab3b84-11df-4eca-827d-44c335dd23b6 - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:52ab3b84-11df-4eca-827d-44c335dd23b6 - 2021-03-18T19:55:08-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HUAn0 @E4)([en-ОbWcrf}}(wO\??"Aj^ĘXj$ ",1Juҡek9- %ZD::wCi"u\ BA#Ji.~7rEQza K}WT);&k{yaESr@+0Io% ҜRqPYE[Rr^^̓΀$n^j`VL](é$$U0Xm?L`llBQo2v80nȑg:l$&mO˷pDGG֩ (&sGO?r<9NM"D -[y-4-q - ) #X'c\Mձ""ԳW%Щ m!s+1R;2{{pp@vdJ+}lغMG{Ȍ-m["OБ5E Uܙ87)= DhSjuVnɪXE2 ?E6Lyho;Gzvoِs^4P0[$otݠf[7i# J\[3+.4/9~|C; endstream endobj 30 0 obj <>stream -8;WRp>n4dq#_XkI@H<9_fVcEef3(rG&a:WHA(&ls@iXhPs$*%q,3h;J'G(!NFWm1M -Fn1.gN]t*WVpSD=jlUR:7>c!4;5^"#;07K?&S=7])kL1Go9%!\qsB1gZ`\*!c1$[\ -\>"..)WRU7&?B>KW4);S()k%$??VQ[+?["iF``NCC#sDOKL@2e&<3RMdqgLrPBJjL -#aD,*.l;L6H:]<:Sn?S)P4n#)reMf'O2YtEZWW(@*$LMn_f_H.6d=qZq(s;QJi+I: ->PDL/nnDlYc1AU650=e*PCgaQUo_3gH\Jntm-'F.SToK];A!6r+G>\K>!*OaP+CU6 -H%,W#!(r=kYl~> endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_gradient_nobkgd.ai) %%CreationDate: 3/19/21 6:09 PM %%Canvassize: 16383 %%BoundingBox: 19 -290 280 -10 %%HiResBoundingBox: 19.2573044618766 -289.215311004784 279.293839037604 -10.7464114832537 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -81 8 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/Xu -m* mm[QΜ&" -NRj0A "qxa$FRvrf)HV +'U$ZI-/ -8M(ZJH"eL -B @D#yL~R*vh400$I.H@>}kl¶HIJHG"a_Lu̳R '=vAc & -U(Ab*X4PЌ<%,iHpCڗ궳6o[x2!uZzdh\WQm~.6lOfU=T]M!cwwFyW?JY%]|$ aye7GBA@ --DD9L`OD,t<<+)*?0J6y/xV@Q|Y(-ٙ$*Qjz$WD򠥒X}ĐӃ0I'*q LĈ1>5Ć# #LdR|jj$4tV% )S%Ql}=Ҏ>QHlV\BCzUǶV֒my'+l'zCҘj/YZLۣͳ!uEIfizyxvu& +0P`j(Yf $AJ bYEC )ĈrȱeJU -LdH[ %ADN(AIR(2)\dZXY>N[{bt>+{ydV^oTTq_"A 9ʜ -bUN4j($k[]^V2p1R J(AvFׅ F0pR$E4J!0̕#L2$CM4^o-nnkX_~7~yĩpQW`[(EaG eqiƍ0@HtÎ;C=~qr$G H!XXY28 -)$D%f++eeffgjk{+0CKX竫+%AǓLI'G~x<>=E6YdjmyiEPC 5z]M +lmM F:ז֕*ać > !dPAKJHHGEBA)@1bBGr$qaQ?~챇zwaGu(tБ010 0 -jgaDHqFaEb - -+…/ - cL!D`&0a\8!Y  0ddp4DDрC d D480H ! $4t &` 0p -\t Bă &@4<  D ሀ(" D0X $<<<@L&la @pA" ,`B h Ih@"0 4p"0@p&#Aă \Dxx*`8D C8<0`A ".  2!¡!  rCCDDשnӞ5D0@:0v0C h :kSflN<xWO )MwRe)aaHR(=)x;vӄQfIJbVr,IbFIbE4DDȀ|$>M{JOMyU{,Z#^nţRRm[BQ&m,cE93}& 1Me-]ۦ(ƁQ<`A --@Dɢ[^HHCCKJbFee+ђ(4,(JRd\3Hv+꿩V__ҭ~je?%5X (Fk$%r 8CCHhI)lN -Y[4Mbl9T3:E]J̧}w)mZ=n"b+wn9.)6ʰ+u_`-e#Ia(bE%xHA*QRe+HQBTq U虍RQjRF(^VU^*qly@OO"~Hzx_kWzUH-]L݄ec&-l:xKUv;R\ZH`9+J9(УxI)3 -w5)nR*:Uӗh+NEs&.kJEx4m5+E"Իl),n>LUwۘ *Ot~5]*ost.:*/|"u- GuՆǵ)$,kEC|ïک)lQ>$oE;+wlObe,M<HmNg;oUc醧yCh"ʣ7ϖw^V2kNzo3e=pW}ncy޺igiq?OOz0mdzDXMg%c\"z,J·vZs9Ow ]]Mz*mu[OM">d{6oތ>YNVQ]L?vl+jәߪj>l]mi)I͜ksG'K˚iS"+~<[NO.;hi5]wzZc{}t5Q'Vrwj{ʘ.]gE$*u=>zs$R5=-*"]^ĽKL?xth)(fnhm>)VZKhc%˧hi=m>.D^Iyhuae[F?jM}|%] -kS*>;HF{xZSH#Y[G?w:;h(voc4YHG5ݖޏ4Jz !xngNsYxo[F{^v>xu-QY5{:?;k4R3f2uЙ3㮏"5<5{CV2seTtx^rŤ=t[gllth$%;iX;Ju|h],sͥSnjj5ZLٖyΚ)ғfn N<זٷ虵ږPdҏ֑ˣ=^<1֭~\iovg+]nc4Vm"4C洛 s:/e>_&Y>.K.{h2-JEݕs\47gd~"ᱪYKw+=feTv^v*͢n:YeK>2;Ze_ݩdS%.Tq:Q ^],Q!; UC:ۯnxRck]{_/(>$ MyEסaSU}Wxh6ߩk1*{]k\ֽ뉎QU^1KO]-rڪӿx+[yOxU*\UYVYn/.ڂBUu_ϳ[S;/}y#\}o~}*{Yb'+~ǫ:֎yC)IuLo󤫧?"=?U5zڅM:{AdpS=UW;Ow&:Lxcj5^oթJìg}շE+LI4:xϭRBݫ**V彼uJ{7²~3M}1*ۮT{*NTmsUI6׵z<7MýڥZ-ުk'/:W%ZgPxQYUC 8>ઈ?]߈Z-rtSgKe9P1ep(L2%8ĽnY_hg~˦Iy7"p`aSsE%O@F< m-PBSuFLDΑGTsk2ƾgzPV+>s_5DIHd?gFlC=ȭȢs cLSa;*PvB1=1 QhRvAD8+fa'UDl .i:0(P? ȢDdrtw5!ŗ3sDBKj#2:e \O(Upx0Y3‘*yS*)dN Q ݰMIGR,϶Q{߹gz-jpE 4[mf/: - MUޫp1LnhShC*mijQtbZ:DZ@D;$ZbD&*IJD?d`9\c& Bl HLhWRm8ȶ[`oyi LEכ㵒Th2rYC{sJ"QSy1 4 -4TQއYItO1Xv -W1: rB F008tpZ`s!/GӅ'0袂6=ߎQM#RG6OH;>i^ 6'HI;&Ĥh9z!!Ռ1?v'VJ\ÒФz -6% 2c':ip1 { J9zmOJ"VIo-=\zHWIIr ?,qv+iV.RΞk~ry1yb IUIS"פi~l#eJw$.kCk:(ؒkVBmGRWZ)C;[Z/ڹ™?dXZ%{[(\ FX6lcH$A\GbNU/x6c]lz)K ^LBpٶU]iL+\;HRѩ (F&3I S~`͡tidWIO$v"^RGX0K(\>Iy(=9׷Cs& :8oHcbۜ5 H2ن$Dl,Z&j%FgRsr6*qgp#Ȋas2=W]},Fj`@gG}1)ݗ#>BK3(S;*sn>#aTt!eKB -nNf>!`Jgp-{g E=՟^!q~"68֐P$-7H| 0p} Bw߷lNE>\jl--]>Q3ū ͢v'fݾKf\׊_ @QzNh Q)qvJFvx3aٗc{n:|l"RT.rcұ{uI @1pNz}4iT浗xq(κY.VI;=$%榫:\ՔCr%!b - ypPHKMՀSV /ĘRO E^F0 Yr:Z~r s~]pf -wGբ= P\K OC[)x yLP:6rP]P.h=T\VN?n7E?V H7|BQ{:ZGwOwjE`E:ƮSE5AUN"9:GRaIVZ;c=8KkSkh&q=Dk…\DɆ4Y 81e[e#/ΗyX[Dd3 -lIZn -V*K$P8 JJVVQ%"r\@U4v*AQ2S1~4)HEED: S#a­q ->–D)ՒLj6ip"r>QRv۝uC\uI f@~,^4+=> 36IK)NN-{"SD>(zRrlE`}/PYАNu$Ȼ,lW'A*k;pQT½2kliF7t[0~(a⟈lHl - m{@81-d $ϾL*> BN~#jqGIo7pk=v:fd&|< 5Cّ -@ i", TK ya:?mHGY, ܼ͓UJz_+?k{1 $ E-8ZZ}~#p&V.)`HKT0PlpWk<3k]XmMJ-u˾ m=8j)>ܓo5?R\E.T.Ǽ3آV`{%Q6"jcf_RY?8l鮱3!]a^8TF ~(:6؍7WЮg+Hn-"SY}8QvcPds!Jj BV{0uTRPsJם|_6CV}/p*W}6*?~4ecj9hKS 2X > -rcxñqlKS JE-rMLZ%쵥oP QO'&k{Q5kjMnW;yZ%"9Z۳o鈍h Kq+ /ծTh|c-ͤھQZt1U&Ƕ3R.:D[Lzrf`M X /IW8) -ߊ~Kp4-8 UkF6HzkЭZe*LTSLWֿrX{s3myza@:A ֿ߯&!'}=/p|R'\8C+QK_,GE%ī8!B&n7$Hvci8٥U5֮͸1c9B43[ IU{.$-jr.bt}K}d؊/K&V7p4r4K!5] &\j6 ]2- C N t^HT_kғ&/7kNߚ^J^)s!)?kk^܆5M&5q:__2 FK<{?}醆g tC:@vCmTuzSlEe%fUR^gZSc YbS[6vCuwCޝ Ҍ7naf9U-a q3s̡ty!)AkCc6DyJFA@6)sMïBt+Yc428=!ɱVVlGO\CVrڣfg%xQ*lh3j|0BwYƃBY)l'q^̮icC53[mWURdLMg.at9O6|2ɰi~d>1 *aMB7>KLOzXKW<N`I.4,mB!;u@\"LNI$/I2NP1.֢&sF>| -XMdgY -:ZܺdRj0Mٱ!ueZpܳQtC[smRoe.e5Ѽ]Oّ `dȗ74Ǣ8;E%z?A :A.ΎTGU#m%ƅKBK5PkJD]}D4C~tUxzڼM29ur @.gS}X6F2g9ȔZ@J-iz1nNv6Wq{a5 ϙ-wU(s0dzUiCp/Ŗ.>9fNմ݉ElNEt2YewdsK5|}仈\Mk='`K[:|k0:Wі,dX%m,}{SfA_X/"F??ɦ"cbR4vEH0׾gbMo|.s[ALP -(xahqhŃh*fIj%he^(OOؔĬf=? AwPa\V#ɬXM!4Sbh. ]UW9T"ýUxz,Hk 4jh -KX$0k;PfNpceVN54L׹ 3ynEeJT$MBs @]OhJ -%`Kʼ=Yи\1PEAB:4<քJ!">`l |!(}B(Fb`WCBUzs{VɦD!#&S%`f:^|:v|Εd>[40VC݇e#!To#h!;vt|ᩁpK4LJEBG_2 bY) `lTVm+3$M}:%hzVo2 78.<#Hp Q0Si _t>TkWB%aDǽ=nI$;Z_@0 Y+&؁FZHjm Tئtvm>ÅpL! K"̦y~KL>tͨ{36e{ܼQ/Ef K2Xr%v[gϐ4FuutSe/-chdu. -?~8Ik,a v` |徥>2{I?멤Z[2tn&#iKX5CQUR98 3A8\.ؠ(XS~uPet+"Ӂ$\ro9[Pшp#5xrِ3G?rJ)$,r7Ȥ*Yy/7c僧n-F(\uhlP.k #)o`]#3B+۳%2JaE7\Bƣio0D-rL@\FԳ -5K"M RݖHS)gDJ -1IWP~>>2zO4,!i -"7 P}t;j#u~]J}d^?eO^F0:f qC`y[wX,Ȁ< -k hN!m8pb¤%\&`_,dWA/ nc3I.%DyоBIz,uc9!1ۄ|ʬlCFw!Ut4Q# Ad u+hUܲ2n}A'hU£fQ!{}zZ*5AKi 8͝*GwIJ y<١[`pICu9ӿ47sp'*1P)Ox16}1nVO6B6%m|`MGˋ"t`L -TB2p "b! Mmq_ܯ BcRuԮ$ؽ=LBַQN;TLiH4i*#qt̨cQ4dHkZsS\Ol(ꯒ ql -% ԩz%Xmӹv#NpruƁ&>& -DoM2>C#'}\fqO d:imo8 B͘Zlw3i8\?1\CPX׳ 4JBCtNKVuIG3uc 7ތ*gIeȬ]`;:% fl0{PV҇E?@i{Mc[E\#tluur'WwV&}n›€"UFᦛ)9$JaN)v%{"!Aiİh(n;pF!!⏪^ꄶOkr -0ԂS%=ɉYWr @N\xN2ɒ5nOc5?TIw.ޢFF\?T@h+o!̝$MTVGQJ %Ck=jU-|r"/n; ͹DźcœjDšё3iߞJ6 KށFS)q}{H,^J~Ak$7( =_zw h6!k(*-'`ƓAd_\[ںYO_4y '`UB-<,M! uEW 8>ǜɾ.}{#wO|PJ1 x oX%w򁻸 PJֿ1.oͽPܦyʭHMmkZxf~l&2mAIQf)/Su%G%H_mQY͒~Yww܀GaY屷G_kd\K2X ai- p7SSIpY!\@{b9 [3*e1 YGѣK],XQbDRF7}ICu-5l^; G&:*%v)g$:_Di@k᝭,c|&u_eKXΛJ;NyAW\cQ/=Ƿov[ѳQl.ҚEZm6 ]AquVƱW+kk. 3C_a % -AѾfIv Y0*/9Hyξ֕42~b(P&D+kXW1I[/s⑁\?Tb` 7{)S9Q@ʇAjl~FtaBr^V'bEeK@EG{ ՝E#fKܘ*n.nd;UͅYRƅ$yL"Gfu&?ːabQ!Aq̇?cXR!J Cwޑʹ lOIL}I -@=1)Ջcl sNp38zS_j7J=:(QT -D48mf ]R*G" E 4eҔ(mF;sBX(Y":oӨFU_U ͪ#W{ kB{A#@TP5JPzykRJJfch'ثdC(@#3t> n -ҵJ=햏Dg/=w[cKa{RodxɊtCW"dC <.X#UPQn| p\Js.[$K1yQG᝽Mɚ)JjȵĚ؅?^*RAB^:F&7jEqTe̵I\}¹zq9T5{9YR[5)v}E8usSƬT"NRLVm&C1@Ȱ̘V 7- *,vBn kLGfh#rܞ)z*A1/bPlBze쀏ڀ92JuĢg#K{cSa w55Qa?e v?T(%Q`=M3VK(tDYu 8:k j;keT< p]OOUBE[13W/*h^?2TvӾ$Pu6F~6SzkNoA{wFG}_|hϬs;FWo&_1hjP9zulY/O)e h]p1f)EJ|dAyxZ8-~{C\fx+Zܿ} XY8ܱ!,VBbB =uX_%'zJ msGԪ -r-!)7yڶ3K uRqǕ9`G4}k1ډy.Ǡ'yf3L;Sc|$MĪ4t?6bP:=t'B9uHp>o;Wӳ7+ǷM" ;LUE#)o{ڞHWw[H k;s_A<ƌ`]h~TnAG99ɓέf|3JAuo4l%dE,=;)9'/Iϕn7CO| Wp'ba;o bW(0 `>[^52X -XWWhUQJU]ծяGRѢ^ikudᎊ!iv&-sG̽S{@}}041L{V\lUݏ`=@KEcŵ@` TZd[~zoz-y+K$ iNCc7{ɄQF?9jhd{iĸ:dR7 `:JreD: -y,Y[.z4&=zȣPvЀ=&ZwT]-L{5S~`zAlm"sV4*.9갉p|U1-5@'Rpz+ߐԷ fk6T7:6pm/,&~:=ZxnFǃo21h\a0TFkf c|oAt_|'AGpx"qӢ-JJr ȵ3FmKTU -*"=]C8hE -V e0!v0+aZF34=] [hqqE_DQl B6G[p_>ZP>0]aݫ!sOm$-{T(*BYDYĖ1虘,}~K⎁rvJ9[*w N{ʆQ/pxCeI{n=֤\!q.߄sfSWz*t-B;W/d?#]J:$0,M2DP.^PItE`y>؄=&՞RSGD6#;,ed8pET6 t4>Ͷ - o-\@n=cҶ /Q*П6Q[(M}#1 ) H>t)E~܃肺<`aKmAn4' vWcirQZeز"l)M+ - -5P3;WTAD -vƠI}S8800,-tG^5 Xi|]L.H!ja]_(Oh Ea -@yVժ|f9ۨxF\ c-jY)؅&;% ̩Re-PW6^2^? -uFX:D~7DA.Eh|$8 XS&2$XkK}=Bk3c;@j{z('ʽhhͩ1CjnjhZk+9iF2o4F_]3U|flo |#?߄2(w14)5[o}[KEg<1ZƝ֊['n?n0Dri͸R\hjʤaF02Y!Hv l9:"㉑ihUEЩ%{ ;x2d]9oĭ FM*bBug.cu-UiI‡V -:0뇺QK-\iRZ@hK=6JOa$Igx$@gk+5r6夓=7oO|rgNCZtc_etb<쑵)M`dK"r=*g $3tz9  PU5#SiӧUZbc8PM P=9fV9WDm z)Ӫ4JXľ:sLde{ԗ$ܥFє\hƟBv+ܑ3ɞ6x\ÌbQ[ڗkUh G1^R@za1pX43"#By9k_ rw/aA6G>:s4]Z3&0-W(VqN<1$m/NZ2%f{C"\-oI?$EO# OUt!Gk6h3Rp{ϗ[R6aio/5 Ԛiև𪸷M6Dٽ (1ƨTB W* -Q#ܒpޠ3`2 K{闣E{+4{f+mnzS TFF?:l8 _SWN89ňY2BV#SLl_=zZP4UL0zч]@^L kW~݈2J lJf! Ҝ>jӈќ~=o0q2D 엞;- ?Thʤ+['߀b~$㚝oaWqfğ"k,/z5D U =h1t"[}<\]0HY~+ z}6<e#j-%t9jĹ?)cqYVVr @ٕyHz6H_׫sv$s- \C,4;cܣnH?3bX˘NM:It/㓞^p6Ïaڧ8z*}SeRv&q"J7ړEY/9ē 3O}@&'R愧+E-D_ _;VrL]qoɑ/0 TC{eRvWP(J=\+x+0R>&A()CtK _)YhDJR0N'Of钵$^C#&M~.@TdJq!Ā^8q?+!Jr-d] @p_& א`( FB2u 4^-tx?*&[1a1eX6P"f\gf6طxO3xbcܭJ4>yAqytEz{z -@`_2R' Fq`#9-tm}IlIJB -zw9LqC}TT&8)ᯖK>fC{M8>Xf/'vN?Aj*,#A -+}ּ -L/WCPa&%w$.?< hwxp쎃HКsmR\}_5u#䕂WIO6!QgU 86]hddWM/lTq͋y䣅lXt} \<s9S|:]ӥTV|8_˙I J7 ;H#1nvA]؅.h,sh#_'9 Rgښ@-g,2BvðzSHuE֗ꐲ,k(*K":jc1yg i%b[ޝG@jT& {ҽ,imD\Ѹ5&I8;X*fp_qG 70H 0xm٩HDw`(D&_/߭aE_ -,OCIDX׏M5LKx8jyG܀6+y~l935KMGl\EhkبЦ-%0< - rq7ag0[H7Wŷ6 -g*| q_]yi  i\ K霉Lfj_֑x܀OӠ`Q -un6}NB){s4uA~{(&}Ȧ[w׷F[Vd!.7MjȔ %Ȫ"',Y vIyƵEzC\z%#L=w.jp{^`l &}e2xLEWHgϗ@.Top4Fuc|(6X mUXՑ- -/NTŸ4m@OŽO5tԳQn4h1V/ⴾ$FT9$g.M aN_v]>ا~Np]uL ]# ZUYX‘6#}QdvqObC1 -Epwl\[]ҕh2;ŞLvjം8kp]qRiE\/wPk~pIڜZ"<횛zqO9_)BP%׼Zjy1J^ll&ʹ]W\n$R\.ehꢖ.Z.Թq!s}I@B)P3䬫kHWILOE</d'r?SOcA:+תzެ"87 JU1;o>R?:#㳚wOBȕ(YUHODG6[ KYb["$OMN}a?p@}~붯{ЍsSlvmW^TDV%KƩ}33os&LR*H R) <y?'NlxFsgnxzû^8~Xx<wJW}+me%-)k4!4d{]su3߇wBpY~7d?" ? >Gde_sg/UDO,;ypG&8-#gdQIJ-J9tƛZ0dYQǒڭ4 [mQ!`ZY/QgD1#eh(n:˪B`,ͣg2 c(O3}` L>OL3҆К:8y3ۑHDL}_nXHtqu@5CVOO]8jQ6şE%I{c`nBИ0!X:P?Vܰ)|r=J9C0Z`&N -rզ'RAPak/Ay5W4E\)_BN.Ato.rf6~aT^K8;ؔSEƧ &6D19):DbEzyi3jz ;z AT-腚q<1G֕uQLũ 8%ܜ ([|p0[fY4pN -l -^J寇O5fg0)+؍J M3,W<oMn慺P氬ݱB2bϯ:3$ -6*ph;Kڜ( =53'] 7Ngiبu?"XOh,>zs *Pg -͌x 3b!_PPgJѱB@o97?T Mf֣ڍ9/dwVePsfŻd8aL<4!h ӓ -`X A-p~:wN958(FC_s#½d͑㞛¨cߌ -u --ۑI1<)F eq#ʃ% ɀĿa\sy!ŇH 1@FIUtlf YD:6 b~Ji7E;cX>Dmɵvc2Hb#pf#fj(]o~N>1KOGwB"ٜz*XIɱl$ MxU O%qd$ I;Sc%$F jt?aKg+"^`8v>cd(}^͉YWmzaKڸ5 UQs_FZ&Pr1 FL^m񡇑Yd"&ďJ0^2|4h$Z a8`'=z֝` Qk1p}k&+&!NK3N1+#=VLhR'1լh -ʜY7 UKg8v2/ൌ\iMKVY z.Xs0&&3 SgT@?fC\JY7bd}%Zd5 !Rsst<JIXjr*Xk%G1>ÒҾi܍ D=}ﭑO'2fxR~k!wAFkmT ԥ)IRJ$"*O*#_N AH~)887 Du3FB-ī.zs!5gƌ^bDmTyPp+VsPَsaPuU جfW<C˴jAMr<OErpLFeN1Bh#I($Rlf_B&_B5᪔^TTE5[O6\lbH-勯REkf"]|7$cTD"U|=UDdCqb#̫g*,TϞZ5>U{Cb >73 >Cīb܍bSCRa+W`dHOg\:+ S$= \$Ċ$RDENU2M5&] TftJ=4!=Ȋ2&8E|:S!$BUrNHAN$$DE>G2qVCe*.4^wgQh^ʪFLH%PsGЈHeٯQHC -)M*Xb UsQ}*^7TN+wx;U)oD!-CՁ?):_!SqhRp@D!wb&Du0O ̧kՐO4$B֑6 C^a:sGo2T(WbMHNA}/v51;崑ĔԌsPY%d1LC2&mp"IC"Λ -YW -SNH7r"&Bwŋ6ϫEN_Fqq]{IGXU"̴64{8}'R#<Bz/o2ѣ,>OV~{\L1D; jd>a>V8ba/0u[/'H"cj% ox"FŒ4:iU$[ْFMe/,JSQ/{JkU"Vjf!-B6cVm<ڱe@bi@TQ)&V"!vx`SM풶t\ebAI'F899=98x@S1Q.}|׼au˴ZnslJPRߓUF/‚bX]+ҮZz$Ȯ RJh2 -`UcXyH}&)wE1#5M(`AV)T;Ȑu -#Y[ih*`>LG">H~+uS'm6%36q:i`T!;cm*>i`ڇKap;v o.FNw>Qᡧ-J]ƞxz`UY_n -$+L'kP\+*pn?!3C6'z|(Ns򵩱̋\S}jk5c>|3?B}y<ޜQ$vP"ř@Tlb3pY(B6=E ipL%v|yJV,SY<2oLzՐ+AyZRO7"\lTA$CBlBؗJf"¸_ M,"L(hb>s9k_ (0r5nRд)0\1/0u*/-ۋE2ڇ!a1U?"\*kqFrnz;Wy(t 3O排 2?7\L9qLƕZᶹ8U!îS58ͣfy#(n^%\>8Ę -P/ ACaj"C0,DŽaj})/yFJF!3862 -;AUf,Rbm% 0 .08 DAp0p!4cjP8PNي)z-N@ﶻ/Y(*ƅwV-UםmMpݴK:juW3sμ1Qa444 +懨N*HM| idtw y֡܃,MU`ⴊ̧U QFyYiʨWYĒYioZbPkkZ[Omd,l)d1H9x#EʰΪt(܉4%tW_󩏢JR2\`4k S@ #@Kp@JZ#/MŢx%U#p16#tP&L^4<}&Af [,9UVp/pk=x<0+, CreIfxŊ 5i̱YRSmAHH>O%4~ShVT%vKɑs)Z03lbSCa%R56VbQ*ҭO{n-F&ś;27fEjelw^D!,ٔ\汚 P*֏eZ-Jmh@4;YlȾN?܌>#M|1PI䑅bƱQZ|~6WѼ{jn1>ᩨi>)s1|92iYGG cfWn$=24),mTm%V8zG2y\(kTBQCfsF+rY,Jz5 } y=JOg -˧΢$LTޭsֺWVL9(^T9!5}t{CAQtGF,0oܡeI&)HRQ^ *>Q'R|ɡ|xB?.iu8Jœ)[h,hܮP>p idq&JW;_QS&Fd7)G8)}sY QOUWM,V'[5ari.hxGSQ8c+"IV\L DCN++n<>S+]c̋L+C#!nZG;=ê/)J96맗 ~!c:V+"(C5kQ7AZȠַP1dG9d*JW>J.p$hjQ:+* -d3R%qhZs0jq! c,F+C* -(8KeN}\Sr{W 9w|H}8uFv4Dǵx弄:$8;?; ^4VG2 ᰋ}sK_ -E#X[#UC!_*I燈Zq+戩?(‰eviyHYmR!%WʷYժU38:\h ԑj!cDF+^FLmH㐒8aCb5W렗QQCs@o5I2VBdM/c9e9c%ciPƢ̯Ov"J?g*V5Bab?8M'Z^xUm*Ո{F(D!?M%9UrrFB&UKT+"!7kfCR%-cDzy#;OT SV׈TA![-d[IJP7ŵ Y&=Yޮޅ2.ULl뷰[$ƍRjPG"jÔt},jTQi.4&FS2oQ>f+ˬ'*[ƋBf;.&tAZEV 4(5ɎTsJt>=U!Ūhwm7Sg kB2D10^8r w3>$|`ILGS:dx7; -Yҵ䤦Ny`TS0>\2 "QT3f3HTPb\)T(JnQ>D\2U>YEM~ɢ*!'LPc%Ȣ13D!bXk*J\ c>H Ӣ\@[X>U5y9(S$w\4A߃o:Sl rE@6̐UƼG~9Xi"'2m:cs@W[;AF>wX~݁xg45N+mU?*ihhBH5= "!iV}gC$q4kAFJ5}|BɄɣM|ieI$ rk2Q2(XJ.C(!E+Gx5:!%F#(C~rFjCu&~T9 U2DX=*V#6~( -))cx@ӐGW  GCA6 p6 EC;J(1l)rE\Bf[BڈnhZܐ;6Q[ED)=I]ԃנ=y8J3͌FA7%L{h!0NH1wM{F覰n"M3e\sKX&t<ʃ)m -s@C!, A¢F^rOJSO`k"D!r9 o􀫡 ¾od"vКq ;/$jnJTaS${S(qԷ {ER9Z= Uԃa9 {g@h.'=rD-4Ҹ, uVSωW~OX刕.C =ut yYZR2SW&6Uرi\S:Uf5t"3ZlV8dbUB.2, 3ԭ:[2u!Vt\N&/)ΊfF'?WI2 C>*Z%PURa*\uJ=g_+sK-v#+L8 2DLMLܴb> kޥzy5r^QcPdc8CHսRp1Bd3~tB<D.| $\(ESۓ:u82ܙ~IG#̘ERU5u ;jDuKE38eaXESE-UjVUөi LHVoh䮟57 "rP T?પDF֢:.M Qwg"3EZ$J1GfiVHPЅ6(+|7yɄ2-tj2$*-C/%b"o["fHb9VrPiMeҏYDY_Ք*{H1JY}$B"BB~HžRrjLY(,9GUԕyNe\b/m -ocƒf֎?Dvr" )V(*Xq,Fb%I% qxh۟Zhʇ|`*KK$L[,9S/Tdk"Sz8%fѤ&Qbאj%ZOMxj+( eFQ+\RUo #r+SȊf*SM UL9\J΍NSBeK%ar.՘4sWqT)?e}~LAD3U&J9dgC.CQbfy) i>F4qMB uH492ԏpMU.K F<)^#֘Ds0B%v 0->poM1H5/,#: I7nH0^;818i/eq"BMm#wIطUj#wQ|M$tHitBT,2њ)L2tYDˆ -}{DmU"z"؟adRZa'- r8]gu"3UX(iņv-Jq:T݊9iU,"Db;HRIVB -y_ʝq])(M }K+4d ,{"6-KDϠޏJ't!".lFʤ5yuz:pԥTRK|?JzPt0X+4UEMyOSv;LyމOqjbt N'=`9`08>&AʛuՂ䖨%"ё2S9\"%s:(3a%]T1OH<빈GQqEU1PJTTp,(>_ /s=$ZR[rT`.22(GHHE(}=H*#Lڒ_VmQU؇('F4'z\vh/qt@kVAA1=d>#C* zu-U]R V8Fֺ:hF@@@D`L:>0@prZXWzK:3N(06B`@~VfZ+đ.<6rKaݭZTχ -﫢>aJ &+> -H[A7+H|g$ ;䆨W":jjN"fBkeb6M@{ve%3;<.[*Je],4u.) "~LM-blxvcyp$Nq8o 'qj?Vǃ{AǪ;br -? 8M :C mQdZҐlOEEUo_qY;f*&?s55b<ϼgzLR;gu f)fH=_kM_@ -S׸ }1es'B}KAyhb,#_` -٪韚&Y! ,iӸZ<PX LwQjg aRꄬNHhc`N)^ oxFW8kiHy9yEAnIy-:&WxӰd/jeg6g[4 Jtym7Q'Ly u-QO̖e3TgG+u_]WrʮQB2rDK^M+>D+M QſGDIΆ !"S -&xp.?1#", tMXWJ NۜMR+MIA3 vU'Th-5^Mr`OVWfB.g7BRӯB|JrRl!ʅF}cr%hS5XVଷ (EucCN:*[T>BOIWr:W-U8=4#͡+Gz=daLO#[r/c3<59ʄ0?m)㰉ō Nk>XJ6žQ"Hr+(u"M*\\/jj\QC(KPs](-.p 8XhC1{G+c+K -BY*"Y7VJF -R $/BVިLԉ,n7QNHY?rN&$ _{E3(QE[Vf3z'a9Pq$}6lҍ{YemYA6$(J5AJ1 -i 9*$y ހ$WAp@2۽Aըgw*2(SIVhQKZu AXiݦTD!0ՔUF?`]{M苡XCߚ Zg֑R -$+ HF?J9ݸt!zSMZR1NrlkXռ:i.ٯue̊)@@U5Ben!a8j&c 4f)e8YBl`iY Z((F)/:Bӕ5&bb!"Ɔgjv ?e,]>NpT -Po7S>u`GЋY{Ͽ Mn0κ A#I 2fb.@aXM Oۨor#j1xs64Uh,ކSJ0^?AC+Cה50AU/^NK#dͦ:tA{t\b0 }wqfz+(ʣ,1e>(rZ\s5Kf&|+E]@;S%`բD3*WH'Tx84Zf$?Z᳞#=$EǐO۟:D7" -Bcx;UɺU!mT?@6T?k K^lΖY>OĮQ\˯`KID1Y edo%>/@q\$ʣP'vKs4Y2e%sGJA|l)7E0 rh.G`+t$#'{4w_ 0inCNA a*6JИ4Lw]C8t,3¦kBl'M!9JkD(gwukӴUg*;KRz A'xOᒑW.JP"EorE5~ފk)Yg,aMxƠ%3@{ 3$:+G`Hu'~%4L15Q٣NI}Elҍ~4~*VP-EV\K,w>!vc|MH@? &m(9p\KF>p2W -+ Jٵ RXZQ=h.Z]30_LOؾ%S.\sO<<NimhAGƱQ X#LfwĀ`a&NSL \dxi-p'omwd#50oH)fuqWJ)MF0`v.߸͋ ->feZDG4Zy:m9lԟu(z""Ϫ)`mdR|cvƢ˺ XGu~bhXf80ݻhвFy~SzRz̾@4޻qyQ#@^`Z{aU EgHw -_.NN2&m88\œLGv$l;}4  +cfSFt#Ј2 ,JE7lBsҪM 6~WXng$p'<ұTD[֌E[NRvy_//("E/܉&x:j5 K&oI#]̡}8nyj 8ޘ>tߢKJ!]pv8/]a p0 rߵ'mX&?ۂXpxh+?7X&C6ox{ KFf @apM^^|RKӟ8QJ`Û]]ڲZ#V/uw:@ S}D\}Yne?Ik9H8!bî:]DNڲCWH?ym43E[()6_j"Yzv{\ΘrZrvZ+Y)}INfc|9\}ŰACޞPiw{dY'%‹:J[% -U.NG{ø`qMpʎ5FY>l2&{ֻ$0'o6J= Kc}cF@JULuS tNnQ!o<t/6,VLcM -X\Hѻ\P^OTz-B,_/^@!^Ι)6>*k+}4na0ɵ=L <1!gS)Toh2j =^&b)Zg p nn -e PEtt" 018?b%HW$,%9DR #L_ m5Wk5%&W $lRR8dy0{MO-=\I(w r0\!iJ2vhgCf i0Z f8 <.s9G, N5ڹ((8:ǜV]Vzg ϓ wpmŸͲ -6$&x-N/VY45AJbkIhf#l;7e"P=M_+8Nszw,nj+GIaPə -Vϔ%C_^^\Uu(aІkUзLڿ7|.]-| X EzE7M8Ph(6ɓ h3@EBf6 -K2A -Ju:;UA'67Fj xuYci7Y"^<*W5C| qRYkDC`$za^A eX*0Hā\c ؞mB0ge*4F=ӗ֔<oeH=$1Dx0>TR2Zif/b\ogqP &įjY0-}I%`*0Al"7N P>Lkʫjʂu˷\_NDYJEcmka᪖1&WX@?|\H݀bs8;#kT6'$â|z1JtLlf -{1a zt04RS*Լ?#emd\&eqѭ|>`}y9P8M]=McMƄĤ ʈ (ht/$L|hQPuzLHz(}W=7*A2CíNU8`DM"ӎM/OHH_.^ZRI1GQ8 t%O(^:bڌ06 bo95hA%b&X]Oo3x*NCZ!+vR(.)ܸ [r!Zf*qCn A}L7D$`ԢhОHc;s>"W\6X^mH-VpFUN $ۅ!x6vέ:`|T 8Ț<"1 -+4Fr98'77k ӭA95M@Om̔c aO}uT2A©OqKաh*$£ȻnRoV,ߐ_!'.d\%ݍIf~KNQJ|$ρ -vXKz0}-'fjI_/t%Y<ätNT.Oml:*k}0}Ri[/ZpXO -CF/j;梸YGћ*E&vVpŚϟ,)[dvyA%x[>kXqgT>QZ$ \ -$#̜~up -Ao9 >dڊEGD2fn -UBQ/Q -#MU_61wSFcS2pd?|i._sYƒ& ko^S%[_V\rHjɜd|hs8deXL~J:`xVdL\~F<93Mcֲ֣IsqUN`tōƣ~8`:.Aجd]mօl=rpO4SrU[ޤPw^f='*a"Ѹu='.EZ3?eڹfm@hSY+Ad՞֧…W /as.*A$2/#^\+e">ePAh3g+%9FtBߤ_i \ Ұ˖!Ҧ~@sz9\A_`Tڦ.Ȓ'N~*+(N#b +\|2cy$Siaﭝ~($pLeM yCT>|zNO3t9 - ~_Pqd#b=T?F_Xm .ҤJj~NUiM\jXh4^*m$m[!nMBs~L]+l=uڵ1Sft/Wi4$A85+E7H"($`iBy iKhՐ#[;OH-#-M=!鬇"\d{ I.7$Gf75B@5gz_|vf61g,(G)vsI] ! `8Y*1` rI!96"y\'\BH Wd)xf^7`$R̪߶ft\fiGF'!g؊inY r%?( (Rr K*n -'I!W'ӭ>SAPRC}/пNVȅu`V}~c%Y}oe'%T@.sRPn +L43~z!L~Z YX}̀~DZ8eh\۔OT:Ppqu=2<1 Sc.~t҈]?Hm.'+M9M4W"<. -=9}8= 0q6>NHǥ",=: 24L=P ^jIn q`7z - |,ǝ -O6 qM(R+Q==sC26p/R,0"Bb!h?A 0xv)8Wo}mv]RwE:H:B鶳3λN%)NX ksKOp|$<ۖǕf {󘼖` ?cl8|zN"y6Pj66!<. -~37xq #oCӍaᬀ=u&%چ x(q8ȡXmߡ]4r8xƩXڻ" nT&`1m&¸Diz;?RmxڠX8zKk& -=1u[#6pENMt_Z,d5X-p "T-CAfE\04B')Pƴ//ÑvͣcL *3]‘xZV~t(q-f%w<^V0@+C?"R# %-2~<d61r%-ΟYp\cs/yS))kbטQK39 BWXj~3>qa`"m!o̰Ծ!F",RO%1R}A7B62Pu>gTZot\ p[]3쁤.UtQ5&"3RDg -cߢwuwt['nZDfn@t E+ڍ篺_7З+㢌5iy`qPɳ\WϽKgyXnV?P -M?ȭp0T7||a6(3n>TxqV_} ; Ӂۡ ۺpY֩-m" M-)͵oJ^A?%%2HQG:&d$#k[p}HP7M(Ea_h4'Ӄ7ެٲ$2[Ej qhȂ.KTpk* -Fۍh>p6PlЁm2Z$KOOldDp` (PZtפ"Βv$9~x|"(9ӥ&`l]?b!Pvmv1~XI "lzM:Nd.ŧBeDCÑQ=o{kj0Ic(//TXK萜 BA -)HxjLlN/˘gO֏)~0F}CIhTqkTAh}Ǣ􎔟ƨ k36Fњ.P#0UTԣ-Z3t'e4NSbDެl2NHGkksֆ{֐h?.Ə3%o~ӣ**RƬv5ڼS T1k`Za٨@ku&3=Gζ=[x. buQsH-KX9 $| gEl" ֆ -tBqsXE7i5.Cɇh `o-C-zWN_\M(z܂HwZNim#S gW6ڙTW[-T+x'晒]')ReG䟞CQ -ÐONL.ac7,)͌K/?L$*J#>Y[(ϓ,/ɇ''TI~.I%2_G%[Lg|_"o8*Pb0 qL**Kƿ ծC ㋘N:۲[d6<6M|vZky{&Gˉo8'>j3)'>B! ?`7g B{c~;7B.&! s͹~&*f⏡,Iwg.!k%1GyA" 79h-S *;iva^Cjud+MfA1^2!/̸|dj}XEg CL{g0..E3FM2hKǽ")P˴Kr/)|94!y)X# I6=4ˈIK.3{FS6PX`Vrڞi#n!# {yOhd/P\ZS~ -L5N0‹ߏ/v[1:< vjQXMLDM.ޭ;B`^lLxZJz%SG~}>Ĉ̗~(VjH3ΨѾA'P5+ -c}CNY2 -Yǡ Be]1[6DGUjTՑI^A}`hcFK,1@{-L9| !y+52z <ջ^ --H/2꥖##k#ꮸDr ^}QG"+ qGcVa!x[|(SXyfа2"`m;FK ",~HVa 3ُqo:Dnz/˾]|fLi+\8@6tl'4(C|)cӐL1y@1YQTZTNfC QynMDX}&Z5+.ȈHTwfpl hS۶r~ š7/h7" #Z0ԩ*Sǭc8WKC {yh -䫅*&hi?ɉ[xeS;ƷKtIQP>.yS64ƣ)KƭбO΂U8 QnheJR1MO #r9y8`NJL -!EaMX,NCr߁~ ɗ*xH-rJ#wk~E]Ah7f'qޣ&-4kDT[<xYssُeTuC\21:w5SdHT,J>My?SRD0TȚ; tB J9."^G/ñGis@0:ig2#}\tgᕥ{ -t%'w8G4Oꆬ6}\Eɹm\ss2T]"S8(LqR@0Wxk'p=Ww@7ߒȋ~*_w:T{]#սl!aT=Y+/Ou~mSD^ocǚe~Cjp6|*%8U%Re^%=G!Մ_@C:HӉxWZI8$2_fB LG|ʨM2QLT{hbCn[w&ia-jwwWʨs.OU#$ I:P O̟$r{,'\Ωk1l*Ct<RQo-a\-RY!Q -v'~(%KVz /"']r3 -1aыx!J?, -.ǹҔV|rŶ+ 93dh):5|V4B.XAt, ]bq]t70S%$p|Mw<|/Ouy~/Ҷ9f7p:CaG@Pїev4!k+NC-ڦG -Vd7GHmnf<2~0{}jixc73c`R(0X{r04!WS 7+,`ZzaT u7wq5lY .pRMTrWso B\>A @t"~@ ZC`Vwx $%cgg -9D:97#piWk*|+ijDěfgJR -oˮP=:9Zथr~+ťH4Ta@v2@ţݐ~ -:>e:|-NX-^n)d h KF cGL14%HϛhPS"9Co .ÏJNO3ߣ+)4m Ҝ)j5Kw |^E]l;'bΌB8My!JM WY<Là2N],; *buga&h-Z(=bENV%Ӊl'~G;$M|3C L Sv+ .ΗmHT@Ņk>)O$QOՈi.!A7rAO[OMyL.J6ȹB<~-maӽFZFH -iS=C3[wK:ݪ<wAjOa84㏍}*6$]p%0.[R*xĹ:-8`ڈܴ.0S$宆XfHAF#&}P?؆;y J9c>R1C;WFw(Ma_ PRB8nMtMo-Y1u+@)g)[#aOĠŠ jzq ^~ -~ڤ񛷤 (:;(Y9).̥"tr5{gdc:f>׹BAql8u0k]i0lhٿ!$8|#{|\y[&^u 7&2>laݴRL/:ץwoܨnQ [qDʫ25&F`02'أs9}J4[Pw}2`Ϻz)lC 8@PspqP9U+^ -Nұ9VHc7FNF~:ݻ)L+#'xaZ0fcs>6}(;֙k$ilPNJ$o|Oo3CuYT$9%*}<2@MH<1((=a9{8F-$2ʼŒOKb@R`q6#%l1I/T|1i"14Ԙ@tG\bU-NÉ+d>HWȱ/t_YMJkXao[ͥZjU@[KK΁MjtrFw\jƥ"tGH=cϱEZƱhpG?p5~19pb"Mt0U.,6SNˮ0$a299T`q3 \p*_5ڤ| -A(bPggl3HU -I -*-Jt't(+1à(OgSLW0F`St=NM) k$AUw:]O坶4i=6zk}Z B鲁*'y/(|XyDZ\Z20]|/aZ½q GfyLxdL Qzm2Bѐ@Cf4FlR#VtlX,KPj[an'QvW ->bÄϽ0 4$g{ 9^R_y TCi&%}@N`3h٬h<@"ek ,!CXsT̠kv"U!dROTnKex%;kM}o*ku40H]=?Z{*s~kTrH =?Flz4$=/ `/ ?'T0,Fۣ6_GkH -QAd IJDO[$,Ґk,ﻣpoY߇;.ƐgaҒqI@ 箾Tk9܌>>T>1~qPU?)Aw#U15-`]:ⵕ~0RbWob7~N.; heߢ+\/퀯z -#c_t0` T\Bf mL}LQvsHFD†eYX`w@r&md|D-`b <;ª;w,Zw&u]w*$\Gź*Xw2.ZKQ]wmJ8#};Y|K~' !Jd̚w o^@h -z*),>BhgO 1 -͞SXĜD)L!1p)ηx漚#:SNjLEK!J0[U8rpVt\|q#1b04ӰxaL=p7rjXXnES_>N$@sA(!P -HJdklVI3  %q?.}bG3!hRCE7ȯ/DS˶|/ -rQ(ㇹGHh(-#'7pU.+=hK&bx済"2@!N{Et :jbԚ_x|p<3Vߗ yZ9v~G)앭(л 0g 0!d^pY 2nİ™ބ)wrb݄26읰DTn;eeZ46Z]>8"pSb2uiWy na2V2lO[?FA$uiOW1\˶jZq0Wb,K+Q@"pA`CVrFvўABޖflXC9y1)xk_ouH (C d YU*VJ(~n8nb(n\D;`N KPPG],vK5DhVx5OLa]'&)^e$p.Zsx8 +Ik<.C -ԉ0;uC^ԩ^5;+pH)}7*6"8NW 8a(P>l+XD*'(}Pkr'7cܛ("Pms @D}Gܽ潛 vp~:m#~[|M30 2qǺĬ' '/Ga2:dFYcw;:_[سa+!r}~ɷKBk}'KR--M36Ʃ4ٰri'}ZQ54 -jte>ږg1e%ːE@ggo(N3@gcnq+`kߧJF#yi 9Ó1DDN ܲP\)&::@b]֫]q+GW1M/3ة - lYf -8ڀL<ҿ`@ JD̸ R|IbǑE>'X7הO ˭CZp+w{ {?Oׯ%`YH%OvL`%S< x7gT6X[+vWP)!X4 -q9\` ȣ@,GQuv[+O[3fAāQk`1m?=7Av01P:9w -*mnԎtI-CwAQ~-?o[;tsÆl۷. #6<DM#>Y%%7#^D\e>يU +2Q61@hwi -椨:d+rʋ>2KI4|iר %j5Z\킽6!RB5cxVk\I*鸙&4 7(eq -\sv! R'3%dW]nah&G`pݹj)3/zYEǧ E?aC* $bޠ&]RrhvA9tmОBzX$D|s3J`^ _ht_F':|Php/W0] T֏4[KO@nã>61;k.(b+EK.i"`` N!@4OnQ_$ ZWqY;&, *SNO =\ze]lU7.As&Yun DsQ6 X<̂yI'KfVgﷳ ,G!nM(nΔP7GKh;F,eAPZy4$z(BrΟ@H}(" B9!$9hB܏ #$Gpڰ~N{HHn$?k Iu#wXI3Trߋ6$ܙD)uiY7$jc# IH8$kpHjgD \Wd7$^ځHxe.%+ Dҏ.H5p\DbwZ#BN$_pٰ7z|GLxY҉tmEȣHp3  -щБNO$MxX/H+˷+IkP>pv(VEN -o]&#ۨ4tB8 itϠ@i9LRDud":bG̯DDȠ!c b1՟e\0woI?E~v&YHVy~3MQPv`homIir?&'RW~u@>9ڏg_ŸiP -PyğȓܔC!`:C%\ fȔşw[m' ?:<ݝhfBChxHo?c9esU2ʟ\֦JY_(R> \ HO䯍Á ̟۝10RՖEbq*ߪĺ1?uޜA^ ]UZGt)'0#ii2V1*]0/Q Tvµ>BJKTmJd4SJ tLe4}&diq^}& -la E~@wgA0z)I?o}A&- 8|!a>*y  -VU}MQvhsUI~b0)kg~v^'[,j\&rK+lR5W٧9w>3a,OVb4\}{||}WkH }|ċ30L;4"}n2{qEF~g؛ϭ1߭jM)9M D|N4Q%$rxKE BbHhyM>aK5%1R߀v`|2L -{SFo|Ba=A={ i*k|pH[Xۨ9U`BVǤrFm,T!>h\%-s  0@AA@v"UI+{Bڝ^E`:_~YC<ܞۦ2XIe X%Zc'QSz@rTM7I#i_7c$ek4 ѠKqd$&&OdTO$_j%`}މ_u͉d*Z2[}%Fq -sVޟA%6/Y12/҈I62jrd5 P@d`Ą%H"?e͙=B:,t! I9 d*^<9"Gƥ$t'$N(˭m/V#7\qmE۟IkFqwS: -lK u\'7Iz'A p>?Qd+4 hWmdu_d#Lڐ*E˞"@S vЙ_Kq331$ӃI?"?yО'B^̜˽F{1rއP ݙ(f75طQh=g7(sj -y^qԁݨq endstream endobj 19 0 obj <>stream -3]^kVеWFѶDMBWbS_gH؅cz/1~ٱG(d@7/{ "z{}{_ d9o}x\|C}Ntm_7=)R Ja־xU\u 1DԚ`BWoAxic!+xIuJ'*^),\5AUO&A=l_Šh/CLaN!(@ @LHs - u>ƫz* L(`6Q j"c`&,UQ%+!GP.YƼaP#S+;B^rq Pe̦a0ӢC?X|߸BaQd1$A364>*`ŧ& qX 6Y "ъ! }hʣ Qg9I@LjȪhDd-BE!*CM!W",!0J{z^UA^ԃZ3)|*IWB~:ЂӐo"𗉊bEnUc&XS}%lXDUk(Du$( HPETVCE5!4b40-1A)R` -H:= - {PH}f4"XS>)aL͸B.L5'_dɔ_iCX -Ih!vC8CQL+*Be!" uCuE3PjȜB: k׊c[TXQ&:g:UDLyɪ̨%VCIZ)ߍ屨N,Q$W[JAUyO' -reBD$.TLY~<~z[aO?zLũRtjjʧʟW4?QYGym|φoxI#y}LhTu5^U:~}Tu$/]jv_kZ9=9mɥrSר+S1yczfًxB#믌2Q+]Y#WdsDM ֕{tvWXft,b1F4pnEbR4_{}(zVS7ړ8jg_K+iU2}nm-SL)>ӗ3kNwhϥS ׯEݚF;)4-j.N2X9ݟr&9_$B3kF94?Jycȕqmk= =Zs񜜞BM}x3r2Pf 9Ӈd3O3J8>ȕ?ԗIV7үԋY$HTCsyFk6G꒞zF%T3ZH9T.3OhWQN>>~W3%kD<%W5ze REU?fPXNU)Jbů+8ުt*3^5%mOx^;8K9c-TREP\Ũ"u╒ QщmI+땒O)xQjjg!U-3%&l*h7rpd{Hv[QngCSˢN^v#%Sֱ_#ٸ(_QҏVSJ*ىIDܚaeo;W8ⲗNWh}Ik!qm ̓B<9Ɔ< mfeȑuT'[,N< H$I|H?r7!?3*ۣ"jT(K0Vڬ,AF,EF>EQr6˳Gg_<2i$_ak8-o~J s:HoW2iB&W$<Q$>T!= ID$5Mԏَ%dj]CI?ǿHtz Rxr]Kr|rӈ؜)N=Ʊ98`;vQs,J?B΂qI+M]aEĴp6ieiܗia5щJ<"GGdE/"H!/Jy1V&4PdU(25-3,-9D^breTR.4͝C3pK׌1G|cRRPG:-E9_ Y| Ĭb."<#:,QJMHHc I\)SKAY!Q%A4:XUyy"jmRF"ECu&0Tp 2FsD8d.9ajl}gw.y/3"DX"1#v8| ̢| R8X6YTBM&ԷEy/!'["ƏÓYkG/cPI8*ZM|"&"F^ЪĎTm,.3;I)UN7/X 9qcG e΍D|f]IV,.%!5IޚԌB5Z!jV'eH3$jN֚[8JiC(yF-g+$jF#1=f?_5ڪrŒD{~) gAf`0LP'(x̄N%f"Zp[cSGۊF״&"jaqTDud/wm,!>kB;օ JM|*{|1X^D^k…a#ҧOb%nTSƨVBQ)Vlni$¥ѥ+=j.sXkU>LLvORFf&D{3]qюQ.F4dK,;'CB8$ 5AC3F@CCD+ -4TS:tLEH|6a; փ+OxG+]ǨLbV*͙A\l`h J"PEr[I>+A*z&#" eV% 0 Caa0 Eap ¡<@@@ d D 30@#C9 %y,2F ƛLJjR!ũ"V4C:_<qfq/~YJ+$(F L!+E2 -HR\R͋=u#޵~ՄJ&h"C5o=qKV"?d}J[!Q~oGujZ}=_. ɑ&r5žW,P* AY3I\ "lgaEԊVtR~A~ŸQQӾRYT*F)҉7>(i,Qt&>)Ƀ '.q*JƖֺ#HsFZZI#iޞѤL[-9Gqŗ8j3LRAȮjuiqMX2D?Z7G+r #ɴ\tvuy&ӆ=gWӔ+m$tOJ)e9w2a)XĈuJk-!+[q&zcq?4Amc#YPΨp('*53D˥r bThƭ&+M{(c"N%rfYCR4=.7hʗ2ĉ1iGIz,FQyQ6ө5,R"~ ^n1V}׭4߬/gkkaܸݸiUJ /9)5U9KZ8MtHj%(FL'˥8>Zv:DD Khik_)E'f;GdU.zE_F0p$gk&F{x6PPc*@' m4u?#-j_Һ?Cɐֺ " 'DOޙ OjL:՜ 61S쩛< -BD>S?DtɈB:!&C<է!Gl[9Us\1 ڌNT5ЪjUGuhX{,yV16Qo"ۧ*SIYF6geWդYzfCM=Lb($C"XKs^xsbLZ>$;f3 QT"4$0tBWU}ĭHR/7PrTUpW ML@V',ppY˅&4PIIԨ$)œX: !!h} t(`(#QBU AO@6{dOa5a{[v2amOmG8d ⫰?fs]I?"X}ax7y]Po}?[K'Uh)(}>&b~D\ ˰([e0H 9H\|)CҪ9x.#g)72S%7JǷ a]qVr`T{´<:oA.;U1|Ô@ԃ_S[yB?Y?Jq_wtemIlk/@E&5w!!$h}xNT;F"N/DNq) __LCh49I ؿۆ6OlyȲxQfV!U_GId6;ḲQRCK>a6jY:fzM'[%JDhGDREᠴV;qo\t6I;ˀa I/Ϗ XޢfGeS|T -mf](ˏ%5+f;5qbC\w ]8"%p '/8P<4zJԣ*6eG7z蹩H)I60"fHs.ԙW:?弦:EԷ" uDL荿<ɡA>g#<C\X^Efq(إeo;0dž$ӝ`hO|27*,aL#"# xvag)݁̎Y`LJVY!~eA@2~v-#GF'G:d%{?;u"|'5Ǿ'$ ~nv+M/'r>g$;)(B%]= Pn4z"k8  - @xPlFW7um5Τw*RUls0bX~; <qϋ5qN~gqOϧJ2#-/o!BQ@&[XS؈_k8iH4pŲ6{c"GqBq ?OdzgHnP4 -0R֨wBq ?:*j! =\Ï}i՗-tFR!E=Jl @Zr\Զy_m|fяJNxF[߳)Iam9cS]q'`p_f7/y6#.jF7BYEة>ly&r-jUh4oUyf&F -Jw/4=.>m[)ȯ - o׀gBRug2Gm}ԉbD>2(Ѫ#xNط' G?!)~QWtqu_\[>4g\@O@4}xFAxa/ޱ(f8 8I$HۧieUq!#[ԲY`oX0oQ4ŽLӾӐikx;76$KLՏU|gf饾U[)㨏 -PlUFän9#B#F=Cq[r} =]#~r &} NF.$/ y -,Ng=T]ӗ*K)msO3>CHLCC,#)ʁ>%Ž >- kpTӕ~@ {~غ)@8$'o޲(u0a_Ct] "X"SMsy@C6_i9AЍ;w:KE zx| dSF)c2_tj%wLľ ξ~U¶YhnOxUz|8QFF\l+? X5|\ ŵGdL; 5 - }(ٔKQ74r&zZRa 5t$# QD7HX|I&[< -̤V3UG SӐ;UOrCǯ}\R]ohO,M-@,]B|̴՚=Y8\:fDtPyv37.kQxlS{]apq,O||U'}M=&:m)T4^bۨ4yI#5։]_Aw HO,>'~Pqr8'C6̍15 -[}dpI!x"qz w_jKzKʛEV~؆)?~sIEMbÍVY40ۮYxK/)AS˕CV 3I'>e -[EAD=))Db)s_: 5 hς+$]h q0h'q?bKB?m2a/`8!'늆O4; %~|Dfh4ó!D$<#t͎vCxQ-_eLV)~SYNCeL0l/opVQF,efGX4 AD T i9A&tX򰙑"*^UǾ_lB_ߛQeoE7BMnHBc{us*ly -ԞjK3[^rL_0矛O{WB $a}Zp -1L 4rGmZ^}.Xf*hyF14\?5=XrDCydG52 FQʮ=.۲|@~PžoٽV|x74P/c kLQԡ -( 57{ Nl,iEe02=zygNJh{W>q؈,( W^v~RH&ۇxw -ǖCv|eAFoCBZi˔H'm>aX!d˒ZsO&Mv[ >99$keX$LE8J6GX$6PN7ߛT󽈠DRv2¦8=PT|/xeڼ*;ߗ?\khw.pt&޷Zϔhi&3$aMHWhjjRf/]n1/yPH'?z/WR-JjmE4Noy?ZF5yެ?#hX)Gnq1-,YkNJ/^L -,בS%R>s,-z0"z,ҩ ?kG'LϹM/(R2"n}d+C$AXJcץ ͤ4c8U1Rc2iQ*X :6xOr*B= p\4=YGnW@qRE> zϕb̿df\w:%jW=:´QzIZƴdVݮEzOtUu;{at9y2JH3u+UglD-*7ڜݩr|~J|o4!Y:Q g$zoVnSj,7 >N=<-bHltԈqD;6PVdk~K}JPEUF6̈P_v`b ps2w Z~T9nQ~66ꦕsö%'KB^;RzI^|rу퀕~Vp{XиF,8Kjՠw[ P.|O y>FLns@Z&.&n=h\~<:ft%9Z~cW5shX$p,fDwV %10Qdtoj"  {a -7>ǥ_s o=4u#ٮ |oI~Hd~PF:LV.fˠY}x -~뉘4@B[4?~KbRӅTt">w}]}\&GHژ1׃dKʸnMw3UUܚx߁47x cݍG%y3s0hc_%:dHr(E _Wkz(t^n${8kJdb)CpI) %W rs\Hw xBn=c)IهZP;k6oHL.&(abAĩuso^%I!{t (F$Zfp#B3f)Ƚ"h2 7o1Eߣ+㾮N ~(èSr v{wU۩v#`˶sF0l_/Ƶ?AͷMdkHtIn[w!pYR{m!=M+ h%+u^#DzW)3^Pa $2Wg^).+lh"_ -45{#TU5 C2os=qaÂHC7g# ts=Fqc{c dQ!UXqMĹ>Qa]Jد6x58쉸t—߭T^^_k|=|r2cr 5Ԍe[x &'*cBXgr'mw:AH!-׃(^~9ַV]qrdiYYT^W*? -L"o`-/ߵe=jU\Ud끥}u&J5(d yUYގiVݻ !X x[CT_2r=ůYlRKe4+_'5RO}lҰ|E9vFBY, aH=(J"Il`〉3tcī+G2@\l["]S7_y -Gpu#KۭK͙^el{Vglëplk]?N7{Ϋ̃+.aK]R,5^̎Vc;Cz -ll5Ew*=N،~liPj?GReL()*z ޥK_@#N^ =>E~ yNvM=fbCFuz#uP@@?@DAᥒ1¦HBy`vs>dJȸ=߲peL]Ji@C<0k=wSY&g{賝;`yuVYA1=[Jiפl!y,uj[Czb.VtUIp%M^ƙJ`c L(N@HyQnKyDz(;/Apw]Tx9IHnLEU׳p#~DrŻj1wACykZ/'ht(zAe~BAb ~̯f+ZF);"j (^1J]$>)@J 9y$$/?k5^F4{ g|J)]_-Ϯq^cgX@54}Ћؽ*5m#Y,dϨ{Uhʣ3UtH;f #oW>?gb(v{C\C27yM:/mlW& D?+n>K^$nBM[MhU'XB -,2U bJ-jlZ{wah"/>3wȃ3nж%~1g{ACx~F -x`UB*b%bd R44(=ޕxhN.G&F!FTxȕgh$T"Ə;`K <FcC7 -р^ /mfvKq `<̆=6;p}C)OXMkI8yÇDW񑌘2ɀZ? Cm̸ 6Icn/<)?A>"UL)yh? -$wx -x -ѕ !pM5 dme|M?~6PpA*C $g!$&WE8c ^_ -J6y4i/+(6[4)uJSE/PAANܒnv'ّK.S sbEM2 OKt&ܦF m<ᓗ0xT#Ȅ -%L3Aܲ67WʢY0r9}ϓz΍5A0Bֱ&`^G(S6asR|6ܤ 6R|((/xo ﴣ\v:tz1T!:;^N-AYdƉѦBA Nq'p?_Ħݗ.xV[ 炟,_@F2 g%.xΎ_J':{j;Yؖϝb#V -m\R<|_D_H6Aa? 3vo&V  _5Oz  w_=/< eY ]@0)+.3>`Y~_}1hKi鈴.ʅK4FκDJ₯)!r ](àV 7eC8=H`2|/p02]k >m?)H )h m :/\MFUv˩8ƴ-xozȶLd6f'G: ]C^N}VO2طű9 ļ7kih8Q9j45fb#"59_9"p`~kYJ++\_nWsӗs?CJa̐-ι<qy6hL] -rC':bGtml&Qo,ӥ7hlTx%TQ8@?'h `K&ꬄ||EԎwU04 4M^{޲ұG#iu>:9T|H_hɤ\a ~d힅 -dζӾHRQ@ʘHh;kֳ8ёtwnw+rr ]_3A/M"D-al1Yѓ]Czcx=E+b=ArzVw)?R m#[cvO" e}$Dt=IpҾGIGXM%*SҌ! zʫKjr%W>wv0|@H>f0neR9X9'9FyDn+cAM %^r3],.I]{._:Yȿ>>$ ;r"Je~pBĘ"07 Da^ M7bٽ$17,0rKX͚L-8LXsvh)i3~)Z*I'/ua-4)7Bq3]H\kG%9B{ݧOU䅈qLYRnR]C1f{RıΒ3B4aSӄCcS9 `W0iJ$ĕ @@κWVH>VI $ ~:GN&< sFt~MujUФ G4Uǹ{I4sä3}&UfCt()q:AL&2^%@r7>p;C}nsC>wJXgRGrLU(ߞ$QJ֔L@|ha[&ΫŁ%봏$ȫ]#}]i̺;~I >IBb4>q^ϙ.$1ߨR0ww7S+S ~ -Ss SxtǵwYJσk92s-|0?GwD:ck -H‚ee 9Iтn|Q%t$ei#rTBԔ}l肐v?f@Ƹ`?؉caA?%j/5~k9U ؤG]gϿ/Hjsq@gBTVufn6AW^w}` "l݇\HMzS耚j.-~>Yl]?Os?v&]NvCM9ў'lBMZ#R#REFNawjr sӺ}. -6dpk)]:_5O#|%Nj 93s\DZ'>. v$SDDN$G36 u83&ӭƏAgj×JTÙY|I60ml v#̈́6sRp5C܌6LR#?ǾG(N=33`ԗ9;~l6zGA7'DKyiU7ݑarK1.!ݐNTYB~xRiiv )$`P&IhҒYjZ$0aGRR4?V,XnNz$OrD٠~.~O#/OKA=?Ւ?/qY8yV%5d2IM~"NbUJ$ YVQPQxYԨ#?.CSPRXY 쭠H*((G*#q?Z' k=GPJX"?I?'G̋ Rb͹'&#=+ YG>*~%ܓgOeVxe4y!arNI R5_&y!Aܓ&$:Ӕ,O8l@=vI1IGn<>ԁc^zzOCP[BV 2Bjs'?Ɲ4c9=\d{-d@#9$g+44 ?3CT̏.jbf< 5YC$+j ^*G@In:$bۧ@ w<#F'yt6@iˈcCC,qbCjXVGyAi0 "?];,x ?ru' tz/䇟s^WO_fpNRŒ uځD -<9wƣMY!u'japDC, Ni -a~P$M#E}wRU5!໓(/,4@ItbykI}-QSI)gu_1** uR8";m夔:N$YIRnNRߧ*Nv˝.X"\\VZВ׿ᇲ㶽`^դLf4PU;89[Wj;7$uۧN?ӫNB#NHIkG<\os470yҜlijǐF# 'A+EpNLR\γ_{[(kѩ-Q:IPLg +a: ~E/RmCSXZla{GNG7C1~)}K˿`k1NOa.o5ghBqU -Y|(=PGIxc|qt4 g%dvO4ZHTCדp?gzjMӖ91/9&n71BUϓ[rГT<" #㓪 g(?g!FO"jZ)zy(zU&Azd㱧?DCc{u~ ӏh%Yq~ ])K[ -˟1M+\GTY'8z!ϮuM$yR[yDE0d^ J|kVװǘB+y@cp lY HF>7pHQ,* DcR_,$Koò -'`Kd'Jlэv%ɕ>P? 'aqA͍6xG-T:SRn>bDAK\ -p=^#?~xoĂ -L«W6šRkT]bLPG/V5U%yÈd0hX;DHuʠmjl2tl"J=~wdM*< ڤS[Mș P_ Uqwd菷yǁy(KuL! EE}]BѦaa8NpgDHd/H_-кja3u&D8x#} F{MСtM$x⚛đfZMA1 '14ML5!S4tT:ȥkp:Y +$QҖsGS֣ YTȉKN*a~P#xnfcIiJ]Q~$H= ?"n H>]j%M%L1mSvcu?zΨ&lyiѵX.#'1wTJ҅! ՊC k~03'#E攍zB;ąEQD4$zCdvxG34:tOꛘM-D%Hu|!y"`T f5Hܲh !I&1i?4{MiMJij6'oO H&*5V@*{Mp!tNBwl9E77;~69yPY*^stN~%Pr! $+giP ?H/k&4")3, !5N@i.B=I${&H-Ph'W<~$0)d+8HV~YӒL-,,ߡJڥtҒ|y. RGj:fBFF<[:HN9Ӫ? f JDħNw4@-Ԃ:aE4d1NlDܫ(? MȪ OSMLH3 պtb%c(Xn?y/nHM+ҐPZR -@لRʭlWjB,?Al,$$@qO$$2m%%V>T{em X#Jҩtl`.!v%X{ՊAp4QS(ۻAR]IZ& asJI)& )M2*n a 4 Jfⱅ7*7!dHyܿtgIogXtꁁ0 i3dF'I_izR x "ZXM2Fl>႔PP2ь>}!*bE)gy?ѕUP v~+)輕$X5++1 CN[b>F&4XbmG'UꌥҀB(ƒFuK%3 P>#%b -+/lmOd/@y4-z -𓶗L\K*5I@ғV1(Z95eŒ,%9yo`0GXFQzgic`pjg:DR KLXi_6zI],rhM9q$`uZd$,S%,9!+_0UU|l`c77˦Q+0@)jqHKHBhڒ;2hݍU"-ᰴtT -(߭EF 2Fٞ]y$xKf%cO@)f7{۫҅+骷*8bW~RHCO#9-tͪ ,Ҳ㴣bID+SSQmE0Ԛk61 Lm?VRP/q,y9=Lq$@̕EWkLTw|Y|>1i/\>?' (.:(˜m%Q=O`l*I&"PGMV%wCBcŒ[΀ZӃ$=> %«հi܂h-5C>M`)xj#9qrx uֆ0c71_S փuuOoQCm򔫰I2X1e8n0\eo(d sȳpD:@QL18P,Cɴ4|OҐFIcr*HR 8AY*2;"aE I^D6 - -5>dn =!r0 X elƪ29 GԱ6`̆6je'{why@ DGx>2m)AǍw&Ai LsD8 f,D@d|Hh3(ZTό{C9T2]=/[fh47v$sNK5iEVR:Ysf};YpeS"N6ZF~&LzS$wSH̍bJ%w9LtFo)}USb*k_u]6*୑b<&Ж]0"̾]pHcdGO2|:'D;IH[O|NDoCtvZO-:RʋOj4U;Sz9Rv |ԛ'mI1yFP)+"i 饛n'0}P= oÆ!C&BRRWcuܓ!B31 >BG*wJf\<1|ܞg0`몕* -_ݨ>yay,Sn@O謎tXHdMKMOP)eBO-ϔQDMPxAhN Khy0#+8{$?UGRoI"-F2cPa(+Ót=`dğͳoQSgA(833s73M)MSBjT&4qvDM2>4:`J=* SLrqrbaG &6Gu4!%v=q?@У2P\C֣j/ɣkQ{B(Bi03/ =w?=<,=E'zTeJR3`,0=*:90$qzTriRè, l Qq0zji{TiЩJu%oz$l6M - =*G -3p{Tօ0D^_yirah@¸c.XgoBE1'T7A4ҭ4k7{T-{MB?t~*DJcB'x䚎ޅg<ÕlXQ'OwT!c@;,DU)Q&}vT(QUB6LG๰2.Y:*vM?G: 0Ї"+&+{lG55SC#rTKEPE'ՐE9Y,bd/Gvf{lEk8*~8*4nGXCG N Цj|+GExQ!;b#×o w¨|RQQQ$- D0xTv;nFUMI=j0n{y%Qym -S9Ld"o0|yEmIWKTE#@I^T 1հ DžE坓G03 F~r&%E.VN17*Ǩ<}h0ΨFQe87(6'~ƧΨ$Sefh6E@4*v67OJ'_]L~/tIǰvN2qW/őڋ42 @p2U}~[Z"܏%ǕQqJSf5dW%MՎQ}շ? nA*) y6U_&dJ+\$EPJ4*9R84*1_FSq[QQ/$h M Q"ԨPas;:-eFx_kp؁ꇫf6&f7 H} =.yKZ`p6i;jT;kQ@(u),!96fM<x\)A?㨬&P-Q^ t[8bB\qTfuu썍_Kg^Vzj+-mrt*ZlW(jOGe|K螏ڇ~=PC*!$R&Xp-~ ReY"`Y"R=V@vx|5#{^ jf2:D҃]RTةLq'Rcv?oJ -d?%@aHux#I'm9M=HmHFJSyQ͌ "~9KQ7RJtHD.uh$0#չT$j6Ttn~B 8q!/aڕ -#UO%~KH5 oHuNA.pk#UFbLjs{I5\d8\B[8O*:NQRp~pw)dUַ)7̢#KO*5=aі`Z6iB'@nєO'U [欤O*a~'ղXs,SF IuՐ:vʚɾn?nT>IFԆg薚ɓJPS}RAeI5>BmIV`HۓطƁ](nR%/NھCj,JśX1Pz5uT+yToYNQRe7iJWɔAq:>{TS -SRP*:@8<(1 $|Et'9Qv!Vx(vi'cE=RՋ̂km#&T@Ze̒RCEM>i~MaB SGJYGUh9s{M]JB3))5y^J1R12c7?ڟ>IF[!)۳17JNa'Fz?HXETELWn/; -cWQT5>)U­yW@zQ*]쏀't IE!"$O*f*~R=@ȭ?ÓЫ@NҰ&ruocD ÐTdC9#'/:T>5#*} 엟Z'Mz'~9wS>O*O*a'¥,s<#'Tq TxRzRqB\b1ڎJ0kUk{!MT cTˮJ57?8 oR- j+|+A>PR+yq=%gS7_IJE}T1.™RI^~WXr*VZ@[]w}f TT:W3}v$^֔]J%Ws%+ ]yJZs9&oZd]mF:WEe錙q -J=4 Sb_Jᱫth`7>*5>ꔦ*pT=ٮKX*-80R~T9<ڞz3I/%bRJzFJmuʫԍTb AǚW*(Y3Ju??cgmW*  GZT=kH%xgRyFJUEHɠ'K^@\3+Uq<+/M*a Ŋ`VTKJ5tS/ Sm : ,Tx$bEa* Kp؊^$1:H? TO]1~PLel8;1`9b*(=AA%J}l1 d?F q$LLŧ(0f]N n]gnTircL+s#BciaS ģ& Q+D50s? -W0Evg [b#`D|B -^TGY%5%nSM.'L"q[LUu JC(@ Ţ|U!0f8zxN cQTt6FųքŸ.li*S Ҳqm*]d0Ug菡@1Sh9Wn}ZäӚ@#ͺ*u;g@Ej;$d*<2W-cFLŘڅƴt<bTM=nL JrZd*"~9Fsv|L klS*@Ii.\K*Vf(jݑ+R"S{1\F/\R~ǺF7Po{}dCr/RSLORJu ,eM,2I }һƵ1ݛm4T~D FjߓI,  (+;^b*{[q٨[掘r=Xl 4"1UVv۸cPL38 -jE? dϑ/JLLrC2nTsL:WSPZ5 ng2Em8cF e*HU[LFң/SㆴbsvT;yC -᷃J833BtIme*e(SꎫTd@ϟr1#wqLW#M)G|er@uLh%ET:SI'RyAoT]ު Wx1U2S{I<16(KLXkMva"TL&#}|jɢUOMe(bŖME*Ŧ:VHT@̾5-]S 57E2[eMW -{yYcɮDJ:ť#JSa4SoөBY֞T:ʁaN)tEʎB-3ɄnT K@tɩoԍȩm߹*(e:Õ# , -oVrN%ts^WL}S -֩gzt a0ug1JgAVtSP=(oO>UWuS^lB0}*K6y}68j'?d>U'@TYU[T)ra30zSQ -sĽS%/0H˷NB(1-CIUI -YZ7DjK,xU$ހ:v_5ʋ~*ga+(쵯[W[DY4-bSTe̓? X~*8*@!^Ý1NOa0G(Xp #SU-$#w] -sTq}*sjV@j?XxǬ` T WT᫯XAUHMIV#"M1TU|F+xe>Q$[P%=G|E4@ZPGiH_G9BP]ѿ׊5T䆕cu)YAUvTƧd 2dQ*]ֺדQT ITFU}qdH UL@M!Tm{U3ǝj]FJjP(ڂD K~LwT5%A%}3#Z: : IT/p^s;7k$B,}g,oa]U Jx\ysӒq;ቧLg{:uTPm ּiǠuk( c Ҡʒa.TQ)'kMi렊u' :2/ϊdG1JKngwBUsՉ,^04S10,͓cM).p⨈v9G}˲b,Fl(M>:j=24;D_ -AGTYb@}/EUOQnA?.jLD*O/q:%:To(7^Ev!:*[ F9ej$|>T/6:4w`8H^2~:*!T - r.M>R4W 4>֠HOX ngK@T5L`#J+rIRUx8jDu;F+qrc6tO? $Bى!Qe\U$ fpo1٢jDQsрL*/U(>H[\TQ *<#0QE RY$*ڥ -0_TBT(`DTERS7*- Z˒oo" 1di쳐UƇ* bP%"Y!0j;dgKWVRlй|ϑ*(RDrJFTUJ@ -Qub tub۽=iFj&L|Y?E&QW5m+>'iU\K\: -ʱRնu (ڛ b/={-e?ȝ3U?p~VpLc{#_T98q:D먚ߓ4Ӎagժ0;H^a_:9>'#҇jTqU0A'5ǬAdvxKy@z3w{l(d]/U!dGQBL<sZN̻@ecZv(c2ku!洺,uHRTP$ -Y|ɚK'Sԕ=s>!6X*힊Ks*$׾zT#T_Seq|%zM*^re~A  \&gJRYPPew:b}[,́PUg0,H,d!u̇PS4"TF_oUVF@<8-yB'.Dd U/utَ U_3PR<ٍ PU2M0K^BUp ă*^(O5IXB fxZBZB$O*TU -\t!0L@cՊE='"ԩV~E^Xֈdz4KvGèQܳɺ NM;$V@kC^\͘jC}. -ZC{`P(*|zv,o|92K@e4)hk!5 t:+fS3 - Z `{+.JZlXwQ8$P܅W$̹q?U5Nժ/vcgg\m *ɾ$П‹ #ȣyk+9B].~r=oK+-J:28D<6x3ēelwqV8V%EbsMXԀTo9Ly[&҅l2\v;:K?9&2EuYOu Cl! ȋ /e˪1 LIQzƣ&ͦRܠUZ=R*|oac//  DA#t*Qu4|8-_sA60>D<`fCz(://Itf`m0Ju{eLazu݌= TO -Aĥw" ISsbOdNC m(OL/sRdv9B%(1]P`8J H!^ɀ@bL.!DϑrBp$"T__s.vj,TT@ҳn; vT_RXiN\ ưs'ĂWhfO:^{34]PP*Ӷ *f 6^ޗd1 -9ŠC0`ȥP^mMoyrX,|[06Ǥ(M$~ ߦ]74 I#3#lłU$*P̈́{r-5c9^iu^-ƼB&\:;ֶ!F=}(9]Jf;ҹsCi9RSهO͇3 ~/1=X*!%H%_^@2m}c3^jT,G u|!TA-YLgBx4;`#KQd 15]䁤{0l aBAw -~7xc=pcsv.< fԶEUGG$In7g9Jx:BS צ0N[wQ4q~9| scazSS[{މsZ fp'"WEm P-5*hWoA%Raϱod7.+ FȰ0o 67yKK ~Ti2C_a -nC!׎+]}xS -8O`w9̤ ‚XL!0ڏd -JhR#7w4N薸lYb0m%[QHu6[4ĪbfwKԐ\2рeBn<TQH:Qr/ he<pA2|68ńmkEWPMվ.5l폲U5@lt'`ZsiVz>`5Z]29Џcs@r~"rxuox5fgHi45br^vwhk 2*%nA  -Ȉ5C]IZh0xsY͇4=qYd-`llR(0 # T0_3T$ "k Lg}@eضr I l>ZC7dSx UJs`"vW-MJfrB(4JքgIwqn`U"PMɪB^G`&뾝L!69 h%#Pc2Zey5G.GP %ñ/^]V UI >˸~[E| Arj6ճk( M)`09jKtYJ[}]͊*Z\&rv=kER&ӶkNQq%*Bi ˆgbyӥjs)Eځ* w!Q> Fya9D^[,m@OAfğAAC{rS&"NNk'ߣaUKf=m+݌U?DW'2Ejh: G{~TN` -7qbOj}Oo4k\|Hh@21D*J$m۸X츘/[S1| Xww Fʩ^8pcUQտ譋O?0`4'f'*2lL39-5;CA!z:SUڀ"BOð@*<^vYbL.jԕYL{tmk>J[*Ҏp|RGn*̵v 0h;v 7Eh-OF+r5ӬI4ҧ& g.S\\~:l\qӓ1MEP؅E, -: P۔(0tȕ|G%$DՈkۮ CSܠL {tmpp0 E< T )Ce^r;]rR[=4tvJ'W$PZ9i!?BpenEoϼ ^uJtVg%#$7)oVFk -$N$ۂt6nb`G`AD*tME,Gu~ԻGF[kB&a}@u)1@&A1L, lW^JGR<.G& lܱ0xIm/:gmH)M M_v6a>pqEq7V4w@T\-JkC, ODT6aO'Fr̵<*&srځ.&gglcY0=lg"591M?"W)z.Wc:\*-nhRp#7ŻßF';7cg -+QV$ Y=y9<)x,wEu7r5<7X\jʧکP_cɺ}.LQo!r(tL㹕PKlqKc5!3'xū52Kvn BԗɱΜg^wVϷw-&$|:x +ęEDb@osqЏ5gf~ EX6P(o*33-E*xBZ )U a 1!)sAt3aED܄Vu) AKt`%%cu %㳙K`iJUXJ 2HF$VWm#"B ns]0Ys4{]ek2Ã;z"qZᜲ`rBO~1Qȇ]j^2jQF3 c n23ʰRc`06>fbzr[<="K2*%IҤPdB$LoYK,ZX7E?cHt4ud,w+l8" 8 y|QGD}™jX,ShXBQ0Rx=܌+pOĂu)p382>??2ֿ'|2wh&ql~ExWǴe4F#>1ߘ5U! 3 ;z%( w5N[f~y;3| 1,?/Rs A?4ןb8̱Qm# fyҙ` 9%x҅Cƒ<ᖧ rC?2[&pJO7Dpb9Zv.Ze ]zQ(H#hZp9WB#PE>&IL4*p$ £N&pE -c,a*ѫz4͔f ֆW^9D0[ !mVNy*?>Ci󄷡 -Z%SS-aƦS)tbߍ[FO업b*f[yƼA4D{f 4bb1Opf`E?bx[Xvdb!la<0D~BDdb  ִxCl &B2ߎSlP).CC[ -$ f|j2 b$!ivsގ^8%oD&$<5&m]EyXO$&d}BKi"?c`kDࢌ JrNӶA_ڄ(Iwo:1:4I"u,.ѽ.Q5D$5LqY_6$7_$Xr(j0*7ƨ 5tJ#>`k&H PyS|&_s t-k\ |I/\*˖# w#H~bB  Hg:pqa??^H֢#`؜Dsb_~F-/w& C]lκB7k!ݸ{'vAM.0s#Ǣ0w \pKIC k$3vSco&pFLAcm2>+jB{2fZ/Рr'hh#TRUdş}`zp#-Q(EM?7E-[d]r_͂DM -jC[sݾ_H~0ȗ/@m.YbpOμ^X]EMFM}I@FMa8D߿9OБnc-{QHӄ:?-̱lsiPk\`kƿ M xvKpN8JZ -1 ep(1Î hBA0&Uc qgb' btUX֠P3~:8.QSL[pGcțTf8WIQW=hO\)@I,3d.ڦN\|_- pA=*hs ܐyuNR`Iހ@M"^3׮ `q±ݏFGӗ8^Bh O@wB.pxz_\ - ݷ-Ŗes Zʏj 8M湄"H?AKq$x9c -1AbpEl\In% s &D h.a}CO(pQv"$ \ eS>8Z]qks |~)/ ӿ.Lf |טxm W3.YsmE{z;x.V}11T\ =9p9K؄Ӆ=@B |E^݈tvd/HXP}D%, 0s ڸ@s}Sz>c%p!hknZĢxh0kЛZs 2{xvc7Ӹ\27KqʝrGU?5yZnp{OL es .Ȃ\PGӲ5ox1mmӏЭza&a&UGs *U6e{O\ V]Bin, xyՙK}f&\ Aeؚ\+Sħ sLpqP -n" -)˩ϹXuö ?$; T(xQo;o \bf.lK7 -jgfTM`@o2FQD7X%DU2R&)?.p^o -)a ئ\̷r%hm )sHTN(pAb%DKО)n稩{K.ːܜ$QrEKI;oR}M'Up'`iO~-.<ʿ<%0-a,7pAvݔ0pQ&ge \[]!Qw0. ("ɮ=VX0bי̈́,+QUd^3H"ѽ-~pp-ϥFK;oa5D,I7rP p Ә+M}78"#!v̖lEZ -G-aS$S,iVٝ-.(z7j$<%XCGv$p:ٕ|FKȿ l*|gx].H*rU\#L.@ -[V-kҀ~*q\I-Aa/ДM8a -`_C ҃+=^a A3 z A]^=mĄG96wJdGK@i1ZBA1Ih ƂoD%ؒj$F?i.^Vң%T%,h{]R0c/;h !FP_1C0,J/@@3\ =N Lj9 -=ߢk -+ܪ -Q Y1V 2%DBUM-pRtc%ȷWV3V+JDrDʩ?WqP9ɼҡv},߂qR Ydbn? (" -'L0+ +nibw~LơtGXQvqp>rrV -v{XP g.H^_EN ٚqdg)ߝ -p;G}N |5o4{9%(Ջ$u-mPlȡ0:8&H~+Q>[F SXyU1\XKЉ-&t <ߜ.>X7ee/)YN}r=\ĽZ=ֳݘ6|7PJ?J3P]/-\?/%^O5d* k nIb.-J*5L *]-FCP- -EƁ [Hg" jz>chYI]$ܕ''Z 3Η ]3 :""@gWIHȡO4HoggCgX'$-N}4oa$[h6q^0 %6vh9}z^pSscH.FN>cU2zqǛ&\${ꤺ-ۓ=Kwt -قP3MG{U\H;B$B+h;BAn7Q//L=U?TpqebY_.ݭ$ݞp1]PO.Qo7IK#ԃqBQLE6*J\pd'A6]'ǀ9558 dpq!D-3pJsm3O EH]hr?..Ûy  tVR τ@:$ iӁVKfm##bo5NՈ~-wY#g` twy-j-Z8'NXob}Ơj[` /3B[h{J+t:,Х}NNVQܷ(ad)OAG Ey\Dh$Ix],oA\_$5 MR::Dq-V[ؑ$з9w*HZbpltKnZ[IjrxAMiؗqj5y/AcUl-؃y&EԷ~b^%(!^&,CS]NWӎ@+~բKIP-9DO8j(xɌ#Hd;J `}_K.&m@8ShE\MI85Kr;%?KD@!=σkAʎ0;x}$dG~ '>NsΫL3\g*pS:3r#:L=P9ׇ~{N6ş o}>gSq0}8qsW[NzoѼa\sσŹW% G$)[bXZrTl&FλnK~"σS[U`H GbMDH#+_ad70-ѣ6y[2/Ғ;I-0m]O,9}$ -L,Y,Ev.@) }j[TX&A:CxFQc[ -"X,7y31 K-{9=-Zp `}G!%]aZ.W`Y: QX#* -z+tƭb_+N0 -qU++VP P -QxpTB>bPP?E-z -ox -)8(TM?\7)-,(iXѦ& +6aRֿWS=;alz -#VS`x0ӧwTMq -(, СOa +K,,jz[ A1 /,@ 0氙ækh@LB>qn$%֤=Hb' -lMl%XDMj]˿c5hFc pIxavuo7olƞ=e8}: u.yW;n/M`zJl'2H){B !َ^eG.ٕd)64dZ?()eKdnj -I.TM*V{[ٞ~eueh4RADLLe޿b982["&9ߚ2bbFL -Hbt53ƿ`! =j=Y,f)lY(xYs 3=ή,;39>S4cSXf(Wa` -Ym)gB"<9b㙮˯:)ְƳܽ3ӑ).)HY03@hg 27U<~)' <( ƫH,L>+E08X0L>;AL1r-g]at0@1km] -RYPk~3"?J'CM -%EF -)H7r(zҴ(("Q QȢQt(hc4mQ^\+kR& -,DQp"?#@fyޡءXWgCA -:P}g8j+劀Hg3k p1yBFA?he?1 B` -@ ')/'(3D,V~2"h;M68.`(zy"ΰz Aw"j'BN45 7`@ՉZt/:Q9A ʉ!'pƉ쟍@8ڇ0817HoBoFa&0&@(` qhW@b|M|>4ˆ?EikM4 GMpM -Mh4d R?>W fBZe2e_K&B&nh9D͋ &4&@4`'`[2_8㺡Ю堹Cs D& |kr0^|$4  4/!5y%9@|r& | ^%f&/Kw ;KuZ%ZL%ZHU3@3%K-aZhZB?D%%0}~6,1xҕ0ϴ?JJ;$UŬ@X ĘhSVxm- 4m@@sg"@aM9eWU Y= F].Tb4jUM 4VlgACI|-M/72\=n"3Tr*A=g#@ͥ BZ˙O%Z}4U"`z*!0w[2C}*aͨDmQO@㳁6m}r6_)AM:xͥ7"ZQhA*Zy›іrt4ZG;I'i #Gaq.D&q"L1\__Iл4.Ss$/nl3$qִ" ptG28e}xF"&gu-H Q H\Lj/6NmуT+$Rm20UH AjmX-XB1PeQ=ܛB~8i>y@Đ.YN96whdĩ dWd#:S\ -#OOq -2h%Egta=q+qfJ7;ĉzqMKA+CJ v` 5J\kgTJ1J\A,}K3)ݺ rAGӷqÈ[s88%NeSh₰tZ f7Xrg8]T'}].rf֒i.9پ\˟\HmWTN -*.:Y̶lrI!/n-V9 b#q579Z_6P 2W p&>:e^s2/8-/ A_\U| D(%*]Sy`  D䀎F\t -tooA mA.s'Ȓ -v?i[?G\@^,'A(AA|?' q9A Dn 9J0H>Wqʲ} Ƀ}%X8M14uйB؜Zز9{fƹsZGιQ͘sGV6*s~sS+ʀ +tT>ݿNtO!atl`_n@t:z1&oChp -e:8Mw?L;]= ~XSwG?QB䇚kuCX~Qw~8vj_!>0/Wj>|G>c$|uCL .+|_du=ǯ9Pr=ԓ:#K2inC)5Z9@`~4/`ypɃC`[~u?L%B<;]A vJJ6Pk?;\;p ekfπAOwf*@dƥZۨev04;;T@uЖu-$Tϋ|:t`Y7]˺PN!_:=fa[߽|}kBCSFkx7 >q]V3#E; W>Y|#|׺ |.Ï}A V'|.A_ncO fSv)4Z+[eHJ2: w2&AG2})H#Qo$%{8 lPg?} qc`(D8`uc ^ _[[nCIA/(@i>!D[0cn0Å}:᪄C,>JC*R`8iCxM 0A~6P /t c{IK>^7Ha Ey!e .huĪ a9r07>ط8{rl=.,}C@Ťt~.o!}@n r[n7m![/xlB1}0ՂB*N  k_DPhK߉XY0vVf?2 n,heY8p7xгXҶXaA:Jt D#XvouW(.1pK{~O+P>\x!0m_y[k -Ow -6'++XPΫ`=VAWB -zS5DOyxjR̮ai` -Pv>g4,nD - q`Ls}6->ӑ)е)}#O|l$ۧ9`sSq#kىRﲵ/1/w N. F[*>)e{/OX* -g%)}/y}܆kX*L=1-RD/75Lq}S}ڗubN#LT%(D4֊ - -kվT -gҰF*do܉n> ^ rBpYAOH4*WԭPh| Br@#>)TОh#,X.Qnh_<1 V 3vPi -[ydFOWAC7h_`?T tvС=TpĢO-?>W` u -)Sh`;SBKKRRPЇR`RP>RR@"FW*PjJWaT, - -O7rWPk0@D,n{(\:+"bЭ}r@'Op'AOȴվ'OIP"J`_Jg'`T'8YdM9N^ a/O7Z &&(XR|&$pi&^RwR_BɄ(&\00/gj%ļ]·NxK8mj f ;u%p~\P K zQBO(ٓb9 L+ NP'>>]H]$AXA'Hh3Dr_ZCm$Z !W$g`5AX;#>a`6?i/I8T9}l. jC9}exFUU}gyNߑ' Xxb}B@*a0MٌTQE e0E@ z" Dc"x>E:I'|Ї!B siyM:8껇Ŀ!BL CFHz}!x(?!gr6>y_=wHEC=dާػ@G}wr(4:m)d=[Cx Gj[CHz3D| -GYCxNN_C` o!p.BB'PbB8|AMCmAl}s*5]Ƃ'I|:  $m Z &܀=B@m? -ֲ~}CzE>>7|}䃒}, b>{r{\S*z`CW/΃Ay˃S ǃԉug@&[ |B;(Jj0x뀼XPp} AFeOў7A.ǟ~9rp\+U?290 <;tX  ÁW/ppmoAh ne7 ݀ /m% Nh(VEę&6@1=66P5`)@`V}H T;09Y1o> 駁2S?n6i3` ~P?KCA{હ`)OC5x/}k ~9bj8~+g\A~~a\4FpdA / >&4h`r*7GN3@Pf`̀"\3N Ưd@02d y \HB k'wc`~Ǡ~c Ѕ_*X^%P`X=YL_Gj/u-o ~N ctƠ]1xOCx|+'E8ߺ1蝣 YO?] PW1/1(KkS09D.ao=~xhLJCa0RhեSz1(Ǭ㧖t,y"??bl'ȔQ"5<_cʉ$ay, 11#b#LG_StbA8[4bHWv7DL(Α#"2 =/ h֏rSZ'?l$GIE R1LBݯ5 R.0O嗕 ) -W4(Q/s-z+b]e^0~c׭;T~XX~=&TW~*;9 dS~V\Ha.Z :)~ႁoA{t -0-pT~h:(j㴠8/MdbZxD, \ƙF@r ,'$n˰jaA : ]@H唉 -*D9 9C@ ?*x* -kr -I*::,F^7X3z[IALRU(8J߆S`1/REЙ_' 'y |槚 ,p&@N:c&L@yd~ V`L0O/A".e5Iɧ`L2 $|{_{ (GG@#Px@"0kEr!O2+*!!@C@AK/M(o-u -|bA#!8X -eXA*J!a { C@?yeܶ8'X\~|}{ 0K9'`{ށ$C"P:這T;9r%F@Ժ8`p~u-L܀/ۀ m|5PWtIFj4]@h s 29eS2p{CȰ0(o ' )$Fli 029Q6qZ^r-(Ie. p,`\X+P~ZGX6=?:OFD)Y -h!dH/Ș|E~n-?ùC^[~XIa-Y.?IRL0X^_g#%TBğUOˏś~OrU|%3@_eAP@^ -='~J6\M% l_O@A?+?*#b%'#'ʟ%  ?~p-1I\}'"Lya@' _AwD8#JfySOexcY#A2ASEv{Q -AV |zM`ۋ@!$@7n+eGr(J7?.nEԱJN]6w%Om%tNh, i|@ZȠ1AGdgj,-c" y%Vj~=`^<.׍R RD۫o= ƚ8~WJ"mFZSWs;A>[LsMEAK)ӒL47A.v0>|r.pD:-MF7lUqM_D紵­ڀF)VʪXQCV]Ep4!:W?bb]!RX- -3^ʀ -ҖK(]u !qȐ` x*Z@$GeX x`<;`~#xP,^,/pi0_Z8HO̽ޤG+qvDVH0l -;n#orXf N@Pf(k0rD' kK6 nhz&I@I3#&,8k~QQb~%` ^7uPFh<=EPk4ZxGZ\N5myz+;I8Sѱq"T}XD~ !IÁ+ ؛^| &v P45trh,Pv|!/R4R`*c/S.%bLS_,ڲ6)٦ɲcބub'`zJ`ʸ.g`@ܯŴI| ?HAr{"?c PUv&V̛2JU0Yw$W$$fقDI8tl4 YSpaI_Uth0K7R iCGI]-2'7@'Q -pD! "]>^{L c Bcf J,E[!_C"ޛ[1Ӡ/ `F< -pc(TMԡ_@`(:H0Bs,@͖s;7s @ S{";}wmjt˔1\t 5FksAQɕ9 wfkaoޔ5$Z69~P `ݗerNRkG <x["N{1a$N?.l$WZ<{h,nR#^͔!NJvr֚@Л>ptwa=&&0<P,A TH([t] 3%ncCv<{L tw_߇є/y2{0FPp@.Mۜy@AS<֠ ?ӕ -GE2Y I`_#qf_`3V97pN`>ER 9,"eFαDnXyuF/-sTgr HJGA}7 7Wv"m aS+">e}p:[j $A:똖6,j !*h)fIeF1,_;=t l*Tm%|WMq\dK1ʱ?5a82s -;bG?Gt)n&arGN7A&;TZ157)W6Wj ->Vg C-$QHႺ|x8xX Qs #ǘa=)C ,?c(bs!½ g3EʢB #G:Xwbds @0P`Y"G#iPƎT 7>ވ @cU~#t8i@+ >,qj;Sv u mNS5@PgL]>AjjC,4j"JԎ^G@a,^覙 cI2Ok's-8;`8YnQPEC-.m$zq`gY RE]u?oL4-C&4v(G|ꑗǛc%ZxdhvPβH̋MOLe ̖Һ0r@  Z)EƹFHY)6 ]V;)溢͊Uz3rVLscBmoE\V/_g2"' \oGsN -8)ӫDQw$4j &dm(LJ T'4&iM$$Ҁ!0JҺ -J[@V*7יm\0pF>̰WzXIFӼp -#C'h)Ii< -Cfn=l.D8{?voٯ^3Z}*B#%c迴AQ'(y52T٘dc%?kgړVs:t:vA֧\=GM%oKV>T{)n>F;)_1E"Z=X79O~C=gthX&>)irKRrSj鍊ټZD r㍮Z_\h)V"-C\/7 U(D1kHj$ǝ^E̮q#!B"~__CAHhZ١HF#yS1ӯ4lzeqHE#B u7 T&9)9=ddX,=7-J`81=OaQfa.[E:Űsݗ0KU]RI|rVLﰘ!k;귉R(F:u'.[eԭ n;c΄yɕEޚl%+/,M;{ɭ1 tsN}nPdZBKܫ:d͈MmV)QlEs5˧MC"hDia ,,UW\N!.R1[İi#qAGM1s!\eR7Kf3kSoR#ʛWfcủ-.<'h9-N!/*\(pzB̬ETԄJY0@@^\A:/A(ӓHd| -Wj iI rBX.` ,0P@5+1S -ViO>Ba -dJ_,0(F8``(}bL!(HҀ&0` @`5 `pP "@`2Xa>DHhHJF/W* "+uTh}2JKrd݌`+Dq;d+ZWb[Bfc;1&wGv7qp5cUYWR㠪XS˜.cC%%ޟ%Oa\(ACg]:w#*zuߑZr:Ӓg)/bk2su1t=)b)\a4QեC8 >B`&,0( j6afi -14f^w7ULfABXXDV`фޞS51(1BD^>$JcgDyHVRJ 0PEӨCU0Yxb} GBVIDp?,hU!J! -7@ BEE(| -ST -Eآ苩 E)_jbP( -LHKT8&Ұ~ (X4HzBZ;T_Xj!^ 2`͔HDE;tg/{+e1f$C'7C`pt6ȡ |+4Iv)5 ]ֶ]t5O5xr D~mopOD:.RٹNvnAk`8VzF!xL%G³QKJK>stream --hotbWBDFA}(S69L'?98ۀ@#qE VzK]F -MrWJM!"VpQeW]r2Cl';W'jPKFmT?6.$oF:<&{ K([r0@] zsʄ/w|XtZN .?78}8ǜK`zszӲLbOU?!u#^oqV8 IvvzvoVbc K\̤JrwP]@c8!j hIbCZI-ޭ A1"RgExw֜(tdݜe{~w] ND%J'| #WD^0#v-l]{4dl l,,CՂdi3Z6GNW xw5XWA*@yh@q 2Wpr& PviYu$2JWq -G dx;0oHÕ -Ez iI3d|P _4:fhD2>Pp|ό|F9'Xzd,|e4*œx[(, ҄"LV\ -mqOh2c%oܜ^m{W= }SLd΋>,fnHr7b}G%SnZ89IHOEJ\\$rCbh*:#oȯd'svdˆ."-B5NPRp޷iOiY!0C٣ ̏'ZCʸID/LLq U7LNnC~ q˞~ؽ.pyh%XI= =j؃ >2,԰u aR]b06RRw ;*kn)d Jװ@_5Lذᰅu }X8Q[-.#%Y Sҥ[yaF7..qq+ed\ KyMN゠5g\d^XOOlbص'W3 ala=x#2.=qMzam]6аX64."aA%vxal2A u U̴Jr!wagF 1b:Tw&faϢX:bIjT܃rhy5.Z}0PcW7}OñḺU?0 Uy  {qA揹la$9.F';V ddWHv5fdq^8.(TX)m\`Ee*;׸`%ڸ` -7.2 hYg,Y6)k>߲h>ڳ3`A:[lBgַ<1W͔I ゞ7YAz,켦3ɸxTʧD~pQnQ|F~3prcghhm'Ը4nzzz{q4|d2.b&~jg\U苤hJOw2.O?bܖ||kҸVcfPHBh9 ߈As]WFE̠u EMY2K\A Eh8Bih434 ruςCYϴnhoВ C+ЀШ壯҄q;П8VYchLQ -mThO8U& #Cy'hD[EܸŋqF[8.@3Zm\H*K0ګp H-j4qJ)-pEkr}PD ͍@FDiFErqmmRDZMSȜq)4HK){pE@W|yl\xNchn\24(`1o 2_6.qaРQu=B Z ' ͪ۸T 4]ԸOh;иMJm 'B оdq -o[BIC3.EP3e+[qQ/ -"گtqQxhv>ZqV|hАnC%cb\a`\DT(QOB+7B[+Ok+4i(= i%N, -MJlZ.#blC-Idž6P M ?4JhEkC]h0.hL IgMQbH۩)-_ZB!a\ii -Nf?M{jԾGj4c-`\HOSҧQ-jjj,Q0W j kfٕy/ǚ/}ȱY!Pkd\dki3.L2͵57]{ܼg5{.`{w׸Ǣk.olÌc $ l{Ife\Lk`g?qBqgV~ƅtB̖gvƸ:yӄ|ͧm (1&Vi*k ͉moiumma|=(.C8[@*p1mۋ{@܇Bh'v_!8q8CEq&ebY4n^"A$A8S8"UXwrO8,! 0 8,@ՋsH,hY\:%1RE*'}q$lTbycq9-.6Lx+^?YHSzqL}!9306e8lBσFWgJx(gEEN9W9xCa\hf\N/W8B\d`-^-6xyMxJU7ru.2s2Y {#L]?\ϡLZY?g#NDH-¹d#]\&ds#N.0yN3,:iyEgR/Kt'"i”8d  47'I"BAt&%|\a"EUuEեà<ɬOy^>*V"sFq%}t@Ai51h)c,L))~7MQ1u_Akɤ_|-u(uɦhPuهX$p:yoQ% mU'q1Ӭ$6_[IZH!.F*o wAθ¤k#ѵ$EIUB BCň:z}$˪k}5K{o3Dt2ФQzM]'ve uI -xH$uSWC:PIzP+`*Ň F%>puv 11;} Ǟ .1q!Vzp@w~nE<(.bF9Iq8g^%Q\T3<xxA -̕+v\5Ή lą<!^0z⢥PxۉO\,x -w$8)XgJ\xZ+-^G63קּ'.Ȏ̚/n8xQG^pcY\MhAqdS_>2OG6WQ+cr^⢆vT|ſ)zpB7GO/G!!.\kl+L\]Oa4{M&.8{0 vWr"kOu{4gmŅvoc/EN\Q֗ -NdC_>"('}i oaoa 0tҌoD$-B,M[y#>~LmqT `2'[BЌ վkKRl_/}(L_oߢ !}v OVb> ;Nc~ -KO(-O Yl3GBU=gp D)Mf C~i/}M>D}-q C}*p۾̹\HE-> o,}L W"m,l>lپ qܹ(iSA_Ba!U"IxV7} %2,"44dNk1Ib7H*;җgVhSpp[/*F_E}7J7C _茱}}..yw=@/\090ER:pЃ "j,ڷεo0o6ŐD\\־dA'|!U.M5U.}X I"Aj?0b5 *E$#-Ѿ!'*{(=kACB^D*ǖ"=>A^Eݯ͖!UeY_cM?}\k Fo׾a>eobk.2l}i@s^Z]ھ,m_i<zOeo&ob4a0ŠRE͛.ptу FI KJ񪑦\ At_ʄopXߘ;0y1l/PhppS7pC\U(`ڡF䕼.%;n(T\`ppVy2E o5‚ 08Mݸr  ݊ .(\O -lǟ .>} -k P|cG)}*&y.݁A 7'R>}5 })eEqࢉﳎ+ }4 \4z&pSoYwpS;'J8a#ݹ.psNu:bc}6p3ˇ\U\,\qoi\T }6\tT.z}|?u>~.LpC\t(3vIc .\̼g:/ݬ*E\@~ڴ"]>C+\ވK6&{]su}#Cp!oye -.,i6> -.Hp~EpуFY6M9{s@ǁ"yKC?:3!P~E'?o5p`{#. FpoAW\+ \o .%HJI6?.`ŽZ \hWME. ?;)n"e..61 \\ A~1,eC~+5\(U~ ʁ~-HA~&(Cb+LlR>~b[Ǐ 4i8=HN.p\$/Gɏ!׹ؒ+. \pa$@EmkEۂZWP oB8O~E.ʯS~T"%@ "U~.o52IH_ᾆ ЁhWxI[W\h) p1{ 8ʯp&hDj˝..ҚVaI4Bg\,Rol;2+?][`e5~E,E ER~uBk$z8:D&."JV'yD2{*eeEEH+3ϝɞqY FK@ FRu(d^2o}} 륁10Qm%ٷJoDbA( -+:[]Gc+} _l|̷R /-{E$[Z˾E'+EvnYb`Klz!/.d7vȧ4-sTU|A!hUBOة.jn3ߢ9u4*EߘzVbtEcH=Mh-Ѥ{/T_-4`t\1fvq(n,aB7I?pa7t$j -Zijz-їdn:]8y\H-pG ufO["r "Q6ΩuZ%D --[RRڧ { [&\ڼB$-OŪmf pJMI\$}?f@I9N D 5 Ʃ :P>pO3L\hB/gOq8ʓ%.JiJ7S_b (󍇗OʄZ3bL~`ƒfp.XAqC+`K =* t\=>V15Smꓤz4u)B0{0i((,*ٺ%)ÎLAUCM| iAIJndžM6/-^#QwXG2$ PB:p͊>[|Oxu4[ML!*Tg7ࢺGlŚ hX&\79R0I\0F?TIGf[/:6 L!r_Jڹi/P ՛ # 0X&i4_/ vJa"OCS r5pH]#^=8CE>={2Ю9U|& ƫADE!7m^̛$/d\q5 0͸0(|I#Bʼ֠7ԣ*ȶXBIJ`"d{Y\*^8O.T)La҇`[SHe92N\%A* 4JGb`NdEpFsɌR876GpQŽ;3MXZD ~onլKbK=%[`CT"C^. -i"2Y5kH^Y t (qVboR.bOX-.8w>-\T⠞hnQ%˔ J }("-bـ.jȦ5$dTvHbtMC볈s3ơ|MK}\ӹ0m']? ,ʈ1k)=G]`BUt.|l 1ӾspA"ts!@jp^Yct.ԅLe .sH .vˀ \~lq\@jwYDt{b.>wtC4EEu͹kdý^1vpt|Do6 .J5pQDk F7 cG9Hbˠ*I΅NXNoym¡٣sz;ⶂ.~; IѹwSF8e\}}LA&Ui7:t.5oxJOTL19^vy|,]X?w1?UBv%*sYW^: E} .mkcC"3\ħIwa;Gz nE["ƻmhXWf7f#Hu ..Ȭs||eҸ1E3ӈ@(MpY)nmLe@ds.\k324쌂\C:iN1"4 >'\c6~ -.<c{ιV\E􍁿 x -.ʎ2  -.$ƙfKm."6\_osAb L[98L0P삍[-=IBT͜N{ιpgd;N $iEk6!gsOFp1*?# Zod@L7$,OðGדf{!Mp3-z~\4P(V \+,5l2DPpv^"Sܕ)Oa^E0,(T@d)B9bZ+2Wn!Q* ƛ \.QǙȧԶ  묫V15> |Sjt[[OTHy22 .T&x4&_d8QDւ 7"z-!{QP:R>׸͔\ԘQsLlg6뽿HE\tt!j!z#)5fA◴4MR\\&WdCyXj\tyţ+=(e0 P^Jca'culj'b+ .,;5Ƈ[m82xl^/ؗè*bpDTsƪc$`pY`{FJ&Bel j]" QQ2,*sX;8='hp3 @e3X8KfI\3B34W〝`7a2֫\N\\LJ\'(jBy'Ogp_aCK+&۝bhn-\t[.0/a6H!νy\_ .bWǺ/ԮAתs Rn\\lEL%R{TOnpqj`,#}ù$QFbr5P)3Rmp1Z nӅ^PBDd%ż=?h".)khp!cB!#}fԂx[yW7O.E]~֜`nCZKV_Ko\̟q^7v.=]dô僩uTh0qG%m'C`Ե @<3 ;&->Z}SM׳nDkRVmB: (ve"s} D)=8br\^),E^lN6v*,Z;0uk%< -+nDEcˡs3!,[52z`eÀl0+le@G*0ٞVֽ!w#Zf\4?m,}<'dLA -7IRJ\7[7H<#v81;E0Hc<-b{2Tȝ:z4 -׎X%͑ -*M9Ep1E̞ J -kK\tS9:p죂u{a}t6i9pI_!r" $`E c]Ef(1fuaG:IFּ.!K[5*o(ljTp'|0ܸORV\PRTiN -/8g2:{|X>.+#*j\ B`\ pm8Kڇ;V\DY4d*րjT -v5 \|o # VWlר0RrVIЋ1U[j4ةWBվI4ˉ܀j%\x/6ֳQm:hTr=;|aD٨@Mcr'pHt*OGi٨P2#x -MmT,x~A) *pLL]oT@)%`wjGQbF:xɮhh)ߋo. -Y6 *\' -*9Ye -\5WO</hJAV?MKq  ?4R{;b`<S\~/BZ"DXSE0r{窡:0sISŢZV-p"!h>'V2W2N.?" -J#=9i`ES'7.W:_amzi΁ d,/HanǨpgrrˤsB;ђ".\b:e7MAM^@3åBFxՈb;ш&lP旉.݀ O;Q>p1Z:pQR ʼJ" ,R-~vThP&`,39Ei+Kpn8 -|=^ ._1od?#p^;7zCnm[pQݞyĎ*z\$0 -RѭdS@ -`yffEc;\i\^B|MN7Q <<:~t'IwҝtC-b"K؏(398;-X:DYb0$)8M-F-Xxeq}\Qj ,V&*R&ke`G $,1,"-Z&NzՒ#ZO-&+Z%$VDH95j JiY!3d|X"fb/ES@1TPv`P0JV8Tb){nRQn7 0it -Ǥcy {peu>7Ow({[UU~!*ȣGY$_QP)!j*x^H-j -E0;zU0œuKe=z1v*D%xN'$# P_#TCd#Cڂ3.2 3ȿt[%q2Fcdv"=C-ҋp⣥$&2)VUȕ$G)^0dpT<*-ZQBR್שgo˂L2<Ov"0ixϭ"Qt-˟(iň>&9}(w^BAD`"sz{L9W~$ -"ك|vWWH1BT+Ί h/GYD%}5 U3_sEHȋt:FҺZ"6 hgٯ -,0\o%xrמ?q;a\D~ -(0<.)H-Q2KWv!y\HO --z/IJ z<5rEUáTɬGAL@|U8 vwrMMzYf7[<*nO+$&?6"[)|mzUS̪8*L -N[%ݺ_=R~#:mE1$L]8}וȳJ L75Ԧ955/>\F #{sQL*ɠ@&-rǰe/h=q%|g IzYOҡO2z]E,JrUЊ(w\u)p _:ժ$sԹ&X= --3LZ4,Lòe,{LPZr+ - V˟0'CZ3v#:̾w~9rn)9'%A>$&52i)[H>S|壧n[H jDQ*nClx$VE/6 iG9f(E ^2jLOKzU]?蹓u"sڻe&y.~Mqj%Q)P_Um-~9sOpWxȥ6 $Wz{ChW%iknsˆc:'w0?5Mj֛|tώIv;~ T^65(}ݱHN`\Q۲* -cЫWE&>>ϫ-܎ԓCTZ_ё˶v~Gh6%,6)jh1CsTIK׍l|Ԯ#TI=wCo$i`>zY6=Z׿,E -}]\RSw29|Rd-CgYRQД?\g0=?v2$uu0*nySIO%CIb-h#ͱ;ج9Gرo/A䮭ZHEYp{bӝ 1)ur"1KҊTsR;\NK?d.KC92KZOUǧQGI|v3P%#4'E=fjNK|<t VEh7$fY-*:GLBd",(iME:FϢ,f.|dU*BKv*v?呛7?ZP/Sw-9\]B+΢z`5$O*- -fSm)G܌n[y^V$Gp{ĖAy v (tN&DXBSsuBcyu^׿ۖnZ yű'8WsyjYƓ/ fw~'/|5 l'p^N{S6twgwgMWzSS^ɟw⟖BQjǓ?"3+M+]EE׫:rn^h{7lNIy؋O(^kY  7g4Aogσl Hm%gn[qvp7$:RYax决p3̎Ɨvn6n';dk5G{3d%bDDp䍳3 2;nﺻ gl䯓 ݜP- -~tLOlNŶT?ovbC^1y7>vZnY44ܶ?c2YbfpnPxjՏ9Eꩋ a9(Nc-EkJrُIkt8 jWUz.y84W6mcmA)Jϐ9\$$>D$sn0ðv~R"8ZM3A@(CpMcfn6$fմ^nNM?5M+gjڪi$pbմV\-ntTNpҌt8A4Q}޸át<  -Vn6]r8ꆓr8!ȺuΪe"U9d% -&esv]upRΦ37'RL"|ߛ%mov:hƁm4K4Az_mYfo6:&"K~av JKݸϤ%,p8tZ:=)ʜs?蓢$E'ɏ` viޗGZkYeɮZ)ew1E0?B슏bqس >5fujƁ,'\ t5MlN'޸d;lOS/9r?hϛ/ý APNelyq؟oz+eŰE=$uPr[˿K{4Nt8fLᄸ@PYL]MAP{X[ji'fݶ5`s5ոڍ+;bf?Uݭ?t8ڝr:'>Nei#wqp m՝f=Gqm0YVn6f3P>~9Zj5%m7mZv6ITM`xdy7({IĢmk,pgA_ MKrEJ9An@^nCki-1g5orAp;޲n#]+;(Bn*rߺ8]j-yI(!鴝VRϿy1p:TfCÉ7m[9r13Nq9^k6qӤ?/l-EIҌvVugGQ gsqkǡ:n$8t'oz*5?8ڍs;Z'J ONx7$% G4Q=ϴM٤Yfm֝  n4(Yr8cQ9Y KMW6%qn m !I7B(LdX:'{ۻeig9O M?PA=;ܠ0;): vUr;6"LAr/#s<9lTΦ?/+;e,A%!Hq81콻m֩?KTax޻e (3#j5M:yX~k+ ~Kh-C-d,9lmGhʓmG~qǁSu1\5IN>~ip6뼚&w\y*v69߇iMe1ǵj_G"ǯ (͆մd_/7nh -!XEhCvbfhϋ7Np ~j's3mD{ߛejv:k)7 ơ=N8s0)uَn)]o;N޶19 H/;ll HHe]4;^nKtfݲh<7 -<Kꗣqt\j op| UnĦ.}JMlnݴtZK3_+l2nG@2T﫿,jqeCr8"3r8{YY:1K -ZSjT9~#&JE[e gfeg\,]{~$|i;mnn7ղs 8#|B!l$CiA˖\'doʈt5<[-d,(=Ajʛ$e.^sqƉ9h=W5I$A*1K-IU;T( -~8^ Ȓ}-(r:mY9x0EQGwܠ=i5CKglLk5pMAdql7dЁpR-1pni^v:"ٸZjCP4W,k5-մ4mUTDEj#}(P uGr5$Os[VnP؟#q]iu$77 2 X_NE02Q;,@@@'hTd`Zsqz!X{]'&%n`uױZi1;U=ji7M/In'#@K9ȣ,~1YbWAU#TN'E\-NźNХapk"lq8r61SB"gO; zLtEm𛿭Ԣ,6Ǩ2CxZwL &E}cu0(O/jCCS$ -m~$E/I< em[9sbW4| pZM{ҊzH䶾YZF8!e=E޴A@ e5H4&"#5u:kv175{e87s\ rC:ki76Ci 7I:6!8wuXMzc;;^S9rrjZn%kUwk j}Wi倠X^ ÏAUAQanǍV%Ϡ(_!H!/`FH -+ZRA M;Z2̂] yQĽpxѓxQ$mAy𦉛0 oi=ChYNz#,RW<>`zurZ$>`NJ -vC:}Y$"m(AF%&6#n:j17(>-BeM4'EPX}qN^XTh?OG^wQd?o0S&Qf$B|j:ۆf3@96q -mslt&Dl,/ݶ3eY{YfuRv~2_'s>8ݞ!iIr8gw^EQ;.8Vxu8IYne# -i\-~2ȁס5n[ټvqyw8o#kyWerchmg'#9Q83X=%u^b 1D ԗ np\'2ݢ|B"3}mq;ժ#vmƉռ9H=Ug~Xe):v8(gjuZvn@mӽCen[q4vv8("9{_霝Njy=)_ҪR/4%=/9r~WxĪhIp(ZS|ruNr ~w]%IbvvWl2fc vt[_Q+zv%9-rz 5W|xf!v)eriV-m>/O3ȱdDK. j=RT;WIgmUb[O9_vqjy(NG!g{ݚu:'b1n -~p<9g$GJ 7iΚqNf4ڬv:᝷r8#ټ1wNz14?嶫}'EYHigӡ8vIe?xp>3~PɏiPEjNhU?o[udn=n:}L2knAN17 'gj/|ˆJݶqy6l%6Cl{(Us3NmG{fNearBˏ)PGAYrz$a6{ zItFJIT: =N|q+nE)iZKHt UӞ3 " -VK]z'z*nc4]RS_.OtVe~Mp;d4$z8ZQh8^#]QZZy֞e.:-96ҪN:d3n@J:t?j`8s\ijnm fN٘Mjۚe8z]OY_EUn+BQ>&IJOnGqxfMִ= m;K3mOśfwJUQp$;;4[g?/،r@E:9Sd{o[e&so)EC`T27m{Ltpn?2޲ UB}̆Kyd})_GbY#:I䗴"/E)z@NcJ,;NrӟC:}M.ˋ!]aMp:t> !g,PQ5FjF,CUx@fY^q*!4ҤIbWQ+u_ݕuקH=ys9fT,_m=( -a -bjȋ_c=٦},39WQ$r=AWP/K{7MpGpFͲqfilVs\imjmII:OY_珢_.=4opRө=olЬw[OYfWm7pϫp;kDEhjZY$ec 2f>HBOYzF>P8%wm˒N3XT-S,6D&!,}rDiiMm0lLtPz\U6ح$/Qc^VçuUCA͜U -ܷ]Qr[L2hR1VW2eQ* -ݗִ:j֔E*M]1ْ肄7TL)~O9P-:=o7!oROj&Y^UEm[{ O{ iٛ$EY㰽5/{0w!O&"e+Fy5YN (HCGbzJÿm@A9 6$ o "AQr87k[5DZ᜜M^7Rӝ$;$KrُIr4W.=o67PCqlT3{yZkٴYݴVMK;hdmiNi݆g S+$¦ǹu{;.:8wߺi!'Cϳ81OSCximQ -*vN@v0W!Sz[ r1ge[o!Cloÿ%TG!/k'ZS(ޟq#u+nrӭw-]H wfxUg~M[(=MjjRQPjG.-LߣZW=ȰE?'Yb}Z'E5^li 3\dYn6t,37 ׵dCTsǽ&oq%ϭ'u r#JMw#QXʹ$E^iðZnC?OxxK o?NCi"HRQhn9M޴J*e# m{$ifqƝuz~LE[k/7'W̒6.~&ՌVzH1D O8 s[u^N/G<, v[t\߻^2pSȇG0ap$t }~nEM*bUjz̒CZ'=N4hУ?N6~R]0tl:)=yO92.Mh5W-˘BNAj(JOJ4Aޗ'I^.Pժ"ˑϊxL-a>~{ &I_u֏!/~o#MW-<^Q -fY(MwQt9lp1QR ⷓkfU<ڟgieK{^u1d 붅 (D(l2} wQ7K\ Ѭ3rP(٢㰷"$i^s]^hKE_.qgr8&NTtܶva3m<;iCMݠpm-e:԰G#^e#ȏbe\ R2VbHZ~EJ)bd]3bv'"b/L">efY__5q4TQ`J7{|8Ee",=*Ggk9 84cy;9)9ƫb)W5h5dpʿ`xÓˢxLMi鏞O9bEvͲeazSƑME7HHOwN?/Axn3(oQv; Q%5Ek>i= NtkN'U{zH<䌃{u-Zau'g=Eib (LΦW .*].)M AN9EC?xX,RWH1Rݴrv8:X{m͜n[ue)ep_G{~ǙT3dyS#ؓ(%A$~jA;j=.l^NA/;dGդ3LƟ (EMjMvat -fӱILEIq'zf9^qmց9m?^H闣 z_7 zuWBv00/Es#$,fG]4uYR4t)DUCdGQXn2VE>ZM㡘chR9n\q'r]1l?/&SeQZ:92y7M3JbnC9^gq떍ӡCzKEVجr@Pe:jҺ֠g[f_8Ns(bm$$OiJn𻿯:y7M(#C޶@jYҪ^mW2\_i0 2œnO)g)Z-IA\n?C(Q>ErŐ4peH=k%Lna<^vk;Q~Wv&i5Y6(knM(G_oxG|&(I5s.AIZ{v,ޖ'QY IzUܾ6͓}O2z~4σezoi2oo~k۾m&ky|[ys&sھw{od.m'se}x/'y/ȚdF)d׵L:x{2M|~Ff "m5͓.8df _ `J-4}n׺N黶o[{ڶeۮzyZe^s.鶜6]u=;׽l|۲Ml=O߸|7M5xo7㴌뵜|}{9\̴tTm;3˜4I 2O$qKS&NJ#T]ٵGoU-jz|}n.OTnpXQiQbRh9UH]ؖ7ZC|øi nn"Sh%'cIPJ'~U&. ~UCvʤ"ErtK*dh{֡n8j[Xll <]9】a"¡BR@)|֑E5`A >)|._ܶnm׹ zŰuwL7_Dס]u v[,bX NU4@uX-?ot"5MwΆ!޳OӜE&En #3Ƅ"]>ȐTBǍ 5LLkxNStݴ@PnqzIkm,u+*"-R",ʧnQ>oᤘk'~~(@L+9^{r6%}ł%rN 1Z\fBH;AP^'4(Qǀ|n;n un)\u1N`-JDB1e(#;f0ßv/G~M]]\|{j#;5,Xf3:-BX'亻Y$) z*~/Txo%fRŀ~I۠3>\E"N7uYfot g -yYW-bR)תLʌSl0>)Vr m֣h,}YbXjeߞ>ʡȓ'Z.s:'_E) ~ b1bg wTk4j٪if#r8f3f-$e3Qr|4ARjU>ňG#=k4w 8-`bz5S7>ϔ']<]ysN:[o9;,Ԍ)%E&!Ά4 'TXB.C^$!؝QjTH;9NeyIz^i"s49^H!>IòKc]7L MG J2f=c[qOmsT>}`C%ũc$kjn}hBf#}7Iw-(Xv5O$ChM ф:Í"b̸PlB$ [&y Bz kmEz]h=Y!ⲑ*䶟0${'vaÊ1+8񻋑XxשS38uHΦA܀3РX v8( -y~!ZQbBmBpqLեi~EGѐ!x } 5Lkڏc_l( viάRie('LW<:u$ ¥$[˒ّ}+& -)Yz4K?K;Vou$9` iRs?ꉚV@(%1#)RƣigQOĮm84KHyA-$J6hLOQ^;> <4R8b -(qc2Un^ C4-v~8kլnY -ԉ)!} vG -+dRR7XBp(fz'잀v=T%#75ŭH{t3nF er+w}yXdYNRce$^ȼB7:P @} -IJLFU˹[r6*)y4'mYlKBO֣ƞtm/tUKkUh.\E{jʠ7^q/TLh1A7O;,[; P#^[No/$r?I~6CRx\[~ޞCCqDӪntFYzYVzGNj G J kW||5(MͮE,aR22) z#bU  n̼R;>j)^o5H$$*Z/ۣђCyƟwv8:hMmͱGOU⯛AJvEY0XP%-^* Lv{p!!x *D^"}i$Y:-:Ԯ."E*DsŘHzI Ů)?h aS@H%*|'1~WBc۾=W^8*=ȠxJ0K`}vj<)QT{Q?K]vKv]B/e1RձMWXFi6ɰu]=O՛,e͓亡K?4D^&)-{P?,Iܧ*-((|h!qp.-Z6811A@R1D8TXgMʺ~K~s-:"4bCHzaRy|[n-~SqED -dBdH&:#3`1y=/!Q*,# BaØ>1HX3XDv`D:p9˱=4^fZ+z Rs]\`r1LeT(Ԣnxp"lpJ;c#x@ ɇW4MaV$E+>v v)z=\F" ԢϪz݈Oٶ.#X -FjfUzSHTl":JG4o}ZEe2wiuv5>V䶩٤erdDeJ0i~I@PB -LjBEbr ne1D3|qa יkMrYȆD#Ҕ!tvJʄ&xQb-r @q H* -XSt07qIvK1kIE˽)R2G)!0e7  >(޳}j٢Q(g0:faQ"B2|vNT/N^'_V&%QTDjZUu?Me; -~YOs{BMH"}Q[=o'y9Tp$-j,3NS)+o7,Ekulx$[KZQVd%ǩ=/2ά3r6}Z@-yn筛Vۯ;vm ->MYS9.C_=UJ/b,~2J~[q3%4G<wLɱI&} e>~ Ho*E$D -Op k=kz>jxG>%cF~&Ћq)M]M  .:`5gMR4*` lI+j]uLc,Q4\ b4cöyިu+ӧ7܎k9.C G efr%'QV5}zߐԴ?:47114]WI=MkJbW,ߎrX=ǀUgyd]zH -T @Z8HR3DT.`'R d["C cbT˲8e7PZ>nކXiu'Nl4{9n8i'J}m׉ιŰP|A/{V ~RR#q>zׅ3!>:r:k[qkƛ EHm!BK ؊5ˣU=ulRTմiK1='Ek0OANx{0S3dEZ"uӮ--+9fͲnX'r8&:v~ߨUWz_nuFr 'hUx_On_/KJ˝ S[>TnmjIjYF&lNMMzZl}ޗWM kgJ6-VnEI]UU RjT$׽Q2|,0.Cxs.=D#)):^ /\oV3M9 Eu-7OTEN @4D9 -3f|:!gKgqLpΎFr:߆roʚimv.z&u~XC k"Rt^<"'C3MʎV'-3#//- (EsrAAD3-ǽF{?.Y>q4;N#Ue_՝{r H&|NRMLDCZqI8Tl}em 7 I.jimǍ6fSW/KdGSEe1T=2XHTUr$XvĦ]|j[ֵ.͘i̼a8 u ,{vZ wi}DIҢגim,S3͟'M?zn8ݣjښub -fM{QP춠F4Lb)?׬-(u斁SӷYJO;atby,Nffnֵg'R ~OY-1jz'@Tmsu&x&-UA 8A1Ѹe6Xu2ύ׊Wս$G:Mj ~búdG]x굛FN}vGUvjiX|$mS;rPlRѶ̶2D)H  -(n z)wqԲo|I-llAJ=yi ~ךiU=g^qݥ)b<5s4RzMrE.(^)H!,M#52BwK$ñ.mܾ!(v:e֒Au51ɍ}tuoPKуy9\OLcNږg"t(Ѳ -!L=o g\{U[g:hӼ'22"B6E8\4*42}H%cq_uo|/ݸp@8։lpVTR.*悩H/6|kTN-|w'ILԸsVsԶ=pb#)uH!Rl\nK>=}4&S;M'X,v{F>ðV*Q vޣ:,۪ðE4ysңȂqŪ -VّI -K ?&ѳcG=;e5tCpS4 yfJ?څgԽQFۙ|ĤPRC)sme'@6+(WlG8#3 ` A @ #Yg[m8nmIbóĘP - -hp !UP*AxL,20JL\BZ> \(Zg϶]Pb `3a oxC@'8B(4A,Pď6^NLbLJ\\.Vƪ";NJ@)@)0! lHCP+h -kX- :(((a7(&&Et::+Be:)@@ Ґ4B ``)4> L? tTH #4lJJ]o/DX=܀1t@94a T 'da XB@D Îfp3]Yjsi&/(Bс TM,= -pD?j)>q[4y,mig\nJ6ҬZ01 bPˆ#衇<\^ZvCF$D$RHĪquPT`B 0@4a$%. ,*@hzD&(Q Io4q~Q/I-Z7R0D> @( A=@, L vؘ) qb 5UӰ^t /I/Eׯ[ LH`JT  Z@4&B d5byfPBXaC.%-FX#fE+Rj$Hz]I.^686GZ-[>:Peum*!SHœd<-Y RX's2.)Vna\ -bFjeϢvU.E^5}qO=YV˰~ʩbbkQ<]>-qCP4x<붭ZEjq"|yn "xv7͑~͝M IJ-%]WBv˶}D1G',~ƣzM.\(!R A$vW=C.e}U\Ń| fIizJ}Z@} -fIZYT < z1\J#qU?5yq+ -bSElłu:Yq*OO3\Fjj#=SkrOmcC&7ޣd^9Ve:VJzXE$FE8bh1B -"* eus, -RA}2e:BGԪt5^h11bKUi59 Lg,S%%NJɊI䷪GnwиCD3JZ/^G< IԿ%tO'~QWu<-;&㿞=kک…)Qe#ruN/I Fn]xHxű?Z7HV #=jFZB/+i`bdT'UMs E(}/|Vo~[R`xaNm0'_`RD$!>DԫzN`ߗ4vUK"u/oc5 g!(*Q>7.ú5/grA1- 0"ƠH>p)9N\-=c6,'Sq8@8JvwS o!h\Bj99\v&~C$U$gEb}fR#n%}忦ɮX -u|juϱ>YzĴש峓 9^ubS3>iN/ YrbQ{$$$8N=xhA?ĜhaP+v)H!RX+F| V/Nkk(-XPh@|)1ĐiRFB?MEyr̚\U5?zIhWb,oԅǮ;Vȏ>]* a$*'/Iwt^&_ O I@q9DOchcbC% -rӒ޾PGG_1ZBI .R$)#.|a"0^<΢fU15VX)A1~eCFGn .''Ϣ&l{d2`T<+vG9חVi&ĕ ^HF-ԫ~S1+˨xI1K5򉨡(HF [hq~ȴ\I)"IkG*GI) J D]Y@:hj4SbWĦ AE 4ga"bENj)R^Pt#EL ~ǨL"^''|USXPZzVNE@@Ҳ*;Lb2i+^eR1'3TDb}~g! S(F>aWXo6H1;:VD\D? C9Ӧ20I$*rM] -qL2Cb*f`Hȇ!iHrۃ h!C-+RKh103.OU@N]s,1>~ -H#`H}^L+`(= mѳ9bV(2\$,H5" =zŦ(5;9 - `L$0#ǰ3 -D}Kp)}`@ -OtgSS;Z(R`?pJ#uRM{G - 89hVLX AǏ0Ԍd2j-v`Hˌ"%54 峧@dN!&*"7RDLH  JAl~{1cƇ//(QçM[~OeY|;o8QBEdJ7\P:2HBF||YFS(㠸JHчDjˎY<>xx+oV $n]2/;`#&d ͏)Q'?q=h ;̘?A#u1j3 T -<-,4P^J`Ccu {H/p|HBP &eJ뇘#^x1j B 8 4Ċ bPQ1"F(قUxʼn -Io91*$IR -̔JMh z譐<*Z#YJ "]e|.S#XLJ(V*C2&2ݲT$z}`H|X"EEHK4ZHEk%B >-`-1"\x9Y2 J,BduiZ*!*'Qg\%SH-HZ&?΂SRvz9X5B%r1Fv[Jē\v0(jRrʯn9.b*䣻>$?r -`Ԫify aD~Jo|c 4/>ȤШB.^#Qf!ʎ{vŀhz0hR4ܺgXƋ؊*J|>~5HX6BV3_œw>T)#~=.B5 -ßOnYK5e``L~_۫fjGNW8I1A#KoˀxCeDIhc&k+>`Jnl^N$ OMWL,x$1&*6Tb;ЬeuBpЀ!SxV>;#/X|RRF``wx&eʟ`f]H5T`GP3JBv[JTanp)ޮR*8UA)_}̠Nf0%M̘{ ' RMWB]՚$UDhEMEx"PPl,_$ǐjo==yUѯ )\Lx%%L(}qnԦ,X&.(,'qMt B͉'0""Z$!C+7FP-}5^F0$P )KbUB-%٫N%w%e^ T:)x0kS{[<˖uDmT*%/$(܍'$2ձn{O 鮒+J^LС2 -jXĆ ')}+~=3N<_]qMSEPzq" -h{ѯ.oyN3emIr'cEɛʦS1s\3$s0yNٗ`v6(]]7]㫘eͬjnmRE0E!yfڪeV]H=UZR,3-`Ī+9V?yq29:zȩ^uEVAp/Ǔ}'q#{st>B, Ѵ?MAkʗ$9V4u!owˮY ZU?MSMP<@!U!ʲX`؉,YLt1>tEʑ\{N= =%j\Ywhx{zӋb}Rs23+3{N8b/%0_ïGOEfQve&^3.-vadɌN -_M2RP`H۶r6)ۆ".VH1!)~^x&2P)|DRG=?evnݺ_JMK}~sORiȐRxw56YP軻G1EJQR8`GMT<֞ۻb"I5R>&=/] z?7Mtϫ״~aeoQjP!80{߲ -l,sP Py)Nx4 X(9Jp AŇYCf~`N7QIjarM1)zq\Tr`z]1R4C)QY2noǔFy-)3t>IP!,2U~h%)w.7c 򼄞6I,:\6tq5.BtViR`D"L.RM,s쉵 -M.߲ldf #3bA&tE`g&azPDJBK'jYݛ4sIA;1 8R0-$0!؁P0c5P)@>,H R^/I8N+q (婲IRXnhzaDŇ'B~uSTgLZ7ͽ,}?I WQDJ'6%ᡀ|JRyJ -8Gn?(f'’!GP #`_HCx%F0Eܒ23r[k[$NMX\<,q ~"d! z⣴wݳF"ׇM.l)tdzy dx'?LF'5N,8|$lAY'Lr6ԝ?J&ƒIX) X<BA&Ex"؎ %\( ".z$˼ū;Nh` P,B -؁&-\ _i,&`e1sY_ߗi(8'LbF8j0Jp j`<@0B( Q%$dՌ%h̊<+_w,ߺK!xIQ#Z8@CT@0(A08 | |~J֨"sնDۥ_DT19Z;x1(RP&L@Hp@!0lT $H->fi`ݓFYV|1l||06` _@ X< S~)7)g;:-h`/Ap, - `b,0@FI*;T x>dO}[H 8? 0z`>MA -xh :FHpUx@I1ed"䅒A< }jJ X 5F0(z&v -@BpZG=q 2"K0d׎{|DXL`$GEh p%t^"3J" 7% ؞7hZBft@ -^P@,T+B FjDR;0A?n^2&%}dOpԲ;_?E`QC3pB B\`56  RD`0h %ia+>%.V'+uGˏ)CE=0bSXBX$A0)H -b%@(!:ykP:'7\x@1H4X5HB4a t-&* ^<ljQyYto2l` \HOAX`NX`31-L:jysuO@ `=D 4$L WnT Elk{GȊb dG;M/ؠ1*&>p(< o` "8VBzG+ -XbDĤGk^t!P*Q'J;!@A v(p5 #"UOD -~#lA |(pTBv&D S,C8 at %`<P}tjϑF JKd>&p4QLTg /xʤK :bfYm*Hzyʋ.h -`, -0@K?  - %¯ChdT6?zA&  kPFDЀ@ D -0 r41xIphl|p}7jDx@ -JP)!= LMHjAE,|xȰ c|P&34t0 J HLx@BPc׍"^: (j.#'@6ɒxgL.P |J-G>~'au(8 -Ϊu䆓j agubظK8&@.:|p#12J#0|%YzHUgz#¯H#ʖk-練2 -P A '(Bf<2"@#,'G?PUJ roqƦQH5qk$[4L0-Z_brÇՈקhc::b}_BQxCv8y3f -)zĨhBA1DhCGߠL%$³HwkD?' -rݘߟJ F zA $Xf)?٬ -}rT٧esnjhRADbXFˆ%4w -6Wޟu{ 8qaSP49U=~Hi!Cf$`,~.۔_ˌG%.#er_׊ݒO"yzE:6r&;q2x,Qx6Ʊ[gxj]yչYs td8qfiΏ\`BHɍ R,4>4B<_x`鎺5 If~u)hKsL̈BPNF9]gi_Z%Xv6SޕWN[x4 )Obn;h#zˋI+u=iuGCbdmH**!S(OB^,fRZ0/6w{s:;ijifW<X(-^T2Gr՟_hr߸v:ѷ$Sz7_6nJ0"~ҩCLKeuH)׵ADpX l^\ҴcT,9pg9vO2ݺ(%Nt=xj]ͷ 7?AYS;[}yF2>bcjv QătVCsϧ~pd;n2$m2=3ha'7s%.~/Al֕`&O'ؿ]O A2:)GhD~b*ti[mkڮ":>$<)oP:eƕ$ /"meZ(z[|R 4O4⹒gl":[=W=cWӺ(nIPNz,l~/6e-xcۯh~Ng:ئH\><5veU2U /("z`=#8.s] -u!j+,l.(&qcgkA.LA-gikK0ZdN7@|ug -dm'(᎞!8>a1=mM:fڅ/KD-p:VsIt8rQ`fǏYN@ mxxۦrKeuߏ9KAtNG3ͶLpCw_b`(ݣy8% ީu|c mYi>\R-/OLǣayv;h+jqƩ\F"2ڧim_P,=Is8 -١:(RB>U0y<ޣ(JO|^%i)bX( -_YucG6IahnX_(cyin7ii:hbd(=^WuK.U\ɸDuM1 q!B0lu#~"Ut!6;UHU,Ith,fU8p -m"F&BpE39a@D+m$q\!JA ""sp 2@Uϻ9#H @(Fe>v`)2xrwnR)Hg"0<Ct<,r(̊ȿvWQnMaU娺%lvQ‘BD2TV`C -&#* z͠D$Fѯ|ȱIfvdK*C=~jڈ-6ZY~Z @"&ѱnd8Uh$ @o1 Gx!bE a&B& tDH`Kl X@?xiQ| /M*"*, Bg\GF{P{MSo". #m+?`N <X#0 0"?A)L+Vt 0&1RԢ`ޯ5(  !Ex!3v@(a~Q>9 ^HA##Z a|$!@ ͍pA"zn~ }X۷.͕ۗ'9Kg|O nGxQ^@CE7X5zqRFLe,>bw7ImhY]z}HtOQFNq1T_H_A4>lKdD&ɷ@(B3S!`XF,{h0ϯߒX~O]yxuIHŢyB imיfF՘$]r2b&J!%y㨆 "?$GzKEeNgDB%!~y)O|&UC_S,VX/>3DN!ӂ -#t Zea!E 3JȘQ:-}Qur+fC˦1}b|rS dTk&$kϖ*~* w399CPD ( E41NP`nΥ M(^ /@0BfX,R,`4B_p @G)Xt@Qkvq`Bz|<\8A>smrJ5i(@0L^0׍ ĉá0M.(XB!fPJͰ9IaRb&e+U1)c2d`"յ7I)P ^%! 8" a@HLxԪ(ZւdAqs|U'#]y<x@rYQV13!~t۟uA6$9Nb@}I%v(+տjvW}ФeYWدˬD!#C *yYUIƊɮW #a -Io8ĮޖĪ'"*fC. nuо,Qi]EwtB £֢UAB"BI@ ACb1}VU_GWUN٬FZurZ01!~ E  &5 " .\@. LJф5N\VUiғHnl:~^;ٹ պW$mqL0ʮڕ)T !侽pfUk:vpb麞uWCqDFqinZKUP($QF%RĨP/|fٱesB#BRS&vϠ=6is1yg;@" -թWQ=G lԪKĐA `$bb%r%U- dˑt$$u罬VEaqSL/3B^|ua\J&!4PDh`+zEyZP8O;W^(d]O0+yiޣ9`j~cL,(7JB\yf5 6} 1f #t0" ֊Ja$aS7:N8I^`^RF/r@T@"!r* -2bCE,o(#,) -1d&#aV~ǤP06oY֞Gp:P帺kd˗𾨅Tp Z[qCF6^,Ac RG bт&!.dVPACdժcjyC~=3~R%ˬ^u3&#; P#4/Dh#eELi; LIxE'w(qBŸ~"V-MS"jU$-$!.F`gn2:$BDVm,݀^w鐐6QFkJE$?EwS$x8 ~/(;R(q#x@ - -OO+&9` AT;rړ^WfFV_dt{و"ɦG2 jYd9%yy".'!+`*!VByu}pw!:z7r6fr{ߢ$$)}dJ!*Ug~e/1JX-8jbH@񟥊'۲Y `A E1Deq,; -Tw8{`yqyTĮ$w]6TFVX9M cA0+*$ų'iudCp~ume4IS(b(dD0F ȇ/@.X&&N>*IHY)M j*s&I4UslUFZ $OO!*H{5uEP8vIZf^A&*Bѓ&)2ɠJ,{K7Y0ʤ_ -C| i$"JsAE Kz5UAdmd$!^)^C$Iq8O6RDF BZ7"@3㥥^G, ;u1DJ7Zb,'Ј'9}vt9dP4P?B],[NQʪ#V5l ^_#fTӾbe 2!GT!M1r"jGV-+ {ުm"m8'\}m0q#_w!}v hI .003-* RCDv}CXN'%wh:H9im[LktP:{tn:{c vX"+Q5^x\ш{[>U{tG2:`\T_ܾv)vzI|-,2RPDʪVV4E7%&3,'mup?pk0|񽨞}ey`X-,*> Zf93/GˊLSa9XƝ9OMzImfiuv98uKj ~a:.[F=P1>$`G "h\v\L'^/RNq4->&crmo7GЪΠǗ#M8]IIE{M%QpI"E 2hnfF&JnCB}(IŚb¢VUsiG5RMk/@P>NOhT|ܸ.R̲ʿۨ6b"-TR PAX@}Nf.GH -^= IT<  - -kvtTWz,pͳ̴3Fg,;K >1D^2'.RR`mSJC+fW7(BjRĽ1&0TH[F2&?H\/!˞IjrYQ aDc 2dX#ij0b,t<['n8' -jUN ǠB>dPzhSCń"tH -ʤ_P89)zMjב&Ez َK-4 q˱; ,kD*X^2mAjZ ~ *r_Tɤ[,R՜1(`XDמ]ꖥ~_jZ)"2#eR lrYIv68r*-2)Atx9 =`T^x^]* -O~ AP8"f[SVw@qZvp܎x-͠,r:'! -]fW|[.i'-l>/[v^E2>) -:KI$ȗa=nO|؉Fų(==X=6epIn -`Pp/E}_Nc7YB'r6:ȕ0+#)B< VsS9<qL;X1;Y[G93 z?œFZH%c||ȓr׹ެc2/<,6:lG2涾YzdBN-% !?r }\XB^7ւn_wRtE=}X1#ȇnM䮱IQza%X,:hu1ղ-g՛0YE[V{kQt;G%IEÓgQP8yN%wM}{=Or]'si׍`8<몟fI-A9IT~Uъ"({u?z\v%&۔U7$E烙*w돚R6 h~2عw\mYZdAfiݫu- -nQ[eK旤SPA7*!:D\0<-{;ZRtRc8bۗ'ME\=dhZKT -c{ވ}݆jvl1 SlZ#ïD*jry f,AjqѣXߺejGobik3f&i'vnֿ/6AmqױZ9G.Ԍ*X Qq(Ɯ"ŗΠ@-F\=ϳ80IA帗$qe`I0~>RQ} ok.j~ѻO5@Ȱ0a15Iiͱ#$ '$ϒ:{ۊP4PhUˌv-[Md OAjh5a+aBUI'j0I191Oz"\q%9H{qؓ> d+LnKZ:ǝDeB߯=`.ͤI:eO,*]RQx<&Y.U.h=ajԴ֞%;rUa̚_|;YѣEձ  -?$S\[IشĦ|I\`m"-!5 e܂qj\$Qg|c6h]ݬo vwd'RhECv(3H^'/m6Q5*-kfX!]4|Oo{5z:P?)Eel6}T=Y:B+>3X'Aax]z۾So{zYmkE0R H5O axavnT5iɷ޺ܸO׺,u]shEG3UT(#ѧuAʣfhES~+ofwGQ$L?\rtͯ S7E\RGES+Z$q9z@A9xvGڣ>L~ВEǦŐ\PbQ`/EYn69ږUӫ8K26 $UwۨPWa&Ԫ"ߚuhndz%)EMk`qgMYzų{R='ʞ4-ɞK0rУAoԲ!>bWSےZW,CzqY9zY穒c nZM[>؃V-/U_l*-펞.$gqֹG%)]O>y AA<׌cr@feQ[@%~WϓGGU-xΟjv1E]z2DY日 -,ݢ,K.;Rwm;;4[trLS78n1DZDqb=iXR붝N.zY({_]utP.U(=Av2=o8~(PYvMsUTSQH@%ˠjmݣv}ڞ|D9>k4Vڴ×tUK9~}ic~]])IWhðմ^ Ol߫Z7ǖX[xl ><+H?ʎf w ~GPZoJ3L3KסHAbv{R "lEm\l zF5npHJrr=g]b(b,}=]1;JIS%X$딐-MĦ%K&sCˈGwpECI+:.߮UqkK,vu8ZlE˰F${ΪDm?O^U?lkOrn!z[&B侰't %eHJ_m%ȉ`uXMCflv_{ZtIJ8]'s\.`%4Kh?dH|&nh$$<ù2iEnGP;'VfI¡v=iڟ%.v n14Dyr!aez}R+"{!ZT9n-C+e;;`FI>h& 6R"~nv94E]1jQy'ղNx)]vYΜHMI)zٓ{m=*_v؅Tr/C|~V=xxvWF? -~Ytlˇi_-ySmUSU 7meAi_o%-+_HϳE]EAlU:Ԯ}z%ʯZ2&F - -f@o{jQYEAtH -GSR;ء (Ԭ㳬K -5za -W,)o銟u,gcZX0VFIyz4Ӹ#e 1X>G@eubMMr%|Iir[ ^X5mp$8%ee@,]RM,keۧM ~V}Q -}Q`T՞_ǚ]"fXhb2^69ea{N ^p#cE8P˪bwxrUSb?QIsCgɗ#.z'4U r]oN3X)UۊryS$0.~1’"\[H0|=5 .fU}Te#x7b/,Պwc>Ӽj_,_~J)KѪUe(yiiF nR6$qr * UM  -趡D(n3-:\$ˏZ7ˎR6P?BI)X6 SˣKGWK(]MDW>ggU{sqBC &R>H!q1>p䘢r:e*g#w\ -fKi-,dwIgejˆk&UhuaJ˂d endstream endobj 21 0 obj <>stream -"4o -+ ->`T~;FlN)K.]{jC8^c$A6Qqg&\EmcЫ?K%?y=5[[bS9\uVTyIҳ!`)e$M0۷},# m.GM^[D~kS:^~?lF+;}#w]^_G"5X` N`7u͉\zo,mk38y:OqQw -)ehwe(^O,O -]Klړ!~:f9w4]%(EU.EaKRôùC0}YV]L$u=oi_UMGR3 %xLwu%6 ccPtgʎִwr ^Y(΄"XBZnn~ _x%z)\8mTWw۔q_ndw|esM.>PCEoX 1D*r{rRBnT~5s؝E]_W̲\Ī6Igv:!6C@dմ AZR׹,CAP -ʄjYq7o m}~*"ɍk=*e,i=C k -~_je=)zN/Z6u}tziٮ+#iL(ǃUAٲe&_GzY, Ńcjf.ϓsY تoʺv^EMxAdJ!ܖ -ms 3 U\VE+CevDZEeWݒ^tJ-dLaU V eGٛ%WF[@U7sZ(5Qtox,4X君&^=ÆHEiمۢՌn|a{Smѝ߫v[i- bȊI)8 [F/nA*ʓg]D3#=dGɒ'CÓ􏢳('z[7Pr]϶ڶ)KM>~,&Y,u߉" --w_?4]mh?,q)g3s~pm4=pN!Xn$"d'nDcJ̥Y2s'"`D.ŕTiF]yN,zϳ/,Mµ"-ټƊە>KMr\0 G&9++nSZedDU$}0%eS|&!"o 5eB=P^6LX:LZ-/0n:*1%vph)7H`?XLdDMhjgICnei=_k5b)-Rʿ˟ekNyMPn  !c[T3>iSD9V=Rb6J^/"_l&z^m/Joh]PhIvuDj̮0 oH^{L7KPj\6Do+S,wo&mv|Yx:ѕyVZ,%uj5/5s<2#$  ˢaDH-=]},mvvţhYD蓚;yQԦw-MOMkX8<q7I*F (xm,^UC[e+`YGEdz*1j={"~vq6m!Myђ6IHCjʐ<2 }G9~x@b(Z˓{NgtbNJyOJ^양քQt59ش"bԪ@xV <{$NVn@Lz=(m:Iz  ĚߙTɍO[{]upkSp)IJ@xf$ǦxXU&6qq;ų#iza'r%;}jS. ʔo(GrԦ=Z+.JI݆BǞCCZ{m^ZPFvwίCxARn߫C9z¡w[T?9wRK. !=B69m-U҆ -I 3Qx{ǂ^~!^=qU_5MZ"9AOZYN0 4 jFI$9x19s܊XdCrԪ\,h-aR#0G==HZO6-dAP*BWDKCx^L"THz^MUsv[Lw2c"l},0N8x؉s dSF]Omڒ]mlqp(#52@l;"x=dE,zNu%ib hXvAAKw$&9`d4mn\DHNV3RHF|Oy2|!"QSFA2b]$E So^R#|, $nXr?ɜ c:Mcd3V!*j B=~2#Yʋm2O>@d㱙!à -qx*~Y|ȠYiZ|o(䦺[4WA"2SudM> AR -z.Ð|6m$Sr۪aP/B%?<1,TmX^ZuĢ-Z()VE0c?Qf`e1Ls/\v'?EX8iq<2& gWx rOJ\cvlrUhۗNvIMU>%x틡mޡ蛧If4X DRS-Nu#5m)t/- jDuj.>ov1-LbvU UK+٭ERʠFY&I,R )`7eJJ73)Zr壏׈`N~Q~_Nj iDG؀B䮦W%)nSB~Jӣr[aUUX-afHИXHX1 o`@B@ D.#O -O#fz\6)`$x0 ls (AY0qޕ1}L d'xA5O˛HEIJ^o4ӗ2 -bkPjjz/I6'ybYUMs59VRb8w -.xdjbx1uvw,~ejS ip&j n4zV9DTDIIhZ%Jv*i=iP $E%E)nY1>rlny`Å  *%1<ѭKfG,AbVPi',G Fi+XA%:E |#ˈEUN%2 ]e*ozPҳ?Lnä %f0Ǎ&x:NjJ~!^(#MWJ~-^\RM/^" -V -3* H -.Ԉh-=\Hde@)A0Th`zޯ -D%iYH -fqpUQ.K^.j#?,UKv_9KqRav :+[ߙtq֑"`ZD.xe2u11&=ĈH+ztGLb>Xb;XB~h!a}B,ڗ@6Fqw`22P vPca Iݑ4 g>ZH^l2T 3b*/V"Ð~OrEUN/\(VES)%[ +h1MO_yY{-$m9&b5z2v]<>C#*#$e*Bj" ZFPyŷaB<ˇ%oS+zUͶw!„DE:BŠ*`Q*:(') C<E̋V{ړ%" %?ȕ:PTAČ:3]Q+#r %,bíxs+MZ5Zn5ʱ"b%ňE -] kpE|$bIk5Aib)#0xƈ C \HhBUUmË &e-W}ɬ -V̟%T<$RN -G FǤ]m~U@;$6e"-Xrّkގ"y(=wYR>xn蛣 *!y%eد/ȽP5XPJĕ,x)*xRjΝvQ@ H5Y>7fB%>%XWV @&/`~@)r~.aF3\̠F*;zZxi2?SLɳäۦ7GI )A:hӞ&5-qQÊȍXJ~=B%f H #Cp#%f& igO )b`2W2+/:1VMK*cBF,Gи޵_ $WmLhCK )Vx13 -b" GgǾQ% FL손EJSt5@@1Ȯ?Brbc@@coP}_}r&rӧ>]`.}8':+BO lB 9sبf_KϪӝ~.vBimioh4^mx&a5Nvs܍q0Mz;dn0՘'[dWǘb \iҫ3Oj܌9͚&8IQ9aU`Ⱥ -f.sN9H1/kED 'lD\8Ȝs,$ L5M 6n 0u%kmBrQAzqu`:2Û8|8gp:LwGtӚ71Dz6:LG:anymA_J(>A3~J3=m8Gn67tes߀*ӂ]ͷ:XF[e j3ܥR?#uFDpk.qpǠoѨ!X)MhX Vt0`R2q37P f` NGH!oAmkNNKghIPs LeMDw<&h)a/dE^aw!P-Y*?Bb̼ \h+EQWrWo,S ()oߌ$~)0Du ukn\He#ՀܤP7c .;Iym͇TpEݏK9{d -[X%SWt]0:G -ڈ;ʱeOB@B/1mYf r'̜TaIմLu 솿gd)mTLF;5)?|;DH85n#CWl0İ M9xZ.$M}laW-@xNJno|[bT-X^XMY%yet=+XYcG 1 -G<ȦIktr0,'=6J''Qm[dRMֿ:NUS#xc/2\5d  _6̍P-eP1v1W0BV;:uVZ*S@몒B%_?&دVP/db>pZ}`>׼䞄naGÌЭ-\ !QdH`D d+WaOcWp#|dEl];[ڡwOwFp j&%-S巬j~QߵFE9dT9(wHg|q)U< :ISYZq${Xbcx:UA81.]BK+o";qp,ZKe8`b@Mb20d +1̙*:0vq R)5_ũ#ǓՔcf(NC`4ޅe9s򾁑JMebáY5A&2?&:Y % Py܌$G9[=YI*wǻO2 旧:Z10g ZcA^@ޅqH35Jtꓞ3Pn |]nM|ٌefok{$7ǖe8}L[ŏ6&'^萼䄧=_zImG eqs` An/gAEʿ\*H!.'Q ˭՝CB  \7궠2C'ZW]iRtD0Yxk6O$]X—<4pU0uPCh S-ba xڶ/5$lX 9I=An帋&_>8M,QJ C3xO:u6^`1vw -80es>$@J*IUAh~ {:tq1_cv[j{e֐ +/QQ_`l/I/ER3g?7(DM$^mwX?CLuVk գYI̝-#ZX[& BPGL?,vDQ;[{ළ `ݡHh#ᯪР~Cd9̟p :RlEx}{heJ7Mx6+G;ɋFG}-& r{ #Y+@C~,M+iҏZrDK| lUk r5tvsևɚV<:eZKB%X%=6 E 6:ӐpVcuDJuzSX(![xc1il)0d)q("ȱ l QTsqȑOh~0cu|sc'<8CvD<9}QHVwTG1jm>'’PZ5*]AYmcu~wYgӐc˛ѿFJ|QᙎUφؓUJ! |~ 4R'Vڧ$/1#aqfu3Ȉ^ݡۣ ͘d6S>*:2ִv))&!3wlB)E]-$YH{T'NMOoT]hykQVEu}.!~T,6! }+`ёkpҵ5f GVF=cSFH,Ԍ ?AԴ)錾6SΕ8Ȧ%-S'M]+sg/FȤ -dlKL/ColwB]],ƬE4n8fwh^я>S~ v2E,&Cg--q' %(xKFvbdH3a>\wH\v틢k{Ac:+{Y@e~` wZHM^neaZ[$p+M5$ WA]f ƍr '(mdo131iۡyLA7#@RN"@t`!OD:U0 T sU"\]% X͙I*1PrK۫ YEN3S" *ǀf;BN"y_ -( FɚW,Jy>FJh*@|DŽeDcڕ c8:-b|T< ֻQ.XRg ʣ#0ǽ) Z:ug:- {@E`$HaGc hǝt+Yrt@"XM2g$l*bj*ѳ59W`~g/gaTeP`KGmxl}L l~,24MH^,^όI"3%"0"eTVn{ztNDllqM ,xt"b1``C@@;2XcSt+>aQr\TD*C2g j|vIO~78d'IJ -jԟ\ ;%8#䲙RAM!#(.vKYB :ˎoG|r -Ԣ=PN<Z<Ę=*´Yg$L)ShO=*UKd1躟*xOh|2 -?nHDlw(Gv0ڲ33\40ZvNӕ5gTuYAv@Uחu Z7vE y\Pg)_ƞ#maHG6I#)|oD},B^t`è8J >e"*yw0C~2S)@PZQy ^6rUr0c\>_K79=YN)a+? zІu{)Ʃb5!(Ԉ~<6T{ŦJtS&sZTy[ g3"=՛Ʈ_\h2/0f"&ϳW9 l1tU0- Iu[" =rd)^?8&]ዱH/Z^AHAZAgPh}DE[R -FQ4$[۰ -Ezrf};Sk6"!.}cKN+CUwo?u!3yI AfnPH[?L4n@ alWQbg:LVX\-B~O7 `< -Ozz쒰[3V(IIֻ`qlG- 4U{9z" q|?+NX+vUgI56*wĻ .[?*W,I8䛰XToaa̼Voe&M|jMl#\HY_|Ȋց©4_B3͸•cdBԃvabW/~yöIZKo(ℶ₇~znvx1TTBw"B]JO<-+'_pAW41[&S΋8ʑCְ%EJ(|,hR.Fb80s -8 -FۏEܕ,{m*d$Ɩo׎C!W?ִPhV"[_Ny=zMvb(#|V;D@~b! 8ްn B2E+X0}C<l;=8PaA9T;"]g&=|՗K">d]fxH8X&^et׈vq,Z8*V[MyyK;@HAÄ́@q;q8"&Z.S`mȈ¨MtOA;Rj_~ȹY@=&Mް{O"Kzr2i --vBP4|Zovt5lI3IhgmwqI @lz|jK5df?x=|;Nm~l8A{4VIP7C) po7xAfnc 48}xM,> +]r kw oWb|)3mP DBN 7щqԱv"O,ţ*< -VCTB eYY| M2vC\6$0:IF ?;ijpW|p_ʚ}8«{gd.UI's^̙mgE`R8F91Hαf5,!2\ڑҽ#rf a(HXA#5=i`v(؟*bUyJqIe'>325Yvb<{Mu /Dpb8 -disȠͬ 5yڋ8Q,nR"^=w6 -ĠS$/O=N'SԬi5/E@NnOsÙ֫f -<-ɡB!Cb.((r_0PM !%^|?!Dz.r5rTT<SW!N\{Q͐ 4 hkxk97# H3r :'v;S?2\%5 ۨΒg KJ{JH-ɩ4ADB[b&ƪtʷ,{s]D>垚0" -M^}qP(iWccBh:.G&_HM5?FCJFWR$.><$(qsLD0{jr= -_,JIDq5AYdF.-~.4L MrECE]}^M9T ɮ~@; -hdsP[tXC ۬gQ<̅ܯ¨V2EvRcEq$bh$\ǡ ydI *3[ -'~| E__[߯bHZ7 -) ]ኦ Wr XWKӆ|.ΌIR.1L5s)cMTp1!9R&_#[\3v 8{;6J`9\or34ثd֌%H.6U ~S )Ns[oغU{~xt)djf<`{P,> -jx?P,Iȅ#"i"24MqX ](+n=oBJSٹᵶ+=#R&nL?6sG:oԘڑbB9d6ta Cz#z-'ơ`3YD -o e1WCai7;&f'=34Z bWܻL|Xw%Z>%3'd@@H -SEK dD <@vT(  \;BS4xuRSVG9]>5_x}[] -J$8_{x~tN_1"W8)dfdl ; фICo2{ vFt'lJaƟ=D(Q& 蓽g{sFPv°iZD4aT"a=MNJpIXMPˁ! hAeN]6 ui82; ąl4y { [$>\Jwh{R7!b_2+d20b3b75-42b0-4d97-af42-afe4fb28f5ada3eb8ea7-108c-426f-aecf-c5caa6b61b94324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulenc;children/baseFrequency(0.052attribute; ,numOctaves(resultturbtstitchTilnoS,feCompositinSourceGraphiinopeinwidth100%objecthxxyyidAI__1id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-20000z-5xy1ystyll-color:whsurfacespecOusConstant(Exponek0k1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.adilanbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(77spli(1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 5PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre1100011.%3#h -A4TP aa `b@! ٭p>Ѳx:Z`CAttR4.JJF 4]Vρ-0NBx!-NA+.̐%dڜ/~2A`uT2)^֡zitOwR\ɒL 1z7P9Ggѽjg`d0%Uze7A|f\'u⁔/%EUpOM!m@}ˁFĹ#^d}Ézdi NJޞRQftpPx:t(#R, @-oԤ xأstBNʸq.DcźceCPsԈmDo"z4N^PLTNwǴrRr$ÙXPH,sID;!,ųjȱAYbn{{b{;E gRQ.Jm -(,R -@5 (¼ˀ}T MohIφ=CxK< cuiPaM$i2C:GpXwv]TW^A-űɑi0DI' FD#*9TggWP.nTr -\I\u < 3 f8~ ._G8_mpF`Y7oSp,@_=Z svR DGƼ uT}a3^` A~7܉&CTlu5!U$H-썚Gz폸xZkBZ} -SC*(`f8N1b)&h/ i\1`xK`` -MR̯#,鴽8H\pTDJjr i*df, GFF <#:2:Ě v4}i`R_5<5p LYz#O0 Ї+:mJ{.Sف2^qC P`<Ȅ82y+>_Cg¶MUD@zT0m)HǁMb5uEFV2E0譚 p-:0nm +?~kB#(VvOkZC(&}A^*[Ds Z{N\ύɎm2+ЬYXˆu_4l)Kl`0A&,=b]#!,Q&\3. AtH㠉7L7 ɽ7)+P/q MQb%Q Tuu8%0 X&a&Y\̫+H;DT' -2HZAOYq88#!rNIqe9k 7͈eӈA pAܣFfҗkr5rKȅtFK1 ©ōWg$XX]x8(,uIUvʘrF1##%q.puF=" D fF?#8(qCJ9M4JAt$/<{-}.F8`H\}:@ȥ 'z r=׏Ågq$%߫ӒDܖ D6lHȫhǃ Vpߙ}T)W#Ȳ%K%8ȩuTs#܃#tHq?1 mɾN^~M?:st68 LP  - A ,BP -Lf*HpAń 0bBD`ƒ - 0„3B .HP8$ '@GPd(4L@ - (PhpBRJ -(rߨpkJ2J/(!*Kp`Jr/-G)/^iK񆍍j 'EmfNoOޢlР`ЎmZ/ lGEZKD V,#6 -[J>&h0&J(`  h8~ 8 -8фbwuCV -BBHGJT͢/%at#bAGH\0 -aKk-f3(n>b|"8{۲ڨta pmGutsys!NnK]d:qi"JcnC} v w!y֔#ĵg'^]9W5(%ba)š^{Em>(gNQ(Fa7Qb7M8Q" Î KyOybO(FFI(HOt$SJ=QGy0[_ҢQnStXa\qGQt˝ǁZRL  |[u3+2%ZVZ%%FJGkqn"} nse޹z3by1q2U&GUrx%?Bd+ZM?@:w:+#d99DV*ng8<=¦-ə6-8UvڻNmڈGJq0Q ͯb99}Pݺ8󸀌W"/nW@)3>.g#3793<ҳt?3 J=җC' y\^!yŅ \،"8 S>M'k&kiv8#R5K}heut|= vm{-xifV7VӻeL]˴[Vj[ Qn__S6.Mb   ,H "P$!$  @fSaےN<ٹF*lc6[\M;lšKxiSã~[;SؑK׬bLz箬FVnzV\T- x(yqIGB9J?won9v[~$;)7N=G.tfezwϬg%ŮU^EolMe^6 f{lsdS8שo3UYuQbτ-FU[- ײ_PGڮVZ,UĐ76ȓڍֆxUn&dB~fJhBÛT_g'EybH<a F!wc}ʢKiʗS2{;KQ[!jE و jl%` Ѐ -"@h@ @@4b0I#,ݤڤПzmrT>Fэ~ &@r/5, R,F ;00[*䴽V"BmЍܯJ̱HQAI ?=_o6ݣ}{M sI UUrTG6Ba>n1ETh4sh$#Xf5PǸD'ً{g&_qX(_-/yu^ =7 zo'RZ( :k!j!z}x^2\~Vn!̨kRbt*gx;tS?];s3U~. -b/vYXu -eAO,;2Ћ3|ba~%| Pvjg9{7\>7?hFtP0X@h/-VIX~F  (ܷ H>`IEJ664; $A8ދH1$")R]vޘ62)`lwg;ߑAj A42'pIR/wb$A9̡6GUoI~U \wܭDٺORƲ+yΙPeO;_!Z: dsZjҖS #_YGa!Ozo};4W4NRH 2kƼ GCB05uSQ9KFmY1yؑືo( vʣ~ڏR/ aԚG2%d#Ayptx5KK3,Uܖ!qעCv*^ m хHǶ{I b -9YĎ.&0Y͔pO'l&3_.{0SHuy, z)\ZIuJ-#L_{>&lûs2Bziɑ  /?_ee/!dUy5aVD2>IV9!d)]R[Uw[87 HO[O+Qpla)va$ I qYSU'~&Ċ'r..uQ|3>^C6^i%5/`L2' '`b86;)Ppxxz5yiL,6!P;B\ -2? ^a:-_PCC/ؗ!lZ3$i@ /RsC]ձN*c0 adldW ~"&er%:֚D}r&#xDAOl^6|3MJKK}״NF LfCYSr!ixY<~k1\Dc -mTWJwtpZ`Vca1L(NbzgQ_n%:}AvvQU8'M)Χ'FÂ͇f< 6 EL &hkl>Shn"~cWVK47YnU_NjfqPb HȤzm>۳"6eZ`PU_E9YUݠ2@nG((Ӹ[^OL9 -Hj}iSF&]ZM>,iݚigts%>N'/IX"#$_"4 %n; ^2h+D9 -I)VS ܋Rf-p8[uy%!v&:@vmkvE+]7p[X kf6ewWdipi|u^?բm(vdAI'UaJP;O_,YS]C)GMk2~eI1LB!*|W(BXn mqǧ'h_sSD f (h.8LjDi-:ew'snG{hk-0 QwnB.j0blTX@=ikvE0)L+hUMVEڐJ`G %$-АEKL8޿+( )b7o -Um*Kkz|Lgm2 fǰ%46{4p77:Rd]BZsyUCFL.Z_seChzͼz^J+o{|=֞reCJJJ!n*n@ K՛ ;i[M~AQ :S5Ͷ7ciy`UGRdZ<<`Dh QI2 -)Yihe/FÚowKx 3# F'ObgXǬ.r"^pv-ޡ(uᶜ[p@Ȓ9'gs{o;r6>X&/YUbfk~LWcz맳fwh -%p@q@ mYKMp/>k -|<'lmo]D@Ar?O^0h7ePZTkrXSLL@jCw.ڶV%KثcK+Зl.B*K6>ѹl/; 2'KJg l(%[lY]#UN N]& ,0f x8V*K,m K lu f1 Bb~kR့0 :,p$` GG\&" W%A0yKH("Km #\#_CdH3PI+!ځl+*D ?X2.z "ZG-7z@BtP& -:aF@#yxwn:WӍq7(;Jp4R23e<:W_wގpE6Q48g)d3GҎt1:Y%(;ƻa -YC D-!JPP\[JF ->*Fм ?a8P An0+J,v!S b:|=;:JWf}vuGJ0n[Jq)Y6/4/CW7dӌ ]xƜ]u cGgܤ k4kH&/@jH?tXO E(~|ܳ笽?} -^/8QiEWQYš8|'2bdW[*{c6 ZP%_؞lS_CtFijjǣ`4P܋8рF3q~ 3J$Erӂ$$a'[ -%>ĥyB}*-`nVE ʁJ&b@Ԣ0ok7,Qag OPi\󬠒"g9.n -&\Bap\ljZ67xs<-:Z`&mo: $J8wBztnWg#.^UUCR'{)?.d89nĄ"t[u5?AY#q uug}R1՛Vp~YZn!S]u]sLC*74\kX4(f\wQj1d0+!e\0(ۗ~m\[T fӎ"^%, C9qcCMgy{GKQI/71V~z%]Tܰ/36ˎ[\9b{\K<థ_  %'eCSB" kVU3_{tog6EhYׇvrYA)) -qvYc9^*Uܬ?cDl&TuBFژJy-ђZX ZLXhp8%"Uq.TN\'汈"ƀI(0(y;4I Ct#:F꣠|atBʻJf5 YUzŻ6pk& <<ӦZl_CW} L]"b= I?X`")^~W+^8f5DX|V,(Yes:32NzoԤLsSul*n("W&[6Nw F}j|V)8* `Rڹ.쩗 `M}+Oj OU|.+d.hl؞gA[AͺbhL5Wϥzh[l ¡KQR* -hYs~3WK%Hܯ8VRus8s*  -'%y@qC]Cr?j\5azS_~@AKpʍF)O9& ->[Q1U;tj,W ,x2<0!, 5&<JRεJx -de)B*eX xhM"M9Vo-OY;|.,lTtWNl5=I:c̨f0Pck ^b+DO@o\֗>76+$waQ$cL9ō;.SE_|!dT -zYQ$JIV'FgmWӣ<|;k@pzY~>$b?{DɱhzmPx ΐSc/6A0oȵMbC>CL/\i& T3Aܮ2w!{~26C1J-xܸ*3*o K%?[fvN} $L< 5!z -#Q^ N -t׵KmW3_NDc[gLiwT.K(GoGh:v6ptHQ&SeK[,'Flm8wM]^漠ڻ<['64KX~f2 D ["ӷ9%`Ls %ܽ8BK={nıoouI!;.6BVV桤'|۸ygMM}΂ÆV7mܘl(j x[s/ ;9kE̯&gqq_ -]GB\\XglO|M[yʶ+K[q -m`2k{0AƆ@P&Zdvh5F! -oiHԭ^+2(),1#)Ԍ|͏N7ҌD -"N$2~uD B(Ds5S9}!U[x4opke$dhOR 8*PXR)T6֥ߚG%jQrGg`_G`4əNA< f3Q& -ϺBq .ؖߜ!hس5bCP18%џ[jKIX]UKtT|>mEpY6SfK;ti -|@v701cbv="z ?@zk?BXL$A3ETd@)s2/Ѫc*\&(GӬa:_+]d`u,䣢bG~uka\6j1-PRAZg^*]>)}_t i^i7'up!*X`trI׊KR'cʚ=epFoq .- ͐KR>k_K Px7ARA?Hr -:2q8~=C8Rk^k:ڧ=Q 8vQW9f-~7h2#)=ijR$ŖP.*?4IlE**l0hyIu(M0{= ː.S+twĬsn-^tV `DyPlTٻH:+5~zw% QMoyb߱jlcukVD+"bSE[_(NTfBN?^>5_ӹ\NEGZY Ǜ*nHMlĬ P#6ggbpݍ -؅OXjE|~p/YV׀X<ٵ!6ud$F-("3єV67zJtpA848'ƌfO $yY2[.FEhE  -բrE:ԶqU:LT+Śn `]O *}pŹWȻ%"Τ=`Y[:+GLT y17VjɔCJJBZՔYB \ұ̠&Ks1m .o@t;K/1Pg-ŗ͎:.iIN  Y'OIVjP}1`w8 <WDm@z\|f {'xd+fuj!4%v?Wu F"hx| Fl_V|dP-ko'FIMdAfT%f[ĈjzZ;dl7hlnv>m*&۳D -l- I%ùw5#Z!{.F' >}::?#ۧV;'2w}ԣĠ]I=7$/`:F% (y]`7c$,g<D7 L[}Ġdz.Bj5A)q-|k4-|XP™2+"e<Í.N>턂>G2DPmcF>mV;>0ȍ~ƛ.[?#Տz'~ aP&~^{6|qOɫX;` g'z;He j*fs{!,xaly S+\LL ?di8 {'Z`d.qF7~_M$:7w}#H zY]< 3 ކFT8ѤN#A8wu]8d߆x5·lZaEZ bD"dQMoHT"װ._hXkX Gu*'繓': z?-i9?I 9vZrw -Õ}=Aj<&ޱcӬi=;=$KeZm Okf;)FF;3*#_F[mIШ#8ksjx^/LBz|u)’MY? [t+}N|e}vȵH !IUi9 -9Yްhkط߆!W 8YqHPWs6_JقNM,^Wy fŏ`2\r}*J)hγ ù~;h!IzO5K@{XLlgtFԚ} (et bNw[Le3e/n@1PWJ2>ª!U}1qv;=Z魎Q#r2^/qg>f3-I?g47Tb| #z^j<+G؛ *#\"7IWEf TԉLnF'MNvP }|3DAVbQ_mT>zɄUM* -+ dw(bMc(z)(hnu -s_Lk@Jfc7s:܏%3W:pfMtPE($qP>b 45kod߷,0j2⳻sREg }_EJ黴?ƗY8B Z&{Cyf)Ar\ČAHmxLRZyf4j2Y^#NZ/`!wv w떇>jY)06Z7nDǠ QH},XjjMݟm5H%s \$8H-3K 6ޫh3G=jb9My5 HN" -jjQR%X Zܳ9 ^@OuEaY Jm4v=z5~ڴ$R K>fV,yPT5?wWhP\@eK.دEݵJ/Ω ŝI Y*r! FMm蔈7|}R7)>DpnH>`:n~k试,;‡#DkɏG(!_R:*k0sҝG(woikJQjiZ?%ՙ龘{$xAq]zVj죇A -L0DOUjm>4%ڗ6~9) YCqZ<"(L?bcKUJALCgu)@2 ! -Vn^`|Z6D -% FZ dhZ#2w&53/+80G8zO,Yt)^sќ\0ZtVʬϓ -xȠQ5La'|\IP}e%1:oEP!31b!)sH ڢak*?|2V1 Dd`u `T x6H',Հ֬iZ:XC!VJ3pT%4WͩYIs](%*+U'32b,ؔ]yDv@xvxi=}Sv>;ǤC{`cۄ rc Бv@<6ÖH|]VK*@F5-(t/ޖJD~!Ӌ& ?s jCݧ'[7;d}.j4Ն*Z?]DoΣU\1WZѡpXQ -ֲr:>ՓAR:8=qϗ8ISI7_/ӊy,)ۣD ED>Z^śމ p$ni0I1sxA}xM3P Qvj-:mDw}b -.:<"Cüu#+_ `pDWG  Bnn|I9ZpCeR>ۇ$66"%ȤU3❣ %+*2]$}+ƞa>Wʨ iE ME *eh5ƒR-`_J@#|5GlC C?_E~bohx>zD-k_)&D!q/&8LM4j kĬL&5K [Ғu݅ ,"tM(&8W%0F]MVBQkD*.n 2Ef^͘Q2$@|hQΦ;pJ -94) Ƿ91)[xdNtxeA 5fJ3eW._pz򙰌ϊ -g>D2K&42DVw͚`sJJ;~b2 -{|}u~w}2dA@449G-f^-Q/GB{\Jo ' *GuKEg.{LmnځxS7Llrn -=#KӨ"µWV0G|MFxm~4cHZv|񸍃5:Еkqzqx >n -9P(2^{#['%?D ?h {AD^]gw₍X8 il0.壟#G}$p3( hXY4=~-qVHfI~̀QVd ljmLsaC&]rZJP9]KYO]#1`[i|49A̳a26!!XTh[R - -L6H?{D DWax+(D0f^X䝤 <4z%f -KXrH7f`<H2'695ђ'(šN61 N§LPFؚ&3扚j0/8&PP'#'jÈ# ^.Uβza']8tM慉և2p]~Mmv@&7r7TQԣc"#).>#] -x kGf-THT[ZO!lrzgUkۓ-B?ܒ!U -Y=DGcԈ%Lҝmꟶ wji-5gc4/"IID;Ł;!He~jn`MTvi)6&;vEϸ UʑI5*1bXF&#Y'leJ1x^CDpv?|خjnS6lB5VJu7!P-M2VMWxÎOuɦEAͮnJCcX*@63LJgKa'i4) -my{.:BT*%ڮ>B|?ÞMh> -[Boˤ[+ƫch!!?03`I}7iJu{yK 5g7~cCu C%mm!Pf - +K9K5VMwŵE1./9TysxʤÃvY -#( ; T[XvW{_vL6`MvyIZihhcX Aט6‹|(W{N lxqR` "6:Ǵ : /|l eG\ؑu, TTRv3.pKvTHdj,`e䏑`?Dh*;rwTJ&AKOBXv>مN=Wj0IAN{ -e -OI$_P(:o2 bO2r/&\KNαAm!źC&tS\>@0q:c|Nf"M?co!B?#5<)2ʪ$IDVM"95fZ|!H$2atKJȼl%Կ ]SؔVUakgPnGo耇xn.n mz8=^نm)rMpیIs!|ފ ?@cP&C Pn K:/#fW O^*>z$$jt>j: -!Z:DN<Œ# z֚Bqp2";Ya6cpdqJa4 Mp2(?Ga?/~K L f\"Ծ"> 2dJ(qAr6L@I0ުs'FD&RFR#+CC@9,6c14')i-ppf/H)űXzArQQ%` ws;`lr i4jF)|0dVmSM*j_} -UYϿy0gҎT0zR;\w!%}=܅%;^@H!X+v1#qа|~OjqxtM53}F(}=G<<ƝQ VQ0eRayY@&S'^A= ah}z8(z$h=PE}w ,u L9m6meqk1f4xz4#ڊ\"*99G8[ug8s9˦CxmG~߄~]yv^} -Uƈ̣O *|OJFh*@<˂cMPnQϑk/1ey۱ bC֛uj -}1GooR^wG <-n\T|KK+lErctWwl}= )p ZѕM="c.D[, -j鈋ILR'8ʃ2]RhYmSiI<+8F\,;KuR~rJ4$XyR~ ̰)PUspNTW_eq6xO6F " -uUxX"]7 kPD2pVuMAR>_%/;$ #RDu(ٸcϠژdt׸}P80@A/,K(*B a.a 7R@!999mhӫ@ $tv{0wY~uEqOŷc QfJW`\"x&sS甜(B)pI+A$ iDk.\jI41Ďu=?lz[y=:pZm~1 yt ZoLҀBC2E Tmw]?B hptc8@ p-Q(QG+zƻ  x -b#;8zdsJ~oF -sqp><23O&$X~Z*<8CUYQC暬]EIDyGx?Nd>fd>v >Tԋ)aD9h C>$bj* vђɇbwf4ZqC9{D9_¿bBnژ,В$1A{:ALAiD{R|(RR-̬> I*Id'u0qenDO8@ ^KH -+OgM Čx@@ u -R 4̍ Zo]p)7F/9_/{w29T!0Z _Q~?Ɔoxp+4pUGa7DJD#s0- -V$B3-v/KrY&p?k*w9tmQL#Q;51qmJ17+f59-[d)AP"7WfAx5][;7yX5Z*9geat/fQWqyMa`x5xmW<#eݣ3&>H&@DMF׶f"$}u άa "bxDe+lqآ@e}2PJhj3$L'{/ )a5[C1)QY.wYA&jNA"IC1x=aр659É8KEH+e~ hlcVP9]+NlӖYCRb"qVXc]C86l$fD> tŤ-90)m<'e1swV)yU՝QZSYĴ\g"Jk"0n9]$:ink͈3[*Vo@нk/ #.-M'hաƊ - l>^%7xI_ bw(J I{(6vW d()lb Oe[DZǍwÈ;^//n28[??'ilmyT(8,R՗L@?4L,>I| J)bI1b2")FW3CH()='NGlfdLCR5~t{0&B*{H@b:mf\er,lt~{w-7 ,<.Dxy/@ڔb@BF["LaM5e Y(L-oJTliΑDy_KPXHZ$H! _"KMh8R}aC/O"m.ZXv%/KrCMe["^Gm-lq.4iWKfG7ah/AccH9 e\l~ёn*c:Ctt&Gp21.ĘQ02H}`,mZ|$ -eb$qJꐥ})fFgveoP?юp}M9vk=$v`XAM6FgQXlM)Hr{`Y u ޞgy וyxUAj8vs5QWxa3kAI!mIa{-N]nf85X[>(鴱ƢZ`{H PƔ4ӪaP YQq=ɩ"Q R\~w|WXEѻ햲p? |"w=exVSK- S`CRÍqDPc۩l!0~qwZ!ouB[Wb^`*'|kA/˝+͒fH%dc!&0kGPoe}@ÖKj5VXȹȌu1?B1֬@妻qТT]^A"xw5y,!UXDqOD$;QE-Bo ;=ef%֑ġm{ -m 6eE0iFP*HikMs[vc94s8Ӱcb phjbꌪASX 3߮暫I/Dl|ܷR$JgUrx0ʲc2[9v\,5̅J0Z] E11?e56" Fx4zY(e"8ݠdD |*U[d㷂4‹MQ2i1H\%2e^N -al !DzQ0xd'Ǻ"aցmx쉕+ʺfwlO-ƁSnrBS <#{-|Z`޸ɯTF\-pb-E50$Lw(Lotu5/3ZXӘq u@$h5l' -ے`4V5NQ#Xb`'ؕ4@P<7iJv7"8=ZUCm#J qҠ\dGcE@DP([$98Rw>j2xR-66xPOMGl -V,_ҕN)mmܶ6 M$,wfV ND a/0\Q7WL%`Vߙxяh-[(S -fy!G/Y,VrswEh35or0?g{"V׊ t3 D/nblGČ­we+Y Y#%\85L]KwKѪO*ƫ\cg<CS32 8܍Qn8Ief& -Q)Qؖ-Puǔ7ZA|$Qhz3L̀BꆖfGbaZ -.-izmRv@{XSg P/A{ 2+:Z+tf82iqR`0Qn%vL5>cY(t]/!GC7+u5v} r rfE[W9w=xw7⧚hb"*V՛i긁.7 )*Vj2>0j(j-$pp,_R2Ogaዬ/?%X@`~۾6>SkkKX-%#tYB/F*k׍g|0֚$4|k K%^򊺨$.m`7|TzQWc[(vj7G e[l9D3< j3SfNQuqIB,QAG/q^!RΠF#Wܠ=\oDي/?Cj'*`лw|mAdDRԙCIH j i,mCդ$jϵ<:#P>(eXz*"1?IyxssLjyg?~7="ָsN1XV]dݏEu~NܳϤX(g9$=~;cGy&?Ǟ|$y{8oͱoqdo{3w;wz#Ϙ{.ǽG]Y߳IMz7cϜc~x̜G̘ݢ˜KĹD\Gɏ?ݹϽq#$}~g&֙39E&NIOn=/bǽƣH>;wMz~$ELƞo3Yy&7#k=&;~ouעcu]9]wH9$$Sɬ&}s>q{nx|g{׻X$ǼwŮ#kbdu~ޙqMIϷ8Ȫϳرx$Gy$5UG5;Irqw'H7ȧdTtEi<=z2cGk<{ΙG{̹Xk"d$E&:7ǟz$I1c=GIt$EIu:s棈IsG;$c,c$Ɲ$#Uȧ"{sGd88G:&#t=GLHM %uT\ZQpgJq܀}_T=EڅEn(_VYZZ2x C-'^ӝۢv5;ɜ:wϻ9缱{] -CI~qx~" |8txQʰؙ+,ܹGRQ0ᬞBd{u^w;w}꺚:[8h'Zhi sEebS՞2s\9SR ėvVpapjԉ/-ZՆ[˅sLPݫv=qŬ(޽Ϛ}-?sf{L;E͙c}k7';6Lq朩\Y}3uޚyԚw{{sw?"{~w͙ݸ;ǎ5[89Wu'q]3?݋͙c;L?;rgǘw7g?Xgz{GdGfM"sf|$GM$cș?=y2ϻIҋ{sǝ'λIpn:L;;cƣ&}oGO"rǜgνE-pywq{=d8=Ԥ93I>7?y89ԣ!d'{=;>rw9z08!Y9u3w8Pwy5?#Ϛ| y$g|ZZ_d֝|au3)3{]LCeܻνYN;Rnyٛ];ϻǎ{6v~wysǏ9gvsh{r?gna3CLrnߍw}GNk9wdu]I7Ij9Z|]3;)j<~FxwGc=8ə]wHNrf{؍]ay>7g~y;ߏ8>$gj}-ߓwg}ο>rNb*E[)ZfhZlH"t,\h%(t*㊪𰜗u(IQZB\Q<<*&*HP|d2{Wn V@xB_;DdI(P90\D"o1e!:CVf44&Dm :(A|NY@@ -#XBD^/AsOJ|l3S7[D:O6e W@ _A~ -}\>1󲇛0;:؁8"yCm=~!ekl1)6Vy~H@A918$!FAI>. R 54XXV0`2Q< .i !bH M 0=i܈nW;4RtaI8phK?%mF[0` muJ z4*PP)ȉW=j#TWx -`SLD۪DY(= E48^8',1I%S -𩰆xn-y1zՃi0b*< X+P-M^::IU},.Un('6%/F#DL@ucR._,{_ԬM%ʃS[^3s a<$I|.CIM}hb+b!^0`@%]&cVA C".Yil1QqpRAH^$ -i`UdTGIiTMX! B:<s=  ;-ط$`ǡu1Pͨ\0k3QD)7M~@fbhݛ&l[2]yV"\“EM%!IarSyjxA/C*x2vc}ePuz8pyagu@ڮcz:)ԮQUd6Y8ճ lPO'M6br٥ooۡT}okע xS5motoC. jQ/ PThKa}a 9?rZkԕ07-Ԟ4CgU p3@!uo.[C(j*-=-N-jL3@>u(d}ePnHUo$"EZ/'n+Sf™?nœsQH@ A>5r#pS\!ƜحW!I6V%qթʖ) B-$FhNcBIǭ -.qi`/,́h7CTP<` L$Ty]OŌ3J^⻔@o$HB'n 9K"㾯s0BTS,3-ςF(\!E*.e >cdRq-Cꘔ/l2Blo -#WH .!f50$:~3)4x_}0C!42\W3F:|0:pkW qjvqP5 R4X(`0V@eOŴXhC^ -F^"y(MqDm8ȇ.p:6_vPI+,5bdix&0Y3%ފ䄞9+ATiMT(O)|Ykg#9>ĕYǕ!W^^z;#THgKX%C*q&5G4 ֞ۚײ "<"-]2d%`b$!粤02z;PqAH13 EQ萺1O(vэ $S"+$fx1^,ɃQ2FJ0ܸGe`R{4QK۶ *`F\zM}\IMSAv$:" xW C'bN qnӌ,N/L&ظ-42[g AP|8.Nthg"Lzq*|B `I'>f)  n@N %@) SLBMQ )[6& xg<J*DqgDa48.oixp9\H"\mV&~/\B9fN(  8# $ SpE &X?p u!A@be["~U>n]\ (wa%qО.m?-Ԏ8X9A-@mЮ\ȥEaBv"!gBJlm0Sp?4`` -$ ޒ2aǁ/LZ.]8LDFxj|h`aeJ.Gx-NA+H(#^XMˌ%BH%Q-hQ.m]YVV34Ό  YZ -eB[k,  WD\Cc~bJ)[f$!OΐVkqU`V@ p80k4%@!t~I*2Pb]Ct̀vi "ɶMDh@>F%@f8A1hQ';lhaz)|10Kڢ"YI,#2x\DŽVRHƄ@jg^`7d -j̰C%ravftA,dɢ4Q%HJzWq0!4 T^dCF1:~eBIK{@M|O WJgJ5JtPMU3JKűltPqeHطp3jQEsa}WU֬@ْᬯk;\"Q`VJ@Cmz S,KE&&R% j)4J!Lh Rm Q -6[؞f*l #AL DDh.PW]WB_禳[r}.RѶD% hs;KBM$gAks8]/,Lۆ/@Ya]N'ub6 _5dz  -CW]JX*|@QRKE*ႀ>ʑALi4) ɀr1N-3I@bM`A3AErdJ'(qN IQ%$,r(H F)Шb fރ%H6")Ӣb 5nCd)S@A1+iAyyI @< JfE q haD/㾡4CAR`܄T1 +8]rIKR ,e`BT39[2K͏]-[1d* -6"+ 3DEv&(T,E^JJpn3k}$?eȄd[9%"R23P`S`FT,d69XE/F1W00 , -S`㒉s" -, IpR/b ɘ,S`eꑑ8y~_LBhFp5`0P#Ÿ -4@nT ,E>I?pUKऄxaA 'J r PƁ*8&My,%8e=/ -e`jPqʬhY:0)\-~yz)زBI69lHW:670& J%`x% hBz ׁ\vK0l3(* EjW3I O'=hRw9@5XkIMΠ^j24Y|XR2 P/Alށ)=nLJ׳(Gq REB]@E`y ; A@kNH݁I%/xwA,$[4 hp(s tKLmАgǙKl4 -kX@ALyW1p @b$N L'؄.T-N똠lԅH| -M&L$>M. (RT%t\TՁB#̍̓@h!f}Vm=Ɓ @cJ葞-@!ՂKYԶlaQ{-?„ 9.W: $Ŵ79EU2Zrl`(!!ڤle)$PTH%u -P,?4#UxӽV*gtqI l: <_ G4b$P8Hpd,X@Ǒ@Ԯ!˯~(6'3r| eH5wѮmM.'zUG) -*CxqQ" d6[j)f":3 ۅ dJӖ5l fW+ -QL Jh+D&ʔ%A`slr 6Y'K*Nop*${{Gg+3zH$ٯ!8<}d Ʊɒ͡ћע7E!I`s 6zRU4KUXMVRGV$o~|3g%qK: --BBT" -#'"B@Choƺ^$T@ 4ȅAl0'pg14cZq0dtR! i2 <͸Wm&ӽCP3ҡQ Hg*^)&gz^R$Kː{GA)De{{m# AJ5H)E)# YvEEs& >NR(T eh*,dN9-bZ -.L0]l f0"2'Ǖh"㿓dwwI" I;5I66pddB|,lMD3%)_55J041ML`Ldrp\fK!\ZcU^"!jMKަ*Ay0澵ƭ s\0I( '`*DuEbbk8 2܂oۏ3X֪+QjF40 h Se@ŃkT%5XRG3)ŠOuLJ(̀>5=>#8l^JHҧZߖ8<9Aj'Xq 4m}LU -t[=PUtRUt"|ʔ-++-k\V`+ȠP(*C -m b͂ P<% -#뙋\;f<(l.:dRT q b&M)K7z86M94qɒ7q_B~6 E!$4Ms tkQH8KUR&-&&:fT$GfHB3" 3yeHB -M0V7ݲy -g^ur`)6V/XDZ`w6Z"De 7L=ZyxaĂA3f@4/Aɴbx $D3­U|#Sq|-f -.IC*& v0RPǐO=F#'Տ-;iĊc" -\,fLET0^ DYlBF @Ю*Fr|aMl\t[3;3|(1I_O/k%T/0Orn+2n+#w{*!P4aHB* -lYֲ2%8jY2,,dXX0[AJJ\RfX0aMvŮ2(*7Tpɦ-Û]eU8p3+*SNjBad@P,j &ME‰4ù4Q,JJD`&A%޿d{GEtG]+'FI=$7N^2 shFq͡)8,37 \lku5{- -Ijxq 58E!1?n])VĖkMфaM,C -Ӹ%(<,?Ns*Tq׊[G`[*S+eJ&jryB[w~B[%y " 3ySsȄQ9fD 3 ȤbXQ^,D66,P Rq1B)*ב!uGˇʟ9&^^럏45"j[ sJ7zY$#JJB@j]?M dDBUݯ/( aӺ7H{*e3 -:l3OѶqMF. ?ۍ\F%l{{74qm}/$?QEz㴑4]ȄI£K4H;C0>Y8A9 BMJ}#N 3VڐהEvQEs?iQ76 'JSФᙃ҆5BK%ۍsg.ccGl9gnEG)eXQs$/:~ဵA,N.qkNWIn^ez(l -.G(3'kNVӛDmUT8nP1O]~ڝBMR`B|OnvSt,bB$S#dx.tR("x{7FDIOgxlv׷|V"~*Vqx\޹⛴if3Bjn6-E:N% 0e~FPK}XI.H\ u%kqUZ{,AI|U0/P55u1{XF*|0zL6* VY8uk^z9T ph,_.2kbřJKp=| al9>i6)f_ULɏX*L1YWq23D-ROYW[s4֜nǿ(w(OW'w4L@I FP僂T)1Ǔ8ֻ7SuulG - iV,tJ54oWvկԐ5^. evLX3?<QDd~:GJLp{A1jH8 rgP#ϘΡCN!ab{?Yqh.N{^}b m4٨?+!a-8>[$hPWEWM p2t%GY 2L (5-B.38! \{+nH֕dIյ\|L`DI/D]dmn zx"c J!mx?4H ԃ#Ԁ$Ky xMy"Qa᲼ZAnIh3}{)=c]t3}X-{H]xafMX', )OE b9p n-rc8 LLZSfJg=r@i>{[Vu?Grΰ" T2Gkg\LqP77 7JL`x*}:³!s0TvΑԿ>+_CMz| l>{&z5Y2pD&V07e" e_ &X44Ι3ln)q2fBkDsR $C2N0m{ ׵gb(y Gfs`/Tқ+RBƲbSYڀ^OYZ4xw| Xiʨ_7FL^#XFDhh輡I܁EԿ+@6ɺdqt: `rks8ų\ZD5%2q*F1;TjPb|P]V,3+E wh%޴Q+4D\1h\CP;NЖŤ1tJfjܱsXVQ2ˏd -l^~|تk3RҴB]۫>6u[xӘKcd: &G_ (v&ƈJկ@ZNc%>s<Bj71~ e Y3_Y.pŪRՓr2on6s W!^M M0;?bНz0[t(|("0P h!# jc3(JCΝeBpqm0n1oTF#_Wא%d X^3 -!=0"kG|P+6z˒xEPq1XQLunn @? ͥBT?rL>zɞh* -;:R/fhq"b+)g.,5yn$3Iw}d"љ"w/LYߙ%w%2pbPpBFR F:mg$NVd!mckv[vkW+FN=#uU&5ĊLw|xcEcHsqµJ=~|ia/PDe+[> wڤ 8&T$!d^]]ٶb o"0>San]ՆaC@*駈_G -V:wp6ix IkzΉ׻U".z8|30󀗣1R%c D[<K5gW,Ftۺ|=e05]P' -a9QSO==R^4_aKA1ɎJ{^:d]|pݻ{qe8MA@Sc'Bӏb}Fb?K`m4$BRfet4♬ﻻ -2 x gLI,_+i .##vgqBB_y8G-?5\0{wQyūw׷m=@\+VPݰ sl*^/`Dfƻ"2wwYC?r ,,#J[@G )*@`[iNS\+DNV!緥7J{G[39[[m-OE9~1 Kf>$h&l'"佇e>^q-7+Fū?ZNP?v 1~0Av)r"8ס@P, 89+o3(Um)~ VbIp7Q.L^#rkNn0R6 m~jePePh*!΢9 ֆy#It-3ٿ]8d.1E5'V2j(EemɈV#U9,B̿R~'52(yTwU}tWGwOQ+9`5֣AU:7@QHe=& - &{<ϕ~8!@qԣXSrO -kQ|/*45cqC߇>O̝M,\[.GKǶH [glvF S/xŽMgv -ℸ9ň89S.2UCq mY0kC'jv5ӏo`f tGᐄtAQD(V=+%NETPС!eÄw7p0m GHߒfDLw;0eAQV A3uVǃA]5rwlS7'@+KTr 84WpD$ټUڲam(32UM,yQ3@W- >#6TW$=6~݌tSRCӵ~풠=Xe ޼.2ϣFҽer;j7IH2 UmfoOn͖G{;e2VcrK=:d[J53]#mnV20$c˫t{cÛJH_ GUF{6-T*)WsG/tet%Q^4IAW}ݏ(o<'u:kLhN;{~/; 2, P\6%S.O7[-4Z}Sk)f#׮dĨ;QXXϦXNKց'<#pZdy<2K0E=Wl>( SdV~ -07(cAq|wŢE?V=V9$g/LH/.lqE]h.pP3/Oj8=ƕ•k&'+3| (@3k6AN)DJҟ38 x3d(}̑VaG@W<3-à:Ƅ+Oc˾J`ƵZ/(ւoHT_^gFx~!ޮY^qmW7yvp7OGm`B'= K]՚=jSgkqUɴ$๶;|ݹ oR2(n`2D&_ - L52Y{/^VH&[6Don -IlCw MBTmoLK̥u]/Vth.EdK![Gɘ{Pȷr?ޮ@s EӭZ2P꿻xcF -vQOGs -go -81]?E1ʊz@K1ODnȣw09$֬5>fZq8aʭ`%-0F"P;76Am97j%%j4 - tTpX^_A푼 XREwck:Qfvb\zWݔnOʄR$_ -HS-I,!Q10T\xk/k_#(, ڇ8Fih!6>oYJl?6E]6J0Y*>,E,Ӣ5rۦs}Ἶ>0=qn.D #*JeGAE= L@_92;D*cM(`wRQ?didWtIIxpbkEP$±_>BqaO>‡,pU\_fr˔j)lFJ ;W[2bFJ1vvA\E!Փ.N^"=gR<C*P "Y6*^>]|Px,k<,Rtx+TK]ZA6h&0"wȟ=;8!HN!=AtϜ!(`8w*)i߷*LMV\ -۰D-e>i10k6[ T|sW/tczMDe=yUٍHaorրQ|?!Hj9tX+|Q5N6SϜCJn֒(fh$pq!c£P.ES´ز;'whBM~ ɾLH]'ACF:b\ؙ[x N}i6eVk,d ܤB>"JҘif1\ovIeޒ=r&CMZ;EfQZ:Xt&xhP.|)O&;~h>KId{Je1kǛSKKIR`>`}NksPEt\zXYPEVN_)ʶ5%7K f Ao@wJxdؠ_8=Jr70hQXzi]:yW1~#cݼR qwWcP+/ o -9>O>, 6'zh`a aW,Ċ`?桩^4_8uY!Hh -c*HL݁ݩSmKw' :C`pKFgL[wBWn*cIAm<@R\3`{|B5 8k!D.p2 -3H63-\H6Vx!B82dX:RIc FZw&ՇoK6)Y8ֺ9J.&05g$3;- QyWH٢ePOQ\zKy3i/6OI&7F[PjpѹAdž$JdO2B_.Ms槰׭ 2*E`szKĘp]m?!(#K6j:Akh*Grq8A 00+~;uӳR:FBS|4Xvy|z'X' >+Ebë vy 440P;^IQ7_^13ڦ?_c!I}R M,'݋UnOmj}TѪ9|!U4%d`i*.C8fEV1جRLd;Kf1`)w}@aw83d0Oc{myVқ~j\f^BǬ_ #d6Qm#8 ,褰`Bxr -QI Owq/3A|ȓ2-g#rK[G's&`Xe('g@pK5l*޳tY -#8aՊyHWy1Ӭê\$EPó~-H#:V,blzUf!X"5g~`9*X zl"]3gٱk gL> %r~?2C|$4Հ78E3 z\7# nKt6(P.W֫jh4TM/r {p“$' #fċQ#l}hNn[5z3z3OwX@ֻ;UǵNcdЪ ?y+0D7 & \GfLC(WFbh-@8t($JGԷ4c83Y!z-$<ʟ;hFґ9κwؙ9\ ƹO$49t\ n96) W, -D(0>OBP -;nl#G -Q&_(:n4Ni/L ҉/ޥ72&AGR* jsk\R Pёu%= D|-@ ->N6q\0-x1HZ !s1n-y./Qd_xg -i 6/]Ns GKNrG-#A pE5xX{ڐFrL"ȰpGn!<6=ׄ W܀@y2AAEp:86'Gn[omro`$}dg[U=N ~e㨪WrQ6^}265ި|W?i$hQCGN6t~`V7K:H[?Dܣ8;زa5ɸȲp4E''JPj#9X@}Jk͌E4_2MN4&A}.C> xR&4}aDuލxEk 0aaZyS;ߦHY$Y\ŊW= &]]y>U9yiQ}L_G6KN@ST9FLj\Z$ ΊJ˫YVcWڽBԮe0^D @9( o~`=m(PP(lItR*,$oK#Ẕ imiI._ %;Ud1f..N_<//{i'~ rO}{ݰx _:H]_>ƕ%F,9Bv(G -JUHI\('w - ׽5}LtmIaX5#EȢFz6uBTzhwA)kJRLqmb"rFe]*ΒP< U_<+r |/6g\XU*מWBR@q R o]$%1wW:pNFgͦZ,*ju*`AOU7K2U0w8skh`& ­BPL܂z,4r?h06Y_@ TJ7niហBaVXǽNGlqt/\C - & >e 7Y5 "5a2ub$ y%*DɸR@Lëm8j^ҍ:6* _00C@cp$h{:44.@Egp{nRpB(߲qsEc>stream -_AKFAdZ6tRqG]AWCY4v6VNy7FL+XSZvX|B"}?L,O~.Bbfp &7 l"*z2P.'!d&"q# 1MDW9G1wA"R¶d fupr~.#r1sZᶲ{:"YTĝʪI:terոpv:1j)v<] -1Q (lq4ap)ttm -a+!Qt,gb>o;)隠C#p;#[VZo5s09m 'AC15́S -}XTjn* Ǝ袰1/vO}'5o! -tOxlWw/4!a"`o*8M̂WGVOY3멛:r%7JKO֤*t|1aāF7q oˮiV]ģm+DP0 #^&;j}Z5!P # ~lQM -hX4*;]c*jݑXI-AY#Li0qXs4mD +31qd7qorw_*~oĬ3jU0;kɀڀ0b^;~ߎRqopd'G t,<"9=9Uͭ~_AV5:Bb5v -1[Ҵl+\!j҆#K " -J%iYǣ4 +$ E/e|2^YFZCÿQ'\k Dr*k(D!T*Ii4Or 0]"f[1uFɽ|42놐3+-aȥ˜&ϝca,DH6X, [ZP/%mg~[QIg m3tiIo7ݝ"ewQ$sF<zR ٙi?Nq}j|C*>D `?X z o9q\-3<lȘd -U;fk-bGʫlZ͡0hX W zKQa/ {^mX֘Y[׉Z+ -wr:0_I (Tzʧ 9|\oibF!Ycgk.4]'(Y&%X(52N#g{e# Ao $5CNi  [pKLa\DAgwjc| P !jdmlUYVˆ]%$T%K(DQF5`=ݲ)ps]M2\Pb ڕ:4:o⇻{ˀ񘇢[͎CW9!* ʮ -(\GWOZ|x6mhnRgZClOO /Y*f{^2{`NHvwZ o$z_? r4g!24(:D;=O.6iA86`@~VD)CP]$$ˋ]SJv1(z8H^u  ∧NY !&09c&mK$ Do+4C[m xj9E* t` :G`1Fd mk){/`_tear(16Gn#|<̟?s.8G{}_ךW7F(MIOEb D).-^cY^+L'.s"bM)Q|f" 2F%$E2lN-MQ(F!R`k$I9n)H`Qdb ҭ Ҟ?]4,*\k#:ZbAZ|fM1r4|Gz9m4>Z9.$w:ZMzpVy7]rwChɗM47f(GߘRR Uhcn ז~3Qu>aNU]CK`gP6䘸jQ=Wv3P+0/rS9=PTJ>}|JHc5w-Q!xA&#oo^ד]7z沘'];Z[jPZJC'Vs[iS)5y_8vFV3b Aw<ң)0CIo3q3-[^t;Y5%fT"J"c OP%ؑ -:sΫ[ɧoz*5YKm 3\qYZ9^ b×TÏ=M$>[F c1pZ"O_BbHd`ANք[K.ҨBcz=npk㔸)Pg厵J=]ƴĦԅF -B &be>>Tzѝv8Kjp]( -{B)0٠ֿ4R>j(&9c OvA j͐tdTOŴ  Ƨŕ{]zz"VT 'z@_'"D --$MAeΎh7,~S{6dG 3@ g -hڊO7X+֡'0ں}="5lo VϤoEs"ZDa=CϳL?;x&I /k g)6}*U lòWa=a m^a(e)q=k$~Yų-ՙ3ܷv879.7" ȁ@?) QLB;y@ o^vgsًBPvXڣa|{!-ЩyR ΔMpy1H` M P7 p+u_ᜰ:ϛ!6{%f~D%;mQF4vX8/ T(Cv,x{ -qwDQ{mɭs+dz]CLs@=T[ʒs7eצ< Q䭷$-ofR~8X֟bl0Q,Dr0_ -L I}P-wPP BаݿME*_,WO H=$:gsYK#|+'?q.s=QrՁV(ib[k@nM2`k -  92je+HgTDڴ]=8O -E53_ <ךK)?P3DŽ_Avu[:>@YhDB"J t\?W >>iU!ը2˰mgDR z OAAUt9G 9D"Se -c-&aFٲ!.Tg;pSiވOư#"o3 ?{tjC|"i8>ʘLZJ;6#)kxZ>)@-Rv@XeB C²sVYV &T]ǹ\’%5ڬ5 d#gE4t쫿ltFMuǢRyh+1H< s<gA "ާOiWFw 䥀&'aw!-yKT$%mifdSIn;w9>VL\*J# jτZQn{ԬE:9*)q?Bg= (efî*L0eC- rcmگ3h"S&shBkjy)f~ A'RQrX^kiAB@6XF(@oYUɮUCS(:o] _[aVpHӔ>h|iۆE d9fE3n:q[TᾦoHJA z9ڶY37LVɵu#m_ƨmDۀ8TssdJ[NT;|dQIxy " -b_v1ec]Bl@peHX 4tEZSe{ղGO>e>/A ˶j TC)5xDxk<Wib^УLW4m eϻgQOО@OżB{#',Svx|r=u:e@B=E->|KұtqQʂ FTQK䤊 v-~KPV^/NH6<_ܡdF4v3pyE͠Sk,Mc8!ab.1w1gB'&C'H\;h$zW>&6'yq䆋2]2Jԋ {ᑞ޻,wq2 $\0:VUq9KIj4uUJ*5,b{v"j,"Cֶ8)m*y1Ӊ2G@ -T'Qھ)kFϗ"A׈r1z'=mqݗ۳iŽ"Y{dπrʵnc?Kz/gVy>M2I8t歉~OlGLkcq~:FoJ3K9(@x4XpN0˿xbTwBMJ_b=Lnܼ6X48^l|BJB&6t#o6ts}]`͛^Gi|:Ѷ ƱB œo.ZJa #p}NP ;X{>pyy^ o #3(+꼖ڎ0Lpg]mɡaKG{]eN'QtsJk$˄ eɒB>ҷ5[+L*o} c,.1HP8bxLf9.ުy!- Tk4 aBYzƊw8PXמ9[ -lzFpy7?50446d8M{yJN31Ң+6bH> ! &IgL•0H wWztls"K6jH)vNQ I;0y-$YG4Q=y+>>0nm~pƟ؊İ0,_iAv6୨x%_h|f6Yu&m vGqZTAbyN4鑓o3$H9dW8|7Jתm^i|3 -:ހx}煤!&>Dw(Dq%1|Okఊ$DRJ./!-Kkp$41!Rs*{:&9RWKfl 2+%H]84%z( pD&NBO %?6sAGSMyڳmN%ƷM.,=o }&2A`mI7@v~DTc⡁΢^+w~fKwTDQRԌ:Cs:Z\;|r8 =!+6h@ n۔׵I: -0W۠O^tLJ*.w@)LR'RE,e :VDr힑2Uʓ}º3b3I18Of^S"nhkX -92۸`1j@t>쌓^ն1ʲcPS PFf7nm{F+{j17( GҼA,2A")c#,3Pf, u=r)#Ѓ=\{cT4H(WA՟N[|3M71,הcib d#ʀ F{>\ecLBLn9G ߫b<'p&˛$فcW6h7Jy6~HsW_;5_ Zs+%:+]1#C0źr4z0"h{{EDJ e2d%(=RZIkVDE`o>â8]UU:|'ƒ){xyX0=\Oα #42CiQ;Ղjp$pϚ&Bjz!cs#d=_7Kچ)Y܂iDvBQ3mg8y-i%σwZi/ffAth.{4t{w[#E8"x~7F,Yx`ݳFP7MJnD ¯71d1~PTqVO<(RSzks(Ky.?Hsq CYH2F L#آ&1j3R.dm>qŖhISPaxG_8 oe>ƔhFHsO'ʸRGiՌCiV]m.nY/ꃳ<~f܌"Ŭj-_H%Ͳs@ V 5$OZ3xV^{m?H#3!Y1bIV$%Q%xP|g#+,D4A꽐 [:slէy -ť4g~3С T$֑"`Vۈ2 [@<:FJK1Y o=u+ti}u<7XU:=SrYIHIPҁg̮g @Y1}TPli/&a_cTiXR3Ó*[I~-ݕA ] \5ZMW߄^q?z$@gqp 4#)lrpHWRşύl!U;q / D -20],JdX\C!nM -)l66U;AFh>ܗk I7ӓ9o X GErMHhKf#B?BCx ]!FFwu6?͎XI|&;V$=^1&Lc2S&,'qHzyQ -YO`8?DY*n gM!b&cV 6HFfd85YB8K 8%DM,**=%cf '8+F1}fM\@]*!7= qOK3$D@:`-:ڕ U>r*SMDp%gT \CTO(FR^Fp1"Wzхpu? j=̀Ez EfB#hWXhS@Tr\#cMЦ^{V8@* BW.qtG̶wҠ^5@̀ă H95W>5:ȌB 7}\xǹ nΨ ש=(j(Q'+`6:9 9Tbs$ )?:Bϗ\t>%K42v`D;pKD#;"'@ UT`qğYaCly^CJ͔5`OR@b /1Ie10U(fr3?_cz}EB*M'q|.?n"i[khCz -4eDe Pi%L,u֜=sΟg3ɰ7-!m<-Efuβ9y>*DžaSp-O;ܻnԹ#]{.2.c"rwlRƁQǃt `pdF$sC%6YIձcS~K2d7݁ U(Ca#$-%ؘ(Vhz %%8)(EjptϾG<5 [DDqT d(468-MAl~&t`ڮlvvhӍq-gk -pzkIwwH!8b13d#Zt_1G3IoEysTbEzD~=u.\!-A -$O-SXy@3DϨ2 Sf hyQSp!i4@r90=u AZ_IIL|E\ ^Oh'7f wJ9PPShSy?T5$I-;,m ;y;MrOFk$R`cNVTD6PF -G&1ZB Ox1Xw'gI41lPǀP8.DphbEEE4n5ĝZƴug?[u94{_x(d7LHg&ikE;*Y!loaMQPcV[^aq\Tˮ -g@[7Br7 k:jBzށv8f!p`DU+ _"7 櫮<[^񊉛ob#uçKRp -Lmc@,^sڬ@Mt@ A  9P6. ʠaNp) qTzPP*ȍ-8%$)16^2QZ4ثtC#Pԛ dLIF6u~DfԤpb. a WKDf3=ZV"kgFlK^ҞܵeeAlKMӫ%Ǜ -=.a1vfTU&ye_ K@R'KcK>IۈC%Ȍ>%+b S&avj+K2sCYVq7f݉? XGbRmܨ1%g@Bj`ºS@F 9Icx;/z7̤G -+\Bky8]9t(B Y#TQ_\=$9Uh'bXqaV&_z1Qg`jAR a%Qv|ԉxMS=Xؙ`v }/:w%;'5ގ{@@=8TelǍU^FH㺣udo=nDԼY~@tF韗wp>rw\L}NvM[`t7KδJwzi"/O% 7JO;O"Dv/d{-莏7 frpRK[H;n26T { `yq/1đ{̅cy=.[c2!Ӑ;^icqڔc 8BǝHaÊͲ;Lap$Q6P \qWZ[Ԙв%b@-Bk %q\(I|8%9̚V lj(J7OnVLg8vMd.=?5fEx=+оy&=˫4,xeW ~*MYԼ -^JW|qIW;J}JˮXx.# JlbK1BodQlcw^YFj0'Zd$$DB{_8&WOF])։h)6 ֞yCv1#贂 -,6%D1 - ǣK˸i- >%kqa%Ja̴P6/zw/BNF™K"iT!ɋ\0,8I9@ŃX tVRZ>=&k)_%B/ -+jѭ30ANwDsaQGb1`U 8.<';Ԛ)% % @s Y&U.]UYncqCC ,W"̚Cn&BF9vԡZ u> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000046012 00000 n -0000000000 00000 f -0000046063 00000 n -0000000000 00000 f -0000051763 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000051836 00000 n -0000052076 00000 n -0000053238 00000 n -0000118826 00000 n -0000184414 00000 n -0000250002 00000 n -0000315590 00000 n -0000000000 00000 f -0000051463 00000 n -0000328742 00000 n -0000046477 00000 n -0000048422 00000 n -0000051650 00000 n -0000048279 00000 n -0000047233 00000 n -0000047718 00000 n -0000047766 00000 n -0000048457 00000 n -0000048815 00000 n -0000048570 00000 n -0000048695 00000 n -0000051534 00000 n -0000051565 00000 n -0000328767 00000 n -trailer <<281EC6DBAE9F461782448D60F4EDFF1E>]>> startxref 328969 %%EOF \ No newline at end of file diff --git a/misc/branding/no_bg_gradient.png b/misc/branding/no_bg_gradient.png deleted file mode 100644 index 0d485335..00000000 Binary files a/misc/branding/no_bg_gradient.png and /dev/null differ diff --git a/misc/branding/no_bg_light.ai b/misc/branding/no_bg_light.ai deleted file mode 100644 index b7c49051..00000000 --- a/misc/branding/no_bg_light.ai +++ /dev/null @@ -1,1838 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_light_nobkgd - - - 2021-03-19T18:09:28-07:00 - 2021-03-19T18:09:28-07:00 - 2021-03-19T18:09:28-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 240 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADwAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUNfanp9hH6l7cRwJ25sAT8h1P0YtWXPDGLkQGL6h+Z+iQVWzilvGHRqekh+lvi/wCFw06r N25ij9IMvs/HyY7efmhrspItoobZexoXb72NP+Fw063J25mP0gR+1Jbnzf5muK+pqMwr/vs+l/yb 44acKfaOeXOZ+77kvlv76Y1luZZD4s7N+s4uNLLM8yT8VDC1uxVXiv76E1iuZYz4q7L+o4GyOWY5 Ej4phbeb/M1vT09RmNP9+H1f+TnLGnJh2jnjymfv+9OrP80NdiIFzFDcr3NCjfepp/wuCnNx9uZh 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 bXYq7FXYq7FXYq7FXYq//9k= - - - - uuid:ff665777-bad3-4a4c-a9bb-ef862459062f - xmp.did:53b4259c-c78c-47cf-8bae-7ca5e4a2d91d - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:53b4259c-c78c-47cf-8bae-7ca5e4a2d91d - 2021-03-18T19:54:11-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Yellow - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 29 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HLTKn[1 ~$- -gH}C9. ?9$LOgޚ{iOB+ [w&f2PX4HK3Tyv2ᕝt!/.)~/cr{$㐬͟Lζ!ޫ&"Q :B|؏G%9&R n>;lxy ~Yӑu>l@Dq}D.B{,0`W54k4'S o*ᘓUCv{Ň 0{"0 % P~?REdC{"&J$+W QnFl -t:J1% 2ѿD'{Y t{%cp6=*ᨮI9(&"@paa\vbw"n:A1]bߢFB[cNn|.Oxo KV endstream endobj 29 0 obj <>stream -8;WRp;%CJt#XcqW(Ph8Cb]O]'8T:ou[T'2*7*WUU&cXMnbO=XM/q5m9827#t$_8b' -8u8>7Gbe1tMMI"Pb(rt$8^OYZ6rC=A_Wj&n7?$tRMu$)@UR.YUH^ggQI-XdnK%AR+ -8t6PdV216"kX6_6d`&#Flj'BR=l,^;AF&-mVqGA,D1"ZJFUL,[-L8SK1?I@34Y=pF;S)R8q3t^'=WW@OoM~> endstream endobj 30 0 obj [/Indexed/DeviceRGB 255 31 0 R] endobj 31 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 24 0 obj <> endobj 32 0 obj [/View/Design] endobj 33 0 obj <>>> endobj 28 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_light_nobkgd.ai) %%CreationDate: 3/19/21 6:09 PM %%Canvassize: 16383 %%BoundingBox: 18 -291 279 -10 %%HiResBoundingBox: 18.0444971393727 -290.349282296651 278.974628053849 -10.923444976077 %%DocumentProcessColors: Cyan Yellow %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -99 9 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/X -m* m{aΜ&" -FRfRj0A V -!$$oF(YdqcD= -Z"a6?+Vػ|jU\04x1"(!)ǁVWUTIqYd$@"#QlXxd=LD:;E#Cc=Cfr7 Mpsޛl2XyHg~hhttH73;fK99^y$ "=aő%AU䒣$*Ĉ D0(t$084f3lT #)R EQ#7& - -6JaK(g7dXRZ((fd+D"i X4yR,sU%qБ =tKa %rQQn($$\H@Llq^$a;-R(Ĵaݛl-RU '-Krt$bdŦfYQ +/Ǎ'HqWdQ3Pʲ·L2O-ZJm,5/?d^Kj;IHyLui&eYtɬyJ T&M۴D߸fޡ&xWd*=gH$bu3`9BtFr$F,DmaHd9aɑ U-) [F8 -+:%WH1,?+R] NJV b9iI( G#91bAOЉJ\≣C -51kmbXHX—Ƒ^xr24T#IqVV^Z"zEPD(-d#S$ˮ /!:do|-FfnYXJ6-LLDK2W ХdGg;^6CuEHfhғ(3Qb]Xq+@Ģ')b "7Ĝ8Gr GXCѸq +2n 7-*т衆SKLWD*'J%PafrPNuÉ\V/< -~)^&KEfadM6T b(2l(K>!S$`0`< _xNl%4clGJYC6}\Pdv*\S54Z<^^V2cS$``p$& 6h)ouw^Oq̌JGGz.\r1ℊUUeuXUTR"nhijkz8Ȉ b HB'uLr"1#A %%Jnj"DIO,)EV~VH2,}Yu^BTВd+wLRMXbfXv;3++6D%QFrQ%aÅ4MNPBD뭵k&[K*YhEQR$E Ffq4X0 0#1>xaW0u PP8I L2d IPNO`"0$HH #q$JH$,rSIY.&"Gn>u?q!g\qzy;;]bVʬ$Q\,L0J'ffF"d"IWTB =DJ$\($hyQjfAFH0" ,d=]]ﭭ6z"#BAJa8,:_/Oo8C.Ə#O8&e @:rewD$ɓK,'$A1EI#bB98CHQ(((HH) x*ܐ)!` F`'fA\`,("zc `V*[?Tnzôχ -*ygkJUP7 - SLDphA"3AC `*0pH~A`<  \` 0ph@"X0,phx$0tA0p`` L@2!.xh 1h D ED84  @!" Ad0A2gS$`AC"3CCL>Eŭ-u K)jh)a0( - -$iz|b1}aŰ- -sCTi%TcѢ0 -[+!!!_4U%wi«R{zaҡh'%VH#$uid4PqxΌmAsQlI̲x[*qhY[˃m[J52J}K2w/R$ ]uT)NOɮjYeKw{FT3R@ mY"A ImʌBA;D -jSPR2 q<*CF~[hG&%#ZhE:\.q[e+[eP,Uf$%mbUue;V>/&Օqd[&hI3^gm푡^Qȴ&J(D$IⒼRnUUkT̞exwZy?̻K-3omJ':((~`r"Qr Y5(xuEQQ+颠%:kˁEKUT,כV L R3QcIm6M -&@ z8tZ#3HzŒ# -`l2?&mo͸dek=%apA A -;BS4#,.1,kihK`YEdвrTQEGq$*#fN 8=ё(sQBT3AS&p僆G,¬54L%-Rܛt0]۴"nN[z:Eu-µLɵKkR]ڭԿE-duR^.f﬽ zs6|7G5WW]J5[<M]/Dўj7)>ZݩQzٰROgE'W=EV nWZuC\,?v L!NNE\:K7!!3Ev|E+;9;QO4J׫Ȍ*]f^g2ŭ=yGB$ɋz~Z}OJtꮥDecz7Iխ^tŪ:ed]76+OSWݩC/]O -}Mԓj˺Ҟc=9u;7c<-3c{4xDӮЙͤV;7By)?{gFsX?ySZCFFv(-:}5HR"4KjG ꩒ޤ؛V\k;h)3CgdU}̌94| }Yx̕Q)ʶ̡jz$=tZG(LRdL$;hwꝤ:;ժe6QIKyiZ牉GYJh$2D:j+U-Mݺҩ3Gey6D;3{uh>zHΔl!.ک֩`+=syk7צiQGo|?v;}کCsߩMTS[괾>WhtѠNhJ)<%#<չɦ?증Zs֡ז^54;ϛtQ>xIs賢LwybM6;_"C4|l2oG5[무>]v!eh\e+wߖ]j歶.ы^:ƒ1x|Q\P(dҚg,;yvϾ=xU#NBꐕ^njwׂBukAt@6i^PNm*_-]QWyՁcIP(@tz| -aR=|͟$v?'JWzNWKܓIP}ҙ6=e{vwE;О,-]:{ѱMʽ\ܵ ]zxvrtQʸyjUE+\$#Oy3Ӯ;ke\"/%-n}L> -fȶV+nu瘘Ǭ^E=6˴U5t~vf:IY{jww[Uw:_P^I˸!mg\4_yhxߴyg=;ҩTD]D}Cf^yȸ?m,ja>_;),}kRgdyTz*Y+ͷVzʶl֪noMlW=%KYNVهvT伥tiRӘty\'֚a$U^*J֑uK\/_DtR} -3]?^ 7,SlGjg~{KVD=Fe[KSosQ -]%#J*W>V5B]VU-窺zf.:[.ҤCͻue!ݷ[R-( ־/ҩ٥-90ViZdiJuiݭzlZ_JjSiLmoˌk mOhE:M9ZgYtƥ-OWʿ4{(4Mi-f)S{Nw`lhuK#YfJT>$c_nIkxZD3}Ym&+1ДݷeI)R?-:vekiWESWƐH}k˽ӧY<7-9]dfws&ԵZݪn[sϴSIy#2I&]ޠlU@)|V0]:x1!K;5׹M#Y.]LvS|q_uEfwN:7fVK=Kfe{?K{>eS6\Yj[yjL(Ϯ|j]OkZTWsMKsGՓ~uSO.D4,.#1"rf2 * 30(Eyh~j@jH0$x$C@d$8g8a "0"KܟMٹ gŗ@(ze!0CY#@kQ f"@{k Z3px$S>7C^:ɓӅB? \1 VaSI ?J(ڽuYZJ'|8_;bM3#Ң~URkbU.srx^RvP[}WX*hQ@P!Xj~ owdTb*@VI1V7N~QQǰ|}U.AQ{h>7_U=.d_weKHN/ }_ 1A,ox,}@B:|d 5z:N4͘ -apsϗ; - XW$%AX)x?] Q[@IiQV?CpjsClA)Y7B9?!8aVc:QE#SBx0;", -׉Xs?R*!v1)TBW@TݜD75#N\:R_ hyWFM@E*7G@\q[(3{e*Q>H+Ad&1#ǡ=#VD羉ji%Zc˸ܯEΌ8=,jhȢqT|GBiA W R3 -| q4=oDJjkݚYeTN#L`c> 舢E̅ºuQ'YJng _Ώђ,͖$*kEC8/1@]ex̘T1H0I3Ow|c${Ӗ;a%SqlH -[ZKiiY]`iZo5&mϤ_5j5^QYijbF[f/:@EOUԬ"41n<\Ҧ'mǯa/Qt ZDK^@.5''d<tNgWl2=83 ٨Cy%6ۭ܉U$tHkLlzf_:"myACRb^n S.hEQV -)P*]5wn'W(w I=.1oKeܙE5BL(cIp (FeX-us]'fVEr] -0W`Kr Ovt=8Y%gΰN0 t&łr$&]ՠ+i,.h,2~V=fR:HRȠ%%)d0/ɐ+&Hd/y; L:  "`ǗI(suzLY*DbH%b[;$;@TIq.qV]~ ~67dD{bd>0:xj#[ivHm fJ$ZЕOBJ"4m+u~zL,vv&¬pfOY<#rn`V+ "yJx1 mH1W;M?I8ՋfkweI@HVe>4f*\q:.‚zZtA&2uu.~mmɋ.Z~>Ho(ѷOXDw>np\;MYQ%Y$zI.=ç۷!9S;Hi5 HD2܆{ = 6 -PZ &jE2s4!*Ada֞Ox%x#3hi_uoKRk-ta|]A -e,3!|dW3Jg2t]9&=*({6$׋]Wu"/#<*wD4ѹO'J=2\HY@ʗV7Ȕy^l:]~oj̤0"}uX+IжƬ0۔K=#Dy8X#Va"N'RJrA.uVE'-*RY1*㮢AiS_ -P`gB3/&[^\ǔ'TdA{*s7S]t'GRSgHH1qAZ86Ve&.Flcmw][6W<"{ ը+u+M"BE5c4-q8M)-Z&aK΅ m o[-xd:t)W(dax|\GnOnsĨ[Vv^ٺV7cn-!:\&C*^VTkN+_Vg%=֖~7^x 5[զ`ۖ~$A&fG2׬/2[j!X*ZpQZ oLANR}dB`$6Lunn:y|)6ҤڥzIL@+d6:ё']bx$fevu P &6й{Z@B.IM:(\~W^j=y1I@BTKmgUhRYGCwJղl2}Χ`jY[je zi:sjµ0?z5Z_6Dly|ja_ -zWfjd9K$\B|h2qw2 Nfҩ%~hurR4hբoH6R v=p*SgjAf&WUW[+}\DӥjA,۳9pW'_}Vr@kyfvA`DMiIܴW5:sM5j=yw5r=־&?j_3J$%Ds:"f.nDf=!knmDG"ḯ)g`DKzM%{n!xMIġ_S+Wq`S"l5fb+AP!>oSlns1r ;b(| yJb:%RV_7tY:9EG0P^a9*x\ͷsդR{ۂMU2Mm_Ilj/iS kX1VhL.͔o_oFaU <D vTA"ow -H]woD|Fb]h2t?bg+u 0cVnH *%pQÙ%})zfE:3ڼڂY[; .?H彂> 8tPf>*;vFqX5핒,̱ " Ja9HNCᐬ@/2Z( "fJsV!KY{l)ʆi" AenHPeaNz醫7:"!e%CՂ&`0PPO"ʖ\l9p@кSk3Ra9M6a+dpJ@}Cx?,a`48x܃L_Gl8QqE{kV˥6XGhl -x0@If Jyy4€WhLx.9%r^hƠ"D*%;Нԑax%a&82KAA^h'ɝ ytTm; +2%|uHOwN0;6ۭZ - -vkO&z -W٬Ms_qط9;vV -?9€8gU&k(a'+˞zV-kBKQAJ|;T;pA!!ˆ&n)nJ -[Ag}o\#&RRzmVWuZ 0u+z#1/#-YiԪp)\n^DT; FaUi)|Ӛm -bBF@` F(U|H.XAZhBee7sY^ R wqK{L'EՒUA_yz}[GpN6w:@_)OUZqSMoƲm]d -T9@?ݿ_EȈXp߇@ʒ9,"ȥ=Sp$MەT$V B*P9:ǀa(F ف&՞Z[:%ɜԭ:BJV^p˪|cOT0q!lNXbvT\3p?"`Xb[%b -% &,[gpr_z+^QZ>%u(/ -NchZL" PʔA;4*"EpPp|AW bוThoÖ-C%?ܵ@О`|7ps*Qr d6ެlC ꘗ9'3Wt,, SN-ұXV 0 -c未ket߿z MҼ sA~m+3M5"]yvgYZRS3V29Z8kDco2_" B K;5j$Ll]6ѩ 6O"ՈE}QIWsq6jMw!#lr;Ibר^m)^a>[WpxM[D|ڌ {ChîE42&M8Q}8;8fYmȸ1I_\fDIdY,t03Đ(яE#2X`8$Ծ&jL:,X미k-%ܵnUtvwa3dB2_OwڣJ \ ~edi\dOFE+M , -(I%CVljKz)=ܛv 7_& Qy$5&^92Y*Z tcNpĢv\J --uN`qzqSdxFRPNC((pGE,\A`U2$~:RRqAӮL(DTr%G~TA:Ve= [ZT?2z3=/zټ jt+$5<<6\ -ķ tP(H/^C~ 3gm0'.^CApt=M -AjҽF̏X!71l/*kMR^rtfY`S#~7(!aS J:B'ƒ3^aĈ$ކ9BDF[JE*!QNhG -hى Exa-LExNUZ`Zd^J݋@BIija~?{({H)?2*C48ͮ:\ή(l@vZ07)lB^EivaLD"=KDEsPȄLdDyڇ]J%"+(Z -k -tdt k`U}`~e V45R:ZY8 4+(N@@\ -7T84iBxZP$xy ./7e@r-,-R,쭋3i V(tzHuIN&}"]G}Xu7Kz:R@sVu4Aai ςq]t6t: -9) RgZ\`Z;,yz< /nN - ӭXar$KDhI$-ݵ-e3IlEF8l|>/F17p0K׺(&mW\QJ^f=,nnW!ZkXk^=tANnlaA!3[W,\ENK= m~cI|gdqc0yЭ jꣷq`s9:Mk2y<=+MXvHg 4"q^yTc`Mk_)=N('UE'v^l̄9C t2.} ǡ}`l(*%@ 42k$UD/׺u }nce']w=9S<%h.aO3Ymurń ࣷx]Ph}GvAs/'ӝ@mK0,`v9+W4*1WPoџGMUpY-Z\2WwHfz}A>?Wecc"cguBWQY8膩F {snSMm0\)gmjFmD9w2kt^GyrټB{[x9۬ 'KfMC+6KiQ ? LqD5i>pqq3o1I bY{|Ɲ!2T~[il2V[: x,"RV `=Z^!6 z<;CGSRzySL>3Y]ذ{lsκ u|JhRJ](GaJZU|/exP-=st{c^%+;X#=ݧs5uU&G.VȥdV.r`Sqk%&j?,u-T$p9Gk1y<,2’k%if]8)o(}dg{r8ètyim}!/䦥 +dGAǰ :^3FF -~'R:.4w85$d/L/V^DK7[A N̷u D-wZ5p^ o7$ɸs&D~շ|vqqG7i6&n3 LDEUt{_{!6KG} "S1].c>24ܙ! -ypӁ0[3=s&d< `GQbU@T!JAQ Q~OD%:(蠺+RdU֩6L-OSNv%&K1*;egӽDt:2s6#X fDFA-9TQ-Hpd]L6ƬT܏^Rۓ P2fGmi u( E&{1)=e$όhdΧCx6ߗCBV'|S.镤fc#l:ճ+Y\׌ gxM=: FXr]UC1D<1_%[*IŹ*;i$\&NnEm1MNiQmgʇXH (qƁy84:sPݔ\ -<2#]\rpgt"':!6z^CMR]nro0b%iVn -oBW[x% -` zrEAL?J-%E۴Qg}-`mGBV*Lq ?.]'zvc3ƾ]!KO2Tx[ѮB.Mk< "{R<%5BU_YQ|l 7RzBy4K^J7}cQ>F,B@DVðqalBuTV܏Ku,Xapy )~ w5<5 ;T|TZIf_T| }YY|+1k<&FA݄ j^wӦ1؋[*wv--)3|3mnKS u0U}t9z'H`l]ӽ{6k\pQ]3!;?=d6QGρԩΨH_{NL}L]6={k4>Ӄ蟺Y@B[F;gV NXǘm3;!)o{bj{# h?vp$bx*S=JO9í*_;:?vn8w9KEn7UW < F GN&{ɆFItr-tErJ!6C0\CM$ oȓ5ґX#+7`v[.SPv(pB4+pQU8lע VFk,PNh`g/!IH;j"fDq-bzf?{ mox'N,zcs7T7kҎ]g^nvs.=h"`GC'Pݕ?QQt)>Q]0sdfȬ#ǂc_n .wlpFjo3}Gz7}QV[lf{L":YjT<eN&DT"+uUi!` ^)oHU#|ӵinoVot#g\q5mYTq6 'hQ{<'#9nۆcB]N%[}?AA]ƿ6u3g M!#xE1oN ]D$ڋڞQ -jp{l?2uWP0E -h n!chD"Br+!d+jQ=d+h԰:+ F.B:b1=ѽ]{Rso!OR&JNeX(}Eo`'nLn1,X.r Er\S=(".i]5hk#=V1Rt;0L @t L]A"XDw8xW|;ab6~'㠂YKD͈u )Ds@=Q# P.&,xS)? &@CyBɥӸSɟvAq6 -Tה[)YDpj;ׄ3]b%s3vYǾUpU&Rz z_HuJDO ∶Pҵ -[~>uħ9e, h԰+ -pGī(vEP/Qw|kgKPyj3w?\˙ $@mL0rWqm*82j%Dg#aWp Ł0RPTf s."/L5ֹL3\/'WceV;)zlBRѸi0d[C#1J1=ɥǥ+\; J EBQV -EK)W^AU]{<9Ro1 VpuռL(lQ_c(0@gc";u -~ڈBb\ke9ǂy,&Nxa -5c)K,AP4jp~V t$eIu[ čh!z&Z)ٌsOxhpέp?ug`vvdGɴVPO&Kl%H?q]A0y8fFG=޳q{ZE]^8?7*SJI'{u.-`XdZ-SYENijwd] "Ĉ&0hO jV>2a{p+v4fۈu. ֿDMwǺr9f(]}H\P㺗yfg Q6ރzw4{dHN3Jݺb:(g3UNW!o FòcJWtn)*1A}n{ܔN<ty(*nmWWf7Pxn  -O܀1ր*f~])*Z̝'\6Z*FsеHsHI-80ְ\U`^l]iYѳ*&Z$cBL@ufeiϏ^^vPAҬ]JZ7c,=:B֕ -@Z5Y%%!aocl T7ړDžT4Tŵ"aUehFhqd5p޷꣍rw nZ^tfxmhk&E:Qoz`4~6$&r = s7˙cVpPC&#&P×@aƺ.0^Gƶ>By36uNJXJDi闟v@6P'Nb!RNwlL1Jm] -{~*,`IĽ@~WЭ ( \ Rɰr8x[PŸvԵNa8PkueXNPS[}fXojlPp¡*Pj -˳涮q$W -}!leJ`9{D@9QU4/ '4Y::tۘ@1"бeoNc""vǺBēVJo`3;Dy"gDDsba3Re.2h7]\aQm'dZTuآ%#py܃cjuf2j>&4 -oiPKuZ´K4<{7 ՞J?X -d̲࣪8f!ٳ }7 -q)Y@NL)(z{iDL8`V}qm$^j'F?q"M?44Ww& x -d?wkD>s#FB#hϞ.dfчV_G{E8 ]/)y٪VßH*kWچU)0hq_/N`Lb{SpgVCmQNhGfG+@U)xԤ!#Ɣh7_G-&eʙ%&;i/,Mėx}4gybQU…~ĺQ!P̓^Ř+/-obJI -_9u{i[)g\P|.4 %j= =Djmަl2.91t&SK-ʰ^ݡ%ʩ1\(bcDgi!O#l/Ì$7'KIL$Tq3XX8TJ<NNp,%jEnJ/wRhX‘'y]SD"7.}%_{#y(r uOlg:pKYb4RT+\Q8%($(tч:fKWc4CZB TRdeRXAȰtx xc/{'T/t>>/6Dtee 8~{Y;'ڱ)fp)~s AT`t@|ˆD\=bw-)I;{&=!#GHU y^}?@ 6QyXrtBl<`0Lc>d@P9$R~\O<gbӀ)$Cu˃=MV5FQ? -l Vavf<qjʧAt "|D*dSAA h0ʷ d#AyP|$-#wi!adBBy %|B%;>A08ClL'"\r C!{pfqL\׽Ch97+?Ҵ -q>a$ -V+X YdI 4մ=mڦ 7֚-N&)nbUh}k{p2ݗtQ6#A"an)C~}:ZQ=͜[PD],BDxHt2!"/Ty$$.j")N+ aG5g#-= 3hw(rpRK\-HH9`:S'pV;csXF0 SaAFNY$$x}=O̚ -Qx 1l1JgiVkyt<ޥZ8XL߼F4UŬ*&n\9Ψ+=^CGSĈ{V:E^Bmv6fc-'dC "pz+dQeI/PP碚Tbx3ܛ]+wp4%h4%N{ɵdl秉cfܗYIguˈ8Mn֑z/d0`eg2S9&&qPY"q+>+'TmSp iq3=&3˥X0uP0JR&AE~Ș㻚#CR#YG=v%Gˇ`AEӏ -I\Gt\nvfKFf$kwapq%Ep). J ~~4SJ$#2@kUcfѦ ˨JBUkh$zQA)+$4pe*{{@^uJeg"bIP`XzHX0hY -#6~ -q`ao}cfLXN;ZTJ]dH(.yB%Tǿ|gD>5m+mQkJGx+7u: 4&Rȟ˘|rEOev!\+/mx.I.fXOԅ)]sAKA%s kYZ''r0J"|DHITOxq~Gz<[u^p.܇:8! -ֺD{2b Wr{y&2TsrpaE=<A*ߙٔӣ/06hyCʂyT^I[=Z,*ɯ̙z3c"}7qq"9{G&e}ܒ|@G"؞'[8#rJ=dkBI J) -~] -yu㖐[B-sdGfAnԋ)g=^:%d’ ->6q(Yvce.;>6qe1|~R~lc%?֔C# H3ƣԧ0\ -@,COPDt_&і~\}4Uq.6ϋhiNw<,CPc*MҜdC@J+T3~! - e1NlvӝzW:AYVUHDA\ކH?P$XX4S)k*HP>ia˹Z"˃;un| ?i^,EwM,ܲ~1̮7<`-F/zg g˴G0Yvf!Zn|byZ$nԌ]Be[i:8䶾 آ#` !N I\D5U@L/Ұ f۰ V)q Ϝ3) 5Dz򊞢ӫtlSS<O!<9$$ufIBI$o$a>Fd/~1)dc5HC, 8ƀeSZ-8sݼ6C$8L#eaK bd"1Fa^"bP3tKt'L^сlQ+Qz:YfM6* }J*0}rX}%DƠt<"J7ܿ*\eT5,}gn:W%ZSF+#/Ok&e&TB12{8){+nմ)ȐfǙ#I,'LR3 -ٙr[cSh֦TJ68~_ʒ{-9gPxC6unOcV{` uw,bIx{Fy=[O~|/f-Ofu!wAFkmT ԥ)IRJ$"*G>p]#4<46{{jTWIw.vЂq7vM H)@_QN"aO#|L! I(ޙp ?52faTCcG8NS|u%CaU50ӺKР FP~RH`co"k MFIɄGqThk0eZ-79P%L(B*Hf#vZ|ai1ѮU -iI -=dW)%H4wwiTB]Mpت1D9XŊP)c@55_QUiq>Csp>ܜ q$r!'F_}RX+Č3s֓ DFߡKFL|2wQ9brΉkf2 -9h (v=d D׼i5 Aw*1La\&ƄVCF{Pu1ZBztlU}dugnj]4E$micE^3 b1C2FED7 -* ŶLCblT&KW.RpЎl.5E`Q -đHѫP,+y$B(8xHQ':A$HK㸩eAGay)?D E1ml j)~[O?j0؋5}"'Ȑj7Z83DV1PcaS(Z4ǘ>~qruPCj9[y i=BhxKUf>"M4.~JSFվ"^4ۅEZ֖-j( q5t9Y#tezw2* -w"M ݕr|h8 W*e?~Z%$g3"Ҧ"H v|h<^IbUH&\ S"W 6 jFnhv5GN@5 \ZO&,*Ϲ:$̪ò0!GIXdWP-85N4[B7fKUm9כrh 3&>U1V"Uaa(Z.ʹWbmdR#qcV$:V6F36ۗe.sLfdOLe!X&Se_!c(;i es-r@sLj4\1Rs;ϫ~bќ3 Jᆈ\晫+<ϝQ?DF~6WѼbj쩹=Sjf } y=JOg -˧΢$LTޭsֺWVĤhEU) -2moXH8S&q MRpPKUĩ. -feFQrPS3*A QSӗ9;I7EwnRj ZdRRQ^ *>Q'Rܯɡ|xB?.iu8J,[h,hܮP>p idq&JW;_QCs.GME -r_\d}5FSUdO~aЋV +7#w"F)ѲGGyh1%F|[ɕ-Pg$+:濉&;`TC߭'"EESsY/5\7S[%VA7Ƀ:qEW:b Ѭ -maNx@74fn:K<vea)1TK.2K[bGIL#N=GRzI˃v'L'fW881!E#X1O/7Q61= Eڇ=.Q(Bz'E1E̥LGIGCj^,4{S[\Z֗+j< 4,V'[5ari.hxGSQ8c+"IV\L DCN++n<>S+]c̋L+C#!nZG;=ê/)J96맗 ~!c:V+"(C5kQ7AZȠַP1dG9d*JW>J.p$hjQ:+* -d3R%qhZs0jq! c,F+C* -(8KeN}\Sr{W 9w|H}8uFv4DǵP_ u&ItjsM!8=l4"}*5^HRjOcbjOɭ=%)VHi)ޮkj~!aH( AkkLRHӊA4ZF:1jO4F+GnA|אG3CUYcӪϔ]A;= >`ILGS:dx7; -Yҵ䤦Ny`TS0>\2 "QT3f3HTPb\)T(JnQ>D\2U>YEM~ɢ*!'LPc%Ȣ13D!bXk*J\ c>H Ӣ\@[X>U5y9(S$w\4A}pQM`3RD(Ȇ٘WQ"+MdCMS"Brlj+p3;W^ ˯;F)yM]E48 mCmB)F£W$Dz@2ͪ/Lq$tFa#HO(P=y &_#yw|$ܚDLԃL<' - -q}hp^ͧN'A({cjr %\*Őh*0mD{BL#FՈ …BJ4>P;(rEMiC6 C#%|P%xG8[&x6q\.69|C; \r@s-p)U""殩wS0Mi0=UU¡yn ˃q1ӄ'By0P-[ahQ;X4#ZY2s9lߦ:+@\&F>^t$ Ph@, <LF *`0Š BA| @$d`r#tb9Yp` -,R% *Fk'j+: -*`QA]C -NyLFLHV _F6 '}y_+piP#4NGE"1bU_DىW'8.!-*-(k]*'HHi xl'7*%$R'L\"O8fh>X"(hM*!ЩPv¥Vh$STbkB$7s'dITиV=i*;U)Z5ZDU>Zĕ?VoK˰C_̱ўvRXR Ԩ?"ɴ[rEV,ĸ7UP$%XF;ĒAK2a{nzR=!/JZ jDO|U&i1{N7T,Z{/HO 7`ńK< :JfC$*,GgLw_Q/3fiUM=D]Nh2QRQ́v1NfY%kX*lTQubFltjZ.⚺舅 ף TDT H<-xTJ*$ڔX-JSt@2ԙr?Lk3Tn\l -}Bj@<A9Х@Ȕ6˼EhAp[xUdjdY>LHVoh䮟57 "rP T?પDF֢:.M Qwg"3EZ$J1GfiVHPЅ6(+|7yɄ2-tj2$*-C/%b"o["fHb9VrPiMeҏYDY_Ք*{H1JY}$B"BB~HžRrjLY(,9GUԕyNe\b/m~36E5v|p0!LbE!PIPƊc1+H*Xm6OȈãEBS>SY"]"a:gΙz9B&[{^SƉU(1&5DT/xjCtU[ᗅǨDYX/S4j\Q嚗DUx4m^A尜bEp3C$p.$^B$, Ĭj<î(+\<$K]Uc5у4IFaFIO,DJE"xttO5q?PzPZ'T1ry#+97:O -eGȍKl6Wc]iLSM2Q2KT(9)EmE*慧2ĦHEDE4 #,M#l(R?X9/aEB8 9pL"1^5dhwcEPI*.Nӵ&&$ &H+oX̃P DSHd~ߩqƐ/}FÁLlࣈX1DD&q| ?5Ls7Q^ɗ єfA%QP+{NW?Bl-nfn"%H%DT'W*e%+TdzIʅBf}+fuӣk0G$*@@D`J:>0@l|9RpHםԿMSp|UڤGE P>i~tLV٘z&2yr'TF'մ Xѓar˺@SJBDE!I]19;fڈN{x xH9:U"+A'_.Z(7Z ٘p%|wKd2Z'ͣ;}+FE<)?@=4 Xd_. .]إOw6( ;& -ze)vs0ه*GN.nɱ}_B2V{\S%w=ZmǛFM?f;LZ wՐǬzs 5 Q+A$'nGй)?9H UN  ]5uߞAm,<2Vqr-,˛UW#Յ]IbwVc!eB6liB {X*wTjAG9y+GMXcGXkZȾ2^ fMd˓kX"߼='LeI袽)lq9ʇ%cA{/tuP)n9Rr7i$6Mzc˰GfSTimHS.Ѣȕ55M6a֟ -q Vx^˓= -wϧ -6[P\γ@UgyDo`}օ_m,qZV)DzsU3MLƓ-AJ.GǨV1*V5.̖^a\^石_훐`megE>o2ʝ'@q8?!WZԼj.HxEΐ(`_PĝmMZoKԔߓPʹ`ʊdSCu|5`VϷ5ߛ |OM]rҢ7BlKYnj13$AhN=1kč1Ap3qaWAɗ+uQH[ -_R`͡y<2VT+C>d<(|PNY:ԘflDtB LJXMםoL{Ux %x%i;i? -j\`@wiZɦJ8CpWvc֝XB|U`1^)׎$@z8PcCi{*j<؁+7$a Q1H7Xmv }\"!kz0zISPo(T1v:y_J9VҩAp D3oCag&@w4.}z=y[ĠKh,S%ЇCC (90ruC !*YpMʍv|rSN=\ YE+EЕ#[=g_/ݸG7[I 8GҝO q&'ٛ`-R`#znj-JB a9(*fHafņt˗/E5o!MpJ Ԑ~ĿN*`C8'1}# ȓpr29 $M"-]dE"GP -"UM2D) -`NGwn_`,f D έ|xIz`&Ե;q._)"TqvЬq=B jwϐJяMF˖$cëX 5d:cN#;"1I]Еc(s6 fJ>M[q1,m$SD"䒤$s035Pwy.Q(έXuUv|܁YQA)/-::>ө&(=1Wf; q[H^r.?h[^̂ߙ(D)@EΘyG0wM8hkgfN ;6kXJ4)ԢReH1>yB!v2 hڍru^[ `!OOQ{xbՁvSX>: />#!ۥ [mɆM98?36G+( !9 I C%!ⵌ-t:Ny,Nă^FhOoCgz]+㵕6DBc %3Z|(B2.,n3nGY 0ޡ=ԉIA2&U{P+>+ޠeSgGxF=-fŞ0d6R2+1 Ch;OQ yY'^^ .PHH(dQྠ*hc~Wp.hQ{N5[]p8EslC -P..#n~ȈFyV?c 38@n;r1 :!Rfr!tL>ԹZ&k(їǩfLb:6&b([UÊ޺^4&bvd$5L” ^C1; %cU̅ >Tw$~QGFQe*"9ֲ^HOt~$ҔH+`LH0!Hbe8nDLc:c]O!HE@Bows1*ٹ*Œ! -£ҧp`ͯZ{<",{5S٭.Z&Dh&wKG)G\#i[AQi~Rʷ/( H*T_Q/)JR֋6N -$Z],zj c&2RK[85D"$ YIHspY ~=rR0^&&Iӻ Ơ^:e[<.3UBғ^Vs)K}z.,IÀ> (Y3b_\˹Um:wX~;LG&>!ͣO? {ND=le`Uc><`@L܁8t0%a'd'tɪsVؤa/6S *pߢզ{F0pļwV27sF \%SI.848\D/mΰg$0La Nhl.}88f˃Ab}OI.p"Qq]2Ƙ-ѽy({W]A4HPyv3S!g(HEg{+`'B8׋py=5i2C@mbP)f} -=5A@! 4oOzIڋujE8plF ߸JI/]\&OohNʝxeZ&tЋ+jL.IF 'tҸ1EBe5+yYi)cywdj o#aJ0ÖXo\Ǡ)[&8דKgf*Ys662c^ؿFScO)CM`'԰VHX -pC`pwM0y=/ɽw:~Oc)Jjgpp@JB47P`+}=$!%>L$,iMƛNH,XSnܳeaIϞQn'l7 -th  AF0.dåiqWԯt0rG2rpR {2QmCcJZA[2~K70B>oOֈx/Zai[UE^"}qgG8,yJ&^õBkTѱAwT6NE4\MiC>k5aG/b}0Xi#Rt $ ?2+mjv0B$D>NJ@EM6b5yI:iNNօԼye㶵R Hn,SB6 qę" M홥:b=En=flY[55T.PS^8Bٕf~;2L!i'/jtARpkKOU"hO{LQgܰWV)&QJ XD`gg3cP,, 5#DwvA덫$Awy9A{cږ#PЮ}&ʁYR~ yo Dp2 eʹ_ 1s{S1!Ŵ$͸i>ʊ4۬^z ص *hL]nim^R91|⟿yC -Ep^iHq]e2"zi%i^^Auy} NvKK"M%Fex T0!=)%#?T֞3/.:%9u cL9ƖId/EM"Xk(&ơror1zkܘF#l>(X+H]t88Y]Qvu#?I{kW# nz΂2B@9a,/&oIPc(u#(%$Qg6'5ٚAhaY0NX@վ>SgEDr'B|4<6יSˆ?]!#ֹbxTjt,_R#EHc(B]P<Ⲯ~Ί"Nڔ Fk44R@ęq%y$4OJ}P(61O)tGNďNϖ@t8mTs=Ao، +Ma(ΈdwuN 5ӄ\g9Ku='ge,aOTgEMJՔT"5lI2fE5=*&nc0 -Av) bXZsc߮H'Lډ|qa L1Nڑd615kY^KfyT -4#e[%h@D>cӣ -eD -}\‘v -Q=Ȧ5A -M4 :s&la=%V hȣD:bRRHg F /[ˠʕAd$:1p`,@$"0Gyݡ^)E9~ӥ8v Њ&(Ud^B`~aj@P<#]l[Wk C@`~3fTId#j @NH/T~3eCFR8'w?K6LP7E$D+ '$ n4Ϥ=uJ۳@0擈Gꈳsl: 8H > |ͥZoݿP^"Š)n+x?j}ÅKֱ0Hp}+hy|8[_:b/t]aoE}%AuUEp8< XԯHp͂ a<>k^{>in~ -BBٮui˕??4XnC.v{[K:y%9.~&@Rg/T A+vI kՑGVŠ*xב B‘S{~jƪ!4:]BBF%g;Q:HYˋs!ŘU'zH mpamx<70{<.6LEX gǥ2%+իx,Pr6RxmSH'B|fq >vDKؖCdjJfn4dG'<Εy\M Iw ߉Q;xS"k8H#T -(s%95`yP"O )e]衙2ޢ9& -r}UA%N O@_Nq% &1kZXGpks](]#͹~3jUjϓ ] 72 -%?$U0 -vV5W5%:r-n"V3"q~#vF҃cSHK{/idpS^O -"B{{q4]٩_79гf&&3O0g1@C9|_#nB0We%ɇF?@톪&<4DX5Qf7J(|!QǵdV$zċ~tcN xJQ~DX (t=d ud|qbܺ%I{5#@E;™,,%@ -;.mu&ɢEMHY>[-')3Ay{dO&(d=p5=S{CQ`-QA56YAe`Be燌TW7CXE̅i{GUZY(&@e?啅q,lr}e@ Ti ,|LrO6~NsAbsp+0;بlOHszQKԢDgnr54t(5R(/(\Cʤm`jmz~>?1ZC M}yM٢e%^ -H;anAM䁙x8 /^ > - {*w:\10#!LK<*+^H-㐅֞w+*kpL Ӓbf|Mrڞ%$q@0t Cyj"hܘS%n+rFSjGE_vfmfpXZൠ@w,y+XK 8`^R+EpAK˕3eDAMwF#f\Vngp"pDd 7BI{哵y Z0y>=d{%NjC*MW.EVn]r93 a5ЪG5ޞ8`9 >s nQAE&7,VDBX4@9!?HUqđ-R'SA!S8xUpT%^fs'S=U/k&,vv;)[!\c.T_e" D`1*N-{s ys%fOY&ϸG:\HL/ίO~yAk0v)/q +Fܧ -TA" .S܎EXA?T6T,.㲠zpBtzi*ZҎ渆FxR:0\\kAD<g2;hz|V\,heq`O}<*Lok%ӊ~T$M{Du+1 j]oi( (}W`<3GFD{!)7##msu/Ϥ~Y f|;:zK8{G5'W>q!&e wv˒rBn df1 G ̐R.p,c(=8pF]tǥ_S>GFL yO-`8%!LbƈK)<n'"e$ȩnBIPSSMR7"\ ' xK~i/Ob[1bQ'\VHfi(#^}=ɝV@ջ˪Qq1sjcb$i@N;ɩP. &?h ~TD:&,p܆*& -B/2k9b -eKG%ÙNAfṣ81<w¹\[5ü>=3VW@OqrʗHbF>~U.:)ITOlqwp>9:nbK~!tYo(pKhPA #ri\Tx8P8M)p`PvI D}.r ^`x;zznAS/4TJzr  "x$ -8' f`P]+Y2=q9ДCe`lm@X_k.XLE?dB"0`+#& #LhdD*]*4Ddt+h}5O e[J~M#ɿq@L?&)Sq<>h9AeeKjSRp3kAQ/}ڐЂNSD>cZKtcc䜆QzQ.p`ԎVf@ t63ͼgʜ֬e ^BB -: Vn)Rƪ9 `xH=:bJ˱jZjYKFIRHK;Qe!29] .xeD V:~i[]xnݭ]+׬ۭ~DevU[M魲jЕaWJl``ʳPWΫby8Lr[aY(7v,ȍۯnHq;l`͸Ba b cx0pܲ/P}!\oWd+FfvRi?p$ttgdT`m#-$m8Tv3  zS~o>׳C0;[SK!HdYD\ch_3a}mgɀ%+DBD@, 0$񱍣+m5@⦱e-(_\ۋMØ-ػ_V~c6&_=NtQ^"r9+BIWQOO xoBS bZB<0G!,R R˙xF%m ͦ( -JqDaCv> F}b8Xh}_cTd 5F5&]VdGERFNȘ̏J7,q^`V׳f-:X2ka280X;wT4T1k=]𹰑,ffm^7*5?Y#x%tog=K[!Zƅғ.ޣJ,;AKø± }# }^Ƞ?[{H䚑/3rtruaXi5k_CՆ%d+]}Ο{-:"O{' dLԱLXo(`u@آAe ɞj)UR\qؔ , )ьa}HiZЃgvbl/ 7JV"]xs b#zĠB/(čcf'JƳ`^kYl|>ɼ[8+_hA"XA9@bp8azdF~t;6t{Mb!fp~%Gf!My_vhB5.byӃyb !hTxPhvϾ'5$M Q)'>F+98)cV(`ߏp$ܴci00KVGK} zIrk6,0&vsV#V`\w -DB-[bz0/*Ҫp 4+yXr -bJѾ{euZxzP%FJbMnk1%QVv%݋Q@" 8;_x8P)uNGb/hѶed94npB$qY.֎Mg>:u)ͰǸR  -\v-'᡹e)9Go0*ɢ 7%c8P8ښ #*+u8EpZ -9A U= +،3nʻ`nwh1^isݛKqB@@+Q|ZfPoEZEiaԋ{ Fp̮B 8KA Zt}"l DVlr&,!xZɰ(5ӗBaijm, -`>ee2L1 ceiSӦrq?Ft:}6S?,+0vRr*TNVEoڧkp\DOE472vԦTR tJ!M$l- -1$beۈUb2D}e)$``_c>CV2pN*|0pvi$@2Dg؝*0SڢqUl( Ӿ̈cu(G]i(Ň,`r2t@T/f/6.\+aj Jpȿ<\DڅHu\W vӖF]C'=#Sb2><ĉTPFM4 [C+@JRmv8M8{ꃫ%d9AC `.޹ Qtcxnyxt<oP_nMn1Z@-&$7|sZUtCuv]J~V2'kJƒk{,1oaO2 ``;XD, oBpfIx -j.}=fLcYqE{D e NtFZ*!ܣNk(90'1%A{Bk0 6K4BxO,+ՂzpeØϕ?VQեɔסYGNFh6:02Y'(I dD*0TҦ\ -w#"^G >W_p4z3F{x|="]'{f8KvCtTyюԬm\|2&$ŌTƒKh 'C(vt4ƒ!10QԽ{knU}?$I.Zy`̳C} і#G aAOb[sK:ڧݧ;\≠Fpakސ-:ƻ)ğ@Լ.n=B2Eue!wJ'*J}B~ ٰp"Yg+/>#/`Ɍz#D1Cce?T[Z\ MX5n:%I3op/=CZuq1 -g?[ AaL$*{bfZ\3|P\]2;U].dМ;9m{G8!zf—!$_EI!i2zV`tWH}DJW^U~EuݓNw%QyC!JpAƖ%%ak_햼Z P̲284΀?Fiȍ4^9,S)A =, -|{X?WLpvZ|ۀe:êoBAQI@[pAv)mc|qm)OsA(yd)aE/c9dSW*2)T"x2Zߝgb0C\D(`jiۘ)Vt pQDΠD.V0j;aJ5"LK@<]5SMG3e+soի3ō{D /=[ldZPb(;D8mQX];6^$,Pb< 3c9i,A"g@jT +(TpƔaMZLQ_F*=5N$pJ5Dkv[2/= '0P}ƠhҚĶ8\Ѻj\/udDB8UpDhF;U8`R],πlʡU&}c.FOR<— |?*)Vw/:}ޜeJm$4RX͹ @ȤhWߌd lbU*% lа@ːoI]IJ' G +.*!G4l- me5vr 5?/w]uA4HRܦ)ۜ'pGR3I0Ɍ.,ƫH5?Uq*}CD^XGfthXIaѢTЕk@*K'rwn2CFZ30=$IDHA4| oCD -+Q46OB`ˋweP8H1+Q2a -8_02ؗ<6nw7݂)SS\[3 1ɆO( gXn¯) 8\67u,4B *rz7plt~xcD֧V[rDx7f*v1e9MH olwa Di;Y]Xtad>և%q%%/-ΰJNe{+O#oMoz6 VǯJ4p)4kn!GV'8_NuHєI8 )pW^`%@4"8&Pul7xHW 9Ohdz(6ܽ/!K8YPg\l2HEZW-[ԥ@5"y ҂ Z 7ށA81D4<@6x8*IÀ4`Wj^W.;0dd4$ێIc3hmk\V<hySQ BUFGZ]CXXQVd'E'q*ڟ 0<3Oe: f<ݦ8gp3O!d{#l7x N{!Q:U?m:2:*z!z -&&833_\a⻷"y Kh#_c6֜&rrw}+y#/@SuO0t`A=-%BK|" +{qY/k(O# # a !?^^^fʼn #gRx[[MDntʅnҏ4iWXF>yhI`mU,$5KS~ mw)%^O=BT@?:Ĥw'V;{(U_v~( 1=A8!.l 0 - ~ 0n1$J IK]qaLR7>*v/xb6BGd=#a1Ɣ_)!֘~B|UJv&{ju_Nur"Vkp_ll8-m~jǒIvi)䖒`.R i[d'>n3VugWtGv%y&Sc -%Ȳ!+^fw{ Z6YE}Yt> &.nϋUmR\wHXb_ -hBIl}˂9^6*T2dwNpFLM&[ ~b³O[1n[bPi9* )DOaq+(SXoE(SoHa )tϷgFte -4>S.Ĥp0:6 #Gs?1L#%bЄ=c1b=XhlN9_Y8ւ$>$WZAAHϐ 2GH0&ی!^BO?p!s;ʏ  Ja-zgU--oD(u 0!lסɍ:=x=K/sYozt O]2^DHT#¶WK@I O5j@,S%O`D&~^ٯB\!J}tZAc&m zaPPhz@ Zg &@ iO>9[ThzEoLA/_ܧrw AJa4dY9a%]2Fd8m=Iq2L1"`ןn6<1D O u͓TV1ma[k8W6}! \`j7].b WoK6FP~A̷ jmOҢ1T7 ??zIݧ nr)VY@ynC.Iq$Jn ‚*ݙ%-Yˠm OXZ!^҇\h -xbHaEQCl RrKֳJ!PI?}u/ں+}^] @'a4w``*l%~Z^yU[}>Ah.|rQJr)&A-'fy#: =M=B{CqX)5ػH)` U26_ӀwzyFl:^WXם|~ke5Yw\t`80|'I[ܚюݼ"h;qS;RN1z[L:&|n.;4xPp -כ[EwA q]c5}^oL͍yߺFl2i{3u>KzWR -cRVGó +$ȇ2IA՘w-1ݡu(n{d+̮?reWI,|׷ކ~/puU,Έ(~ R1x~QMD#t(ez4|F47h킄 -_Ћx11L#rA =a, w -\R -P 0C%nUJt6rzcoPSc sD&Nop0 x᠑EH.^QVY32.t_㣎PVAhR8+N<]GMr=|CXO(Q$Jˎ Yctu@ 9}P% -<6 K4h,%YY~:* POf=_.'(4nFYBM[RDS{Q6ӒXА̞y ÓV9&əӾz6 R,iW DG}3 ,@% )9P?7GKh*E,PeAP=q$;tkjXD27.XT*dD߃}tHޱ/CHn4 #$=ŐT}ӿ҂IcX?1V!r -mH$lGJ7$Sݦߐ 7$5nK,` - !1 5BIj0Sw{iP"\H朂ɔ^ v)DzDhZ#HX] -ai"ٌ&8'K؄oC8xT*@'# >9`۾ lJX@0-Z@\cS4WvggYbѺ$+3>ϐ?6% B]s8ϡO-%,fer兰M񇚭X f.GH ?:>Ma(n/Aȭ.ut{TCBl?C4YlDV?Y˺FQ$pA(8H˟'qh`^of[ƎETޢ[+6 9tu2ܘwjO:џ{g_!VFY57ykkx`'G}t;9n,ԗ3Xh[ W&}GiȋM̈́؈47 -٢ݏ_fyUҾa@\?P'`j}4ι ׁ^KdT!5xӳRDi@)NnN(glVOx`arqYZ}u(sҔoX(wp|LjwlD)ɍYv'& u]lr˖$'wN6siZVe) 1&koOwKQvOX>My|闵;kC }r̋Aga0Pgs]ye/St "[`p,m>%3Z!S>bwrmeJ'%~,ul2H4$-D-gDT@DbO!ƩI{2}tpsDec*Qp76maʡmV?vt[8^*%lo)#0GA>SHnI^e~͋+\֔F/5\2ޞ#?s=)y!Ԩƈs_T Qwe@wg~ޝE6^O cgF<4r+ۓ1j8NԈS=5q@ܔX8ў`Nj] B Ș=){vvJ J zv3(շg<'fͧLKACǏB[ʨKϪMm] vl\xOu mgE?5bž2lcrS-Ktx6xP%/9jݳΊwtTsif}t`[ʂm[e%1 -I -Sfp | W{ꈿ'b=(M'q9YК@ϱ|;t=ԥv&^E ӂApY2U&ۦmOһ=+"jo3xBO{=}m{ 1>rQOjCwNsT9 j'J%Ph,j=L96H$If:7&V (mu[ϯñxT@ e+n BOmRBy*T+֡k[={^a8χxYOBr`A9LyҪ =[B%),H셞; oq=gPgJKkJ܌+n Y]aDfqU=ۖЧN)#8ASfyLl5=9|@=tp|uyM<Z3L +b&}Azf]Yn'{Ap<_jEmѯg{s$`-Dxyd*5?/_I`D.x*9%~v;C|w;F -u=P…f?>i 0TtŒ5_r#^cI8H/Xdx NyB@gc%z֎Xm<Ą[?듊#_*gF(WFЍ "ǟs1"L@a2;pӿ1x>d5/ -VmzSҨ4S@R+V -qSz6A 嵾y^{ x8n6K vSb`@Wok,*m; 3 OMeKC[xsqnm4RAsZ.(K%Pq@=c4hcBpRdˤgi&rdpچ3F~d.6r\6_йDfgl|"FfnT.#us,Yz1C8et lxt`]+ρW͋ "U)A# r endstream endobj 19 0 obj <>stream -VNߵB5xg`]%EY˨Z,T6Ɨ"3pz.2yǏs=wL8Ԛ:\%0r\"B!,˘d2nag[nǂm,$5T^mRJ~%3C~Y6l+ئl2ĥ]pv SJy%WJ(-bd6U!%4@}(S&ąr~/[l@N mIqmPl0{C' P~6pPdTIZ.9A`'7Oy z6|o1>"T|r8x9bM-G*["<5A IY¢K!**dI++d=Tr*YN -%#L|f/LV^Ӽn tHIJ51K-,F2I[!4c2XZ IdHp0@wc!+U"]]{iu)qwtӉ;Qŭ5nt(TAB3A#?)MiT+ *qr7,͔<a/@YD=K?Kˑ98tsP?&,N]}ʢHŷ("#ay9oAA EdT'b|DƫjYD%آ2J1G/T,ϋUAW= gW**wvt%$%̈1 )E)YJn=[O"ɲ$r} C~C h1} Ioatj&J숩rO8VYŸ( -#j! yek_bn^ j?(cpNDNyFRV\yZ=Ni (u88>+xIuJ'*^),\53%wIRJ֒#a\BD!~SQ>}]lzzC-QJ:iݒ{iJAO)85K}wjo|{]^77LX֔gxJ_H-jDLM,jbZ8B596Og I?G -_ՆHmR|bL -2hXZސpqbAc3n'H bw!E{Os&0߇~, -@p@PXd6^#WItfbG;_y ^f-2fP,_r"ĻdFu@ՎLy [yġtZC1{(2L^c+} -FIƔ0Иr PF6ĕ`C P/.H0ه<u3l$ YU͞,E(DEP'KXB!rU=`B&b* ӃELUgR %%%T(At9!! DT/ŊVUݪ,M; n9J~ٰ&UQQHP@4ȩꭆjB>i"h`[#}13c2:S*)K(Uq>u -8{^3CiD|RøqÅ\4ęk O4'bDC)D#ӆ,&C$ <*phQEL 1D$4cnnhFjT STgvU՘c?4Ztu,c+D"Lʟ)/YubdSJBZZ)ߍ屨N,Q$W[JAUyO' -reBD$.TLY~<~z[aO?zLũRtjjʧʟW4?QYGym|φoxI#y}LhTu5^U:~}Tu$/]jv_kZ9=9mɥrSר+S1yczfًxB#믌2Q+]Y#WdsDM lH'#cD& 1zI̠x.mdJbxpd(Y/7: 2znB0"P -80aU°0dva P r! T @N~DAф]e➮/th1h.3#:2$$9Ɉ!>.C"F}tFfKN85ym53#"3e4};-h-֝֯36Wzwcbq2*Eܣ23cQgI54!s+H|=Xڃ%SFѳў\Q;ZZYL+vsk~o)LgJ<4=^kwC}.=Hj~U,<4r!NhQsawd(C5&)ҜX3ʡQKDf~UoXIX\hÛ/[y2Oș>$3yx*/,QZĉAD社Lb>~5^"/$QFc3]#~$9R4hlR)hhDuvދ-it$^; gLh:B$ieGΡubD5r<9`C\!kKֈxJ% j&'bkY4TQwUŏV`D{ -*]LWMm >wWR=))/XGuBmI;_ć#,w^3?18R=*RH[88FycK\dD9XrQDj Q g<{pų)(1H辆ӏJG4~.0(NHvU/&dҼ qEB#E2CHiғDDRDY"A5$i! Sq4Og"(W\/ɞMN O#bsS.8HX☣2F q(w8 ;$4ue~uӞ٤;l㾄XwX} ktO)*ȑ/1rg"n y"RȋRA^L9d c2,YU! -LMj>g3K 7r,ϒ\TM쨕wjIݰNVu4qriD ş7{uGޣ_sZTn3%5~TNU1u -*ULu'e]ٜm\UVjd% S6%3 TbJ."̍[{}1mFkiD[uG0D!~ ӫBIEh|I0a";@[H14_C!^vo\ --z@?DSLNX." - Mi!`{"3lVxD<bx6%YFtL-MQY_Ԏ.|z9IPW] -=\: g2HXs 1LGHQ>Wbٝ!UlVAMFנoLJyŤ8KRD&REBj׳=aTitkvGDGI{46 N/xU^,I cqL יX'oPµ6lᐹM!ڋ>چ㲝ݹxHψBanF\\5td5+K2KdRRI(Zj -Q+fh%qRx>!4N" jn㪔W< UU% cx7I?ZDibG# ?GȿsgpLP| H!6iIl|)BM&lf<@TPD -22r dF. -C4 -T$ ymY|5"HrYDq®pNkfMPDrrϞCJYU3N -8@3C0 -3ff8j E-B-鱩sHmEkZm08q}BO`n*":6O5BfUBlJ%M|*{|1X^D^k9m,}j/$V"F5ej%IoņN$¥ѥ+=j.sXkڬP$h>aec`ܒr8ŢYR0VGH:Q]#+ھ2ju٥:\#$9DNFس%Je5õ5kVvV1AÊJE4%VBڅ?x0+FV""O#ed?!;ImO"ͅE7_#`h _Q -NttESIF9_'Qgxưeg(WZkl7.-G޹ʺAY" Vͫ(Ϸc%4NҠH⢳VQS␈HG~)xc=H5.-aUU*3i7r1's]._nN-gQh[Q\pUB8 %(]"-KIE !#K%q4DQ <>Ԏ*e wf'''-IG( -mq(o#P<q78#W?̲NNŦSQSJdTa;QSqbHOUZ}85hj!=It$NS!6ZOmph)iLL'ZrʌCHdD}}SRt+tTRZiI)nj#D}DQXASL|JC!SIOUn9N\UΕ-u%FZF҈=Z2m_PG[3JM+l9R#֫i [4avR"ʌvghXF%&rvɦL]iNS.=]2*ѓ-ůLXYڡ^5g78O#-1A6:bE - -rB9Q9CN\* R8!Ffܚmn+޴8&9Tr,gu1$>K|Qx*GƍJZoo)*+2TXLT*(S2%p:k1BH֘AeD4&+R2CQ:AHbZoߚdYЩ41ÒKk|qy/*gUm9!oE 3"q+,:R5AKhoi"tYU43KZ >7hʗ2ĉ1iGIz,FQyQ6ө5,R"~ ^n1V}׭4߬/gkʍ[n܍˘ZAYSjs -),YGq2l%J"7Q}NĵKq|zt&lF.%+dkeG(us;fJDXwrc>=hx*r΁f!=lB-%' WS -j6g" -2ذ0HD5DI okJ1Mp@oztTuIq:) Km$Vڜm8 -6RzbB;~#rcjpu6Xj;>9P@䄖Qh[&SBHt!@jnݭ#4&qu@h9LwYI31% =&uD &E W|`IZ(mQ+6,C Ass_]b *ڶ}9ŀpI_HaRQxf~("M߲3D\+c4h7HIy+\2S)K3侖tRƨ$Ee-3А(E8޿Hδ˙ 9qԂ\mZ-G'f?>g0hb뿐ma:H˾w:K}rEfA[߈l#Ab'7 -`wK9"f%{h%uz$QMoߠ?wd:_qz+r*m?֫$F'!)"/nTԭ/Y]Ǫx_!/DM0:qjNF0r8?3YIO|oGώ˖Ǡ߃y~_PjW63x"(7L茕X$@wJ;{?Z$Lp'u@6w2+?pDECT2]EZj!aѢwfCqSƹa_*:9/YgvA{}WA5Z'ʬ_\f9%֍@nm|t_B'Ҷ Ę"O惁v>wϿ2 -=˓QHk~B(HW]}JH K4UY7PdCy-ۀz2qmXOa%>ʚr&hV܇mTH޵ 'S+i[ Rؖ2XۊBi|o'%SvH~Dk>t魠?KAU[wN1SmWP(2_@f 8>y*=g#( t~@kKras<5r4n?sMt`ByH5lM]+yρK;ZBVb#}/y*tiB]uZ3GBb EҒwc?acsc eQ`5"i`c-GR@LpERS}r)i0Ee tԴ^@kIXx p"^K5ge|=\fDa [3f~f"7,1?XZLo?YJaQ]\.գx{ۆ +BK`FQ0/?֭W7I']Aj03#%YW_qpxrv(G}ʒڣl=TgLS:Q13b=mv2L5bWe*'b%(CR[L w9㯏hVu6S% LbDbp -lcCKwM -hk9 ǨO+< T$~pP~Do~_6@:~<2f~+l-~̧lIy?LH\r$OYFYïUKmA_<>fkzO~r K -9r=/R([{Sh(z aizzƄa/Y!~ٳ}0 șGι?o~̑ctmlcܤTcU7~\Ls ?+m`kK+Q }O00z `K΍lA(-W%_u5I 70RԳ(#FI$1KK$H;78twϋ*qi'y1qOFP24v)(K^| )s#=sA_٫߯kq$c }<3"kҫE@nV!ܩWQ9YU?k Ƙp/,n0%;WIWX#o?!_&#%Y/t}bg8[XխEk! X5?0v -l0zَzb{!.0U(Ao4P]X$K}n>+n h?D^#@fG鋎;DZ*'tx2MGP(pݕ kլTsX!.u^V{_D5&Y8pAHO%8MvѯPu@_*>OS[=#t}>!&C!}{3Gf-OÁ{|Q< v{[D//:޵k9Edg9"F =&ǦǴq u5B76f;騈BdZ!h#lM|S'(0?4fv%P_~.Y dlD˿BږxJq"q72UB1QMr`O(> 14,Z(?8KQh}[^?!gSL%sl kH7~ED669',C1qGlGXJD!_T1=O|{rVM?I}7)?a!(~j7%F LB"~̩gI\(dMZa1Ԙ+CYYjQrb?#N7)Har&̵$p'_~x%u+*!&QE߱2? -'p7w^Ue1tQCh]'h"%G{R剟wW~F0 Zp7??M> ~)'|s𯯅Z!k|RL7m^Egg~L~~|k|~ 9d-@,uu2P - -&h f-*Jz$gEL%27ڙN8߃ r =V&M.}fE*{}t]OF!BMquq|lT0Z[^%KONWC9;Z:pP.4 `mZA^Z.Jf}ʹi@4Sa(Z;i#UJ?Y=+m#z-ӡr|/1~[vqjO)Z8{D԰]:4[_~ºQrfd|u~0]4~fW0f zg?2n>24023;]>]Lkfz8Dp:EZB̹*%=N`8=7w{wI|}~ .䲑eEEtJ|/Q= -')25c[&N~a?~xW\+@2y ΎW}Õ{4:=WmL ytD!sri}D}P ȝu -6U^|n4/[A<4 VyIs:MOVrb_MYfׂmgiA 罅 Jd\^ږ>:2=6{BXήX)Hu~sѢ-Ίۿ.hcU$IzRM%GͶgFZ7+(9>ȏgBS0=*j>=w~3C<:1sy: }h^Yy -kOj!T`BU FVg,KEXsU-wGJ gv>zje&C#Wf|]=߳p쯖Gog=P?XB$B]+`6;1iRdN.&)E^딧%si5.  x;:LFK[RF -l]6S;s/|@%ka]5f?`kChfn|^"fO0)s1Y$A+0ذ}r6,L/&f"{}d -v frW&m<.{&|wjHeާߍ) h~(3Kh^f%^ZFX UcrKQ]nl]ϛ;Y L@v!qg:3saO~demAENP2cE'qg~Y'VX:UGԱ~X7\PگT_CVoT%ꫜ [*[X}?K񈊐gĪ3FP_O|yjە-~IOPfvQש@|&범cRFC5 }o*v#DvmƄɨGQ?H!sWVv'$e0|SzvBoEkSEqGxGH{kL=kë$plr^<3Nw{ΫZKZ[TJͨ|WΎ)b;6.Gތ#N$ĜVԧ уW]s42}(}Rj9͡'.EfHa}k<' -,s8pN}NG}_1b6.Դ -ɀEhp6ZnT69\q%҂s ߴ@zhNêЪ<1$1F/QO.HL(yp$Kp9ū?{,۰ ?E 20<=kiN]^M!M.OBVb˟k\X.XkyPz"9ZV+)gv=g?_+G;Gʃm6*_GGo,MEFN.7)w/~*;/O^,;`[e'kdã yp޾%qH $|b'rx m\bH >&qPj ʪa>a"U"v?kc[h$b'WJxpw\U-¯U"Lu8~drAB<@|aKˋij_qMb%) s%KSyw'!|M}+C/w ?uAM5'\xТŸ'@iؕZ+ `+iGz[yal -,ALWS :}Yл8W=Տ-XZ:5ic%/F zLA 7T _(/x xog.7urK "t6l+o:^)Ĩz N1fѫ#hԝӴi -'gr?~  -1\.Ŏ4uHKB*{w`j' {8ŮO b/x}_CF_΃׷j 0x>>ڿFM(Û῕<^Dov^?蒚2T_uͲ×e.ه6 >\H,\L0R%LTׁ  #2N[s#2 8t?ɵyv I_`Rt;a%Y-~HmLj<ktVSAǍ(LȩjC|~![ms -wb6a'7; %Bݡ@<ӡ\I,)ȉM kmR W"_F?'m0bTahr3A|o}{ZHZc&_kxݛL-*8O_021SH_*pН -ZL Cf^"nLw.Bn]M~C _50yO28/!ecbHQƁ%tF&B]±";h q*Ux G f{sZI (cpޕ-kZEM. 7oَpRקx@c#±V[]B`  7 Yu94@* @A̪™0p(8nqj-#?c2LayG1'(mewePU@ -b)L-u -H: -VF2tp-;B%JeHc3ڸW1#d *NWt3-|⥭zW 8FޅCgHnMM&JQ,S4l`.->"7'WͶjpl9sUgLN -5h鴋+SnFSF߭ᰰnA1BF EMnFf~N@7 Nx-?0^ ꥁ7#22, !p;^1h"gP G&x>c\SEY@08=Y$ -{3aH}W76*K2zwK[dB܁3t{'.{ŽN--k -5Pxnޔ?N<(؜nUF)GW4YC}k>}at,ӫU DhyrhTs7:CyYǯ {7bR PGTdtP^ .&# tR&L -U,A*$588UCRkK%M>*ja78kjMv3 fulp`%{@PkpQ0jxѸ}.Bi!s5ŒC05+%52rF8FAD +AYR>XF%`Y`~pvȫLޠ, gG#%3%sf%Q KQ"0#0>  ~e4{[a3^TRI8fL(rG$[r3>{ G[zq QH8ؓ7\8t:.vDXґBɦJgd JUri=- L!\@DܙNYVԁẍ́#)ݜ-tFiqN2.Ykց$?WHK;8 ufǂߟpڳyv>+ ^$,4gt?rQҝ\>G1m~$+L雷 R;X8 :%H=#iR&$BZmKo`uDBecʃ>Z8ɷW{ŸD &E9W&5q,}'1}ctS(kI(;NX>\+d?&s 2i`1 V^!Kקꃨ_ޘv MCdݵK˜ ȭ#~icAޛ`^%P0'K-񍠛<4qL8FU#|%z vh%bd5iq(gpPU;; -=jt*Op}'ZiRm ["p4g w!$$B'KGj\D7ϒւeis$-Z`|Tlk"6wψLP[k 6Ky rZ}1]L'\>7ӗwO;iMTILOQ~hSA?5Фe ,>gT4%s )3>kg|ѹO=e4F&n$g,!u6j>gu]B}j2IS>OFJ$n<o3)+K}ImBԟLZph-+%!M U}]ti,;e~bS5@)> -G$VZ{eSjkYm-j~7t Z=!w#a0ը %w9h)gk ;3Jآkj\wY:E3?fth@7ZQ-t5eiӰ$M$Pt1:?t@bv? (jpB7Qvl]gߗg$ M3N$Z#`B6D)Kw`Þ_Cla\ӧ&ϯ1@Ms.,-n>⬮k{?ϚӶ&qAM5 -rsb'UT2#ąS6"HkL'3er(B撑okS׊h}Q%?t8 tLTU7p 0rb8_0A{ZF{F+ 3JNR!Z˰#T #el-ڠ0N:rvW0G$ -]LIg t@h%64~ skQ*i,7Gr2~"XlCl8)` .UivP?iic@WƟ5W;9xj -$+g{$=fF@ GHo#~*a0M:Iq%Ϙ(vzi!?.9;A*>,8>^8:9i32KwY[=xGX0:c6}a'ɗO*; I?IT(֏iW+: 9 (u@es(W{Vտ)6O3H8^sяM`u= nB3m2p\̏ڶ R(&Njjyp8 4{ډBu&Imdž<0I iaPg'B~!C6D$€@)+^r` vXLD Ýg$g~5]x GAH#˓;t5ikMv,!7_)r'븓mf-pgЏ6:9rmLb $W^:*HXǏ ,g!4!XvB[J;M`k ?(}ak]Q{2##R?"6);i?K2ROl`?U`߹pmg 1R?;`, CGTbFw;OS(_'&&P>9_ުpԝP|a*gN3&GWoNJk)2WR'9 F][ϯ$Q'=Q]NIpR:p -?@.j{G"2~҃LlՁl~+0=U/leIu)O%q~2o ^7'@rY'OZ,: -U;9NDA9\'A.Wj$©;_j%~̐-uGOzKLpꝴؙ&g:I)ooHI*|+NuLHy}+!8u<> bkB*t$x"GypI'eܽ}:ij_ViK.|ߔ@c2dـvPu%f~Jƀi{LAf7o42~S%@^؛,K.QghqͪVĪ^|@US{ ISċa$ؚz -YX@?!THN?M>`W=WDhj'~rwz G'ykqѲOSޖJ$TȖ$ȈfʏڰYz'=o.VztvZݒ@t(g2NZItO&C96Tv?'`W,YG)&#F#IÝ -ҤD !f -/%Gw4<D$IJZ^KaJEDYkOjװٛVcβ ́ H-U& s%KϿ&R No=`iD/=b+X r,qA*aQ}\ޓ@q.#A6BF:HinD}[0V0!~ bf50{ rhRlJ6\6z8^MA¡ [qiȜORШ  -Cz`;d bPp=[GT}5-@]2!L2?o{N{xM,Hz Ϭ0#NW\N^# F1:ۈ]N;0;Gda-l!mdC,qM΀yTVh]w.ZmZ1,Ûh6ՔYg4rxe$ 4}ȂyHډ6[⩯6q!,3 Ex@ODGb5K 4Rm4SКmb~zrfE5ʏ):d ﱹ!qn=ޤ$Ȥ7%3,TaIXŔ凎D N!RQz$zwDJ'ģ> )3z%& -9ƒSQ)sh[#3tug& ش(?fTHeU-k SeNGյ~MB`Yh~M uJދ^`bڮSc?BQ6L?qnj)N#ZW -GG$()?j1cKJ@C-:̞ۮyWfNU"5*T&zGh'&.'^?|;T{Tob6j!*a@'Dn0$ YeNHgd(nJT@ˆ򞉡lN0YkNל4wDakN>'" 8MT*nCMR[@ *YsJmH\AlIdF\xg9 @J$rq@T){\E. 2ĈR>&Hf=IJMT'| 4~Dä9mW9H'~)!%8Nw-, ,ߍ[d|A]H4#TT:VFF[:epO'9TQ{!EDtLH@P'i#,PudT1@NEhi1@ i4O}NN!&!PMH~Fv{ cnk 1{pW:CDR P} DfOTNR~d [uA6gDåd)FrH9 iOifت٢cHHySI>$$4efx$ j2XNb0S`6pT A{j pȚDuQY rNWZSVVxsj…j)2D7Hm*Eq«[-2Hpc R@P(>!N) Rg;p"~B*yp3HC߻ɬ93MRY0~* hǔ*q3esU2[>{U -@6HʼKOqHt5z*ڡ{B"o[wCRRLKK`! $s'g:,V+#GCdVn@ dpRMKy(lj Z -K^GD :%Œ;\b)*{*rbJmkJ+0o\Xw(fr$=_b: "#3!/)8=ޯn ~{\ὄib%\N}~ܨVt:-Z%nt@k^|+aOJ]lJ*I%%zH+{C(O`8Kjy#;mۈa=X'Meӂħ .^Jh okE %\B(iIRioXFsha `nx+y;g?wO%*"Ai/p%S2o6-Ւ~TW%"vbU:㠈#.%4Bl~`L[ؙP舳尴czϵ,4"ս@>@%V "(c]r4^—p]ҵb`qh#ÝT^b%3bzQiRP#?T񅱅1W<"+ZYA5veH=w_ -9NaPdjbʇEb"Sէ EK N6&.L4(tLȇ`b  d8XY41/atϕ;F&c\&O6B($/p sd2R$Lr>2lcPK0|Lt{.;Gvh1C g1) )ywK92>l) -t -;\#iLa4P#~,^ cMI`La* v$ڡll1!* g!Ҕ%Bf^5jX8Jc@µT`fqGLPrwrH Giydz7xʤ4eMr\lp-cC2J0buC3s-_Q&6,ΖLhgD*NzQ52rL:{P8꧞vHbW/(rvo ayCik0wLmo4R4P,rzʥLYqr E(p*kLVژ:L4> cy'`Pe>Xgr9>8- -jI0[MITثGY$ԥx%cXS QdI4VigRc lX4n; {w$2&bb(\s)x)_ UkC+ ֵk\3c9&Y~<0LX2 7370sp{Y@9 P)o7Io'P)138h q2M&vrы:Ә~Z -( oC&厈{hveh1 G{>g=u HJr3ѭ+OF )5Rq5~:NĸxFіXם"UΩ͋llɼ%7R"Skz'YOE{ t{;%Qz"wLґ:! -edΥi%0̑*~#s| 32R6=Jk4``=;6B Հ760$ND!GqeUO=A~!e62zT}I .ZIq(T) -˪>,[tԱطZ=QI+.fRԢwb 9 -/(MT֖/lȹ*yO5ԣs4#BE9d('D,'FԖ- dZ6JUoņOJJy5ED`l*Ma'K'GnY_Vɒ4G\$-H4xپ$Sr4JŪR)p)8)ۯdf++Eb&*EWj*B(⛥J̥~̷T# -9ȷLiꆂbjـc`Yٲ5؀S*B&Цe@XQ;x*TZ -T§KhK~j U PA}\\HU (FP *[T Ϙ=G9Ƥ/ 'E(J} 1Уe7=*79 n{TmhuթF?@k٣B`ßz(ph(Q9 JYR#:p -@TjwzTy,A4FQ 7`uD^_(t3W - ȯZJPG@kci:wp{TX ьI?)'chFv|{H >ldfrqd/oTϵt8zQY\m4[nTAJ~Fv+LhJp<Gc(?Q;Ꮳڝtp8EsA1Gu?Qx٨2HRT#PLEcq4*SAMhy1FU5{jR-k;9`~i5*K5dtF0&TO/WB۽P@-J{)T??[ IYɨL0eTs󼺭T u -|'lCQEs3ʨܲl`Dd#a8 !QYwNK˨v!r*&87KnJDd-ʨЩ\eT_O3*xԨnl.+Ҩ22FEQ] -P}ݏnc~7aͽ܆ՎΜJ -U9\n4Fp^dÞ[Sߖlǩ.Yv"eI8\)KQ?yJ4ܢSQh!N2t`$:E`yfXz@V]FQW]F "X fxPg|IjMq{D0 tbT,@O2񽹋Q0#FC2L\MXjcT b egTq v6[`ovZlBv/ΩIWӂgOu_%%8Wஔ.0`IowSiTy 뎰j.Ш@22"φͱ.^}4*%EҨ'INQ5#>RriEb~&jO֨$ZzB-;jv -sWR"1|%\"oGJF#0Qi|hTAlgShTmQHRkTsSy DV|LSZ zbBUVڅɛiRn i`ju3@{lTAZU.jTpN&Fj&7o)oT5l9qT$CB~9 -Ԫ#]q /ǟѱrM:"SWjGD_QChݛTAJ9C{UΪ5nW`|Ҩ{ cTSxlLT@"U2B.L*h`}[a4MJu[ZOvى:߉7❳JkDY9rD,t,3 RNDh+7Ģ81O;M&} "UȟBCˍ!A5U*}n A" =y"AVnjfmvc7@T4$uɦ3fHuT;| nǗxgTPYEH8 -)H對!Y#Op 0Rj|us4F^X4x@FjmD7RR5e{D#ՍT } JKJ[ uR  -_SK,T>.'ap m%?JK C9''UhѦΟT]@ O*c\ڌI+'UWKp>ݨ T=>l6O*6\UhFѰL> fiyR>>zTXJCLKQ'UH!'5.|RiF{' Qe[O&q¨mB -KSO*8HSO/@OJbzi,jRBǺ3-8B6_P*ƠfbREG.֩R!,kTRf9塪f%oJ(yߤ9(0iL!.>XvR ?VH,/٦foR%e.PʣpFďjIJFl=!\ *vRnu2NB( _:ŽRAP@)U!=Yq-?IrBKNZΘTECI8ʬl=˹GT^oR=R!SR}GBT3˥ tMJeja[tTb0s^(bUR>0k)Rm8Ç(>¦!a*ET[S*pLa>F~ T˞G?Q+4v -#sa2a/FİE=p^d*M7F[#SqݒPa1DT`ZGE!Sp#{V(Aߩ $y!Sd*Z-98C}@&Sh+:3҉G,do `A$)TX'e*2U"SSFDTL3ˀ_ g?iLF&j -!g3qv6SatI/e**STtOx9#wgLW#)c`!~"L *9S1OJL jmTUe[T(h !z3SA``R;rPTh` -b'~.zf*?(>f*৫Lun@+S%ɬ -Ɩ Zէd*|3U"(@Sd[V7'lL>kw&WF|O?jH -py Cʧ&Ce ]LEI%k[xZ2y;)SA|՘-lDvTWU~~P)-uX5UU /YS}ذ:":X~Kr&'K2)7өna4v+:U~P]q@^2NM - ,CڎB 3|;t  `ʩRq7_ʩmr*f`% ~07:q1)t{?XxҩթFDԳOt6Ћ_) fJTs{קz;]Rqۋa -^:nOEt>FAR"p$}ۋNݜϋ>UOu9j1?6> XQ|*P3(V}Dc:('u6ا :jS-K^Y$ˊ [~;T?B(?-OxJN7DsKYHq9T7;ű ={ ݧjAl;}*45ګ*"P\?*e`Ve8zUjnkЭ EY_Pub+JNS( -a6$ pJL(Dfr)K 40i,7Wiu*ː*  - I:szDOhoUѠ% ©h ׫˴A_œ$I=*bb*=ſMp$|ЩҒe"^ݼ/}HJ[Pe5ܞԁ㨞r3.B!B`N@ ePa 2y[^ ->9ǭqW tPO1O5n6[/Ѓezhp>ӑQD,R1EyP -CXEHP U@OxyU^af@^*j{m -)(2-l5? S$u:s-zd?D. kCT9OPQ*اN".BTO5Z -p Q"UdRo@NQ*lP7WydݡM4ImM;(*ɍ]cPHɉ~qSPU1kf0n8C"QU_C'f{"Rzv3c@~hq -qDբ\oIVAT1*g$&2oǬ -h}ITy#ɩDH$N,D~zCy(J9GE4 qQ%16T,**dqx%о!T39}Q[E5LkɓZ\UuBCT cUQ \5تD#pćũqPqr5Q JʈkzLGD՘yUv@+:2A -)&DT}xfr<Ј*K[ ȿU;ⅶvВSWZ`bړSuY_%:dUqaFP umjqhɟ%- >T\5"Ԑ^KwقDElU^(0CTG+4 ߶dWWSl㧴(lP2\o*S6 -ETYӕ% /@!R׎eK~_m.@\dc?z|t 5*@ĥS*ʩ*8s<(zlfؐ"TO3IGd:* -n1fIE}T ]R5}SGTltmxEN4m)*< *ُ*c='*ETEB@}w7t 'Q3 HuI -Ku"  /Tۺ?ĉ)^qJܛ@*z`QKՁA3|3؏*8:+UZ}/i!Ƒx9R9r}uTQ2Z/2YߪC8U:n[QuB5\FҢ5VxH.+q̌*d;J!i\70FNMۑ߃Q%p[ԕj7)X 8Biw9qA[>EnTH'7'D)U/kEUfHn1M<'T!>BAv2=U|~D =;`ޞk?)^ U;u&foBb/Y@T 3hKxR1?%Pe' -G*?K,G,I0 E1F}/Z:{BU_v P:-ټ$<K$D U?0*q94BW1 agPU7;i0!TAO{0z *J,%P}AU;(OvP3έ$Tկ&Ѱ *u4 jmdUG@֊,B/.'L!ԩZ~"COXꈖ-i]z G0R"d& -Z!ȥָ}l]iwjq,~Š(!TTZeq v Gpl.-6"b|$_00Еr >v]LcXDhT_A*1:MA|;*>D87,S!Oܩ 3d\Q݆ -H&UIJ,&)#D_kv*w9<&RwD^G _bm ?I,[#^YT%_1g_k,Y94R7 O{]d(OR9);E{I@%(>Ҵ& nb}iX9Z[-Em@\?DⲨgȯ$QpƣfZ^{εv}<,)3m62r/b 0Ґ #-xsY0;vQB0g!y]$6,>x t 9T^PM[_N^&"./[yf2=8@f G+DNWȹ;V`BGo!4uE>EHP~~w|>AfEJ eU4.̕HLfuS"ڌ'Usߴ9l$ L V)lZ"96+5P 5IPmŽq%b^Ox% Փu|b>|K'$+wOr-?.E2q٠LV^c`'0E U+i)DtP_a+~P2[xY_l汄(nf$V'wjW:S^*"lZ.BTw!Fev]uk:Ds[:rUS?W#p<=o3^p@LApU~:@8x<-}veɤq18V+ -gr9UCm\f\I޸ӺWHc%3wЪДƐVۑ'3Ϝ\< !D,QO4kL+@_CX\ybc)Lb޶_jD8Z`p ;DZ@uH&@yskI]8[C@k5J³iWHSTz9jX)`jrpT}^ YP]* TdĈkl6R>#K/yy…M r72 J>&~ JB5AyOcJ܄{r9a؍GiyFLT\G(-.eB-.qO߲jJJ -Qi)Fîtڪ;R ې0,gmrbyn.eرߋqɈQC@P |o= ݄:lULƌEElPqIEwʇ -,@,f"ZbbLm[+!A&-Z!3tels[@ OȜ$d dˬ4wUNj1?yhznj^\Wy !W@@F !JiԲ| |:|ݐf3"2¦I9K{l׶n^ehn'3Ze"4s o}84a< XT?g7)ݔ:Y-5`цPyЄcqHߐzU%+hfۄNuNgb5Nyd|4jP8NCJ8>bG`QNKQQxU‡2kOF)<)%}ɏGCJ`pOZ(MaL1H5L8(n(Wt'W#y 1ԉ2AjAkA͛HM*vyb<$2#q)383bډ' R -ܷ4Bn\m)gUn1_) `D9s'3_ -$2=ֻ\ GYvo63m+6͆IP'u':!cCY} TFp"iЍ|R2 },6X" *FUz,6!Wh#S`[ (ÌD$ +-"TjAxAfAI -$lQwq*Qᦎj!ṝpY'8jc <|JMۯNu'!d2qPPJ*%Hȗt0>ph8mDC؉HV,yeY "B.dpD1 aqHΕ/:#"ݛm_ ?/H:#?Yp%DmDMmy -3nDHX2h"b`LUIeT72oLAQ&_oáhtClb -X)Ĥo޶ Aˆ}E6qЋc3jf%'ID|(#^ZA&ӊA@ʃ!K$h-AQ(Y+suHqM!4'C$]d -q QwxX'dY/<2H0N0_ x&9CؤArpМJTgv%ZȸOF$'X%%D5BjPLa2&C#"ɤJh(u)+yysǻu\ʘPߛ 30eSuam#$7D#CCn3|?L=cʣ$DMְYXzZv!aKmj!,ԏ[VՆ!4[CІq%ELf2 G|$&!"ᴧ!AG G [-vG=3\Yi:_IJ o[M$4aDD/A ?B?rKÄ#ʒNsNi -QGoW$h u5L,1fN!(%LS.h%.lA>1Moj#)W +"۠x9CA^KBe7ސ_vkejA$oڽN{^C:v}H(֚ wN4؄qџظLD~Unkjh~pBB'ߚsU9sne4ȨEWa*pʼpK>'! p2k.DN^L^ykł"bCoT q#O*(aG~tpH bCg1Y8 F$E.V#LP(ɃE31u+>5"EC *Pf.C0 -y|N!'ZU -H1wteʤʜj*`Qhx:!.T8~5,t?WA>J9 yA_tCHΰ8,kTRɼa҈pC\,,Wx܆]?C*6 _S§Cd?_heqhIPT^n !0X3?e8raE ', -DÅ[u'ˈo+.u]M^4{{p``0x_&f  -B`#qsW1T0QA<ҾropE+ߞ -:kQԬ<wfF tPL%p1H$6 !Oz8lT b{!x -lT<q$p - BvI\0ō -KҟJʡ\CL\K{6*)>7F.:hu XBxoT<d? -\\*'i. -LPSr$A0Q*;nT(xzmSEMTb]Ir"![޼I=WBvRPK: XQHݓB}< -70 -k3'S1(pP -iSS(OB3Qe`4Mv+pS0jb2u<;Q{.[.iyl -Eb]ShESj^_v\O)tbQ{7Fnb!Ct[i>cqoon1X)HI`x \"[.e-.M GWث@=ʎklx>hyci 7spcdGQ\ %/N#Z:lH8puoƤ h}yb4tOHv;jPj<.)~߰_ v"3̙?\@y \E_;\P\(Jds#w.e`a/) .s9SO qE}nś -tCA*k4>`BFK .؉G -.|2E-'B>u0,\J%3[" S>_Ux)\̼V mHp?6%7cࢰ6/&6&{Yڞ/&*)u2:::~bqEZcuǮ S)e --J|;Fp{غ]|9m|:##@%jہ x;#st(jB EGi qbKWfNXs6u!.tHt \'h.0~)'|RV~Y<: ƫ3֩oNy(>HbI iV@[,GJpᒄy' [Mp#h{.e 7_@%)޸i|E+EpQyXF${Fpb=6> $GMDo  ?7FMx Z7Vlas|&6I&3x== .J@>bY2TIV#PN&cf1j wq)ρ [˖}.HغU+ Ι4y3y#́ %v Y}N.F"&R bȃ^p9cKP h D+qvY;#i4XH⮦VFMhu(2Eahr F:b:<ܦ65YMaIFS4pRJ#e%WԄ ygZN. xBDHm"EG[g?}DMpz+@1w( DM?3 E6;l)]׎ "JDM(bJ?jCzI*0\9 N0'B~ -\`.[ -,\ݵG g!i|tx2@-QCvEq&;ecl# c p RBwqoQ΀"!xB'`7= `DxEJ4硟eT[!94MX";GE'[pKӄ%^SۧMT@>}uG 0vٹ2.E!ݑM(?F}DbLRL;VGB^Ԡ5Hʰ,Z_G~TPCCp+ee9@_&-EST/}GhǂI.D)H2 -:ۦ.0 -?uY\ z 0nViܞu\` :.~Һ\D8@ \Op,`Qe9A K" `ז(lB]– -b˩Qӆ+`Y1z.!fҏx޵x)/ О2Fp:[ShN˹PZ.n >% PnTDʬ`}P̵ mH. O GR q(}m큋/2q"l.ap{śF{%ҥ_\Bq5H"ȰBq: -j=6(.T)+Z_嘜mj`Q]k.%pDFA \ d-!e9 S+Ed;Z-A{ڳwǎ5xue<$.c̸t}0GG㷀-,y1 -٦@3p!U|r%)ZBiO@v$l6@µQ-6(T@뗴h fEXjSő=̚fb*DoJáE _JH$DKh \8Dg kU:W4j{Rx8HZTŁB.7]%, eæqȳ~p{ў+q62 Aވ.m8ZZ?;$f[e;T\ TPxq؃cWtnp-3)͝Ux) N4YĻ:RFK:.cswɣF&p1))c/9c/J#h jt=qҭp.4\"1XobpY隫BJ\ umw)į_I$g`odބ-'忄@i>ZBdTh +qKxTH|,ZYTã%}Gi{.bP0%/Zh ?C %M(_ 1 ;1m,K E)Ht$A<i.d=N2Ad=T*oQ5$V+qoUvzVh9 8LB=c LJ ,~"H 8ogBޏp˭CY-brLUNZcԧvk'/kMԍW'-R){Iᄁъ#b%-8LB -Hd2~6f-i'[e~„oqS!'#ް.,Kʾ֌(x1,ȏߝ ńFû/(:o4?糋(OsJHE'z)A7nX0SzT%E(c U:NUEn0^Ņ"D\̘4 -fB9%^\A~vAQ]UT8a -/!KrJ6BVמ䱘*vtYNB'B"dq%hNgw[hoHboqx},E7H[P[T#71U[L?ǙKЈ%!.)x* TFّ}@\+0HUCf -*]O/Ew@h^-@ - 5-`T]bЖ߂ =Ǿb]$˓ NBBJ+ Hh Qu#33k!8LNO2l,>$ >5fB2[#VW$W \`@Bd;$"=>gՓŷC0(Դ`![ eUxgl3SFY#.h =unc{2ef4\H"!dqxzouGV(H2Ŏp E\UC\|7/HupGqG;\8)ӏ~Z%-~ \`b֚k} %"i|`GRD#цh1gr+HfOxh'^#c 9H$ }f%[ǵ}B.MlpqoDې]F.vŭY֚E=++~$Nhʞ4Z:3n ߢvAdU#-hKSN(s-ܻ߂;ozN9mqnʊV3^dgDѾ!S[T{A ^u*",$oC boQQp"19aƞ7J)-VMR)/dZGtZ]NѾMa} I6}ZTI`M@FMkWVAGoٿ*(2|jfjoX-b>~ JRIۢtX:[l_#D5U^ 5|Es;DM[D0IlK [ -1Uց63qi6L- tEa/8EߢYV"J"<^׃,([$hf2ϧoU[KaH;VKҷXt TX6UDThI>,q2uzSĀ3u% );cu^AVJ4)ܬ!x2&nҷq K6ҷAyJ"puxڊš@.էbBu9RC0S [4҈n/Ze þ@b0&eWBotڷsY"0]EvIUϾY׷8p`EZwqY"yyOmRyWl@147S/\ Lfl❥Tb߂vU -8?p YHCIfЭ I$a[C -k)Dͼ cl& -.}G̭ ;gY:-%^$E+*Zz@`R'>~4 -{^[,hD!W&$S5D b_< -iׇ>1IMq-gy`4-yPB WoQWIg2Qi>CrTZKCļzyPtиTVIzB'eC9Ѧ, Sjy΁>.0%ocUDY@(σr[_cb۷zyuh+00ع"&M_0OSIof t+<-*Rˎq -ٗܨAN]`2N^g٦bSg[ \Z P-[L5QqS8s o"Lz[ߦ<Ёz6wp[4sXI o G<: Yَ` -u,r +"ېYJFQǦ&Eoq=hv,}bi}Hb`b9%-K,8>HN(ۼߢ\Yv4<# <x`y PgB+b/0g~winRݝx4S,[ݛ(>Ё;cdz{fnaeibO NwY/J؎Boʃu5ʃ(r-YUe89ƿfZ ;\ȿ?IU0H+ x/*aP;!ݿEmx# AТ 5|b NFӃ [[Lav[ähUy +`f->5a{O f<Ua :?r`|GBK&-f -Ŵ"/θEӽ-=Fk p'[(''d-6a?Uеk`)ITJ cmZSE?-6---IZ\6Z 4= 9aQf7a~b8 MX~"̛jWf0 Me!IJhjPr Cac4p,p{,P"ŢƄbq0lbaA3;,7BL{A`q,t ,t,WQ'°3 -&+yš=\+)xWUEv qy kE -VPh+oVl -{tVVX20DY~b+0Y(V -x -UD^aU W|{YT\XUUVA|󴊣+lox+L*࿷*bh%ͷ7TE[8Ux'U .P /#; -9*TRaRь0tI/!60*xOT)px>lvgyaZdJ0$S0;aĜ+Dl3GKbpp7hpsIM")m1i -MĘȘMSX-o{Ⱦ>ƍfOǂޜ|;Bffi -3ƫz~" #$q[wɼLeNfPSL' AY~i%SS@L>wq8KeqReja 鬘Muqۗ276Zsݚ8!)a #/B2)|f4Kg,YAc3oeYU7oΚ`83̙gζ:H3=g2q΄'8D -laM٣x >"Lk`س_!<ͼ0A}VO0bb9djE1Yg2TDhq.l]%ٱ23i@mV}Rg6+E*{b >)ƚ8+#)&5R )pB)/Qx(( -3n(Kˌj@Q8DFq?rmQ ܽeVaIQܛ(%b(~(\XCk¥913o0}FBaMn OEϴR1|Ù u?!/~V[- -Ch=>hO_O|3= -%rDz\@b;S''4Мs'Mj'T -;q#;ӀvW'tDsʉCN??qgF'hp"Mou@;MhM`6>6h:+V25Qk}Py6\'}$Ԛh&d&GM$qT4M4eQh_C~&>:#6+3~h L( - /&MLu)LѬ dNx~Sㆆօ*fFk%h'AР6h/4 &,_*^h?>NQ%_NKs_*>yvZkKKK YZ&@a.$%h:[Zy"sCZ"?sIϞ8>%f}5,Е(+!ePY%r 1Y%X4 m ݼ D%W u -PH!_pbThCfJ&h(h?Vۂ~rG4T­2H$ +g,lTXpgS ,@ĥ877)7MO%l?4rZqxhx(<+`Ϋ?X -Uz*oTiMA@s| M [)ΛKkۡ%D4Qbo*hJh4oͳP=9N"~4u;FZŏdsF7H!\N^ITS/' "fNIiE7M$!4{p$p}ZxF:PCϔ"QPQ)н%@Gm `lRaH(=!2<+H@b,Z_ GDު9A]{Ĝ+z;窅вZ[wĹxkW#͟s$IT7k>HZGj᧭q#܈ḖA׶tiKLv1͡\tF ۃʌ` 5^e pPqas#0L s!M,""M&.bq" chYVgUsxElK+B֪"8"V"G[;ױD![&gDP19)g6$"ل ƳވeD""Ħm!bLj"PAIf6o"mC`m["{*{g8ۺtt-\9NJsXFnlcUִ4pt٧6?[ 9MxV6 ̛37z7{[|ķOtm`a}s{-W@7bmu-mPb -S77߬nZ(5%-vC7R7'MvoAxo$ܛBjFp*]Jv.FCO8sCT"5nF 4?#i@3ꯜ5 1ᾔ!Ct2/P< 9Cy@vwUU7SaBuB<1!pw7)!t8}bC o~[pAa t8nfLOdpiA:!Ԇ8>LpXh}c= !,M_9/BLfĭ xUMTBtS\i'5Nqp'Qqʚ6wb8F#:28J%Nw~GϜB:q?1KAA(fDr%,ӱĤ7bJ"zeS0]ҹ z](qAo8fq-m?%.Izz)DvL)Nw -6.Nr%^uf*nD 9M.rҒ .9$ɍ d?9B"4MT=c.2YN$m9rH!"?/V7 K9k"+}5g#͉_ ␳^:G[Z"ɬs$/.NKPó "*Y|S˸s *qX>D n!: 9:c¸~ z:l9ŷB; 384[_ Y C,MZxT>sxBsċsA{:sZBsTh*p޹稧s3ˀ*ta':Oat8_.tM?x˫ʙȆt>Cv:zO}?4Dݫ0#uihM:e)tDWhAh \DA|ڹ7>3į>i.`0a;(&|?Qj 9z({ [Aa)!ps=mu;TᝋV]镇k*@#,6,!v 7N_ܾxrfBRZ>3QcMYH) <.Zxq`q:Z@uX90W. -^ݬZAat  7mZ^|ӫc75RR`UƺnH.iu[tË!!nXoM :ZjCk6 !_uBCxذ X6|^C.s=̎{kj ЮǬa Ԫ0vRmODP l/5Wlmi*AV4paSTvW"9d4ѤAW0iY$KwvH}]pwy]A4xC/ ghB}a)˞!wj21ϤE[ZJ/23et 1N=^ V5a=j=ļ jDrzxlaLɺ#=R -ڻM~f=.Oܻ8:ͽb!dsI=uG CBCHKO >zQ|9Qi ϪEG;#|2| h|.9X V]}.gdO,9 t6f~ޥ7}48A۔<.G ʯ 2ܤ}266o v2Ԟ&{%C~G20>*^#l#,[u -) D/}1LQp 3tc e^?D*BݠU (4>ҾHLC @AM0La i -H ê 8}j=yk\s ї -BD/p/ "K+Rb$.&yF煒 C/.s :Uʘ.J1tMxvBRqb飊 'm pp| Js Ew[}0޾ ,R *pZ݄Yb b]}'ZZygAEY2Ҙe{P:!b+Q$~۷Cp_* - -n$`mWKWr\`P>m1 -uۇ -DLVUX!lW41_TV -*ھܝ -0Y3l--6[3vF2Smر}thN!VY?2C Z -۷Ar_N#Hn׾q+ډI/M_*$T*EZ*\}i -Oj_Ub -bUz@|0BT9 ]ER| -lא^ -}!SR'˴ǂ=M{ -^qREQ7y/*طP!}VBBʂڇ)*h?OSdxӾ^037$>v} *D L mB| VBNz4*ьqSmqe: -g>^֒(TPH-Q0d}2T@n)5Ȇ3h_cT*`4+P!# F4)SXSΞ K\Sښ)LBag)T IeyС0-EB -})3P#ja^, -O9T2 QD,{(+" A}|@a?AO'U'l j_L|Œ4PŴqBbg'\& Ȯ}pBQ'0־n&Pa4X^ :Mh 1&,Mx*PɄj ; - KپO".-zK}b,jXU] X *}tEXRE֕` }j:A>","·2:c"%P"$»GaoDL/ AVoy߁C~Ch5y`@7r!h|}!8r679eSGB )J$i}e~ ; b#>(6 } -p*g>UCp!T`:{ >X]Cp[(~ۮ! !`ipTO!مBؤB$LggX=#G.d/ p $7 L%@h |?k-ŷ~}c q^J+9l||%L|@$@nl=5׃lS遌 - `ѯٟs4_o`=uCnǁKAY8x8$8(Z8X^o oЫ`2L Z~~o;T (mjIO_5ـcaM_et k b jd59uL^i? ZnR ~35&w󴆟,_^|]@ ؇ נßp~Hu.J0,[8A O`)@ ? L8446ӀLc- w$ h@ ~h>@=gw3(f2Q0RqX<=e`{2^ed|21c𦅂c G+`UA ~_ 6 Iha ᷳ1Pi]rf~1~yc3N8P۫W/Rŏŏze1``C01RQ<~&߶`O,A kɍ6&WAe~xv>~CU5LoE!Kdh ȯb/̌$1ڤ!HȞ-b0k`S2Tɏ4&p%?t]M3.?7"1Рwk *oUK ݧE@\Kz@0b`=R i>hv'fz_hB~``` 0msb/2=O9 0+KRdFFuzAnډ(?F^0Ok}M E.@r/ 6IV~TN  R~Ko.. rc "S~~ႛo_[@[U~ZPIX qi(巊0. }Q{o&̳^k@\.DbX`|a + S~ -]l)嗏 -*0`bBSA%xT xVԑ -4TP(\ vn -T)p)<`| #QM*? -i޹HP`g~ ~2Hyϋf< X'h3?jNp'PMw PtĈM ^Z:++H?oA\š4"ӧr@A rw%A$p  Tf!8TG #X#jh~l`jE?]!S}O"+*(D# !AAob"(KYzu -k'l+BXCTCb C XA@[mK$H|-=<<@C$lyhu@P;[[-Krq`Á t ,?P܀m@6 䖟k$<2Kj`iSҀ\I2u3,3@aB |Oc`a <1aN_^^ -E 7X%.$iuL з.l=-q~,0Xર@W\af~t/?x -`p-5/Tc~2RB{)C0[~qIMО(.I컳$ -p H.?. W`w/37?;"?kZ?VhZ7 џA@j?lA%@@@HTML3J"~י\'9۟@~? M%'@7'ٟ sj?sya='ɡ;x^^qzDG5b/E< 'PsCKuP@-lᘀa_i[xQ@ZX C|Q1"z5t'4 TI-ޙ$Pv +U$0EFI@2WQk#TL9G];#лć{Rq&me["@L[M_}e4(+BCȄ&9Յ.:4ݯGM3@@, \9xP e\Hiaf5&Г_oYKrp3N0{@U{)ay8.S b˷C(0hA -N4&ZFyw|1-5-)shҀ.H@t}=spufN olءF_Jp̴ SSz^" ЊG`i=q HA#`RvIj^qsi2dMuW7ZE&\67DltiB Y@e(Œ>PV@\23 `X - tF,g3`w,Ҍ?)J>)chijjH=l" ARldH5pόq3ĪJ֌o+pT Bvzzr/pcߎV#s9]i5]2ZYR0a"ߏ3 -/pXY6-Ebn[_ޒnAz4"o?yO 蜵n:Z LJI4GwPCڡ|[c)3ɝT0n˪=94bzV!c!Z_F|%g}.hp\(Hțd=k1KĩN7=[V//gNEX)HCb4*W|AW)0؎bHNָꆢISͧf"3|jV CLRÜ1JQcHqZiǁ&}n>$leg C8Q R7A~ ->f$|\顱{+St2aͅe#!VoMґGyIN&G}`㿑&qdk>`MG}֢KHdq%FvTuhg**.9!.8ҩ|#<\]Gp[9L@Qů\a t99n/'߿8ώQ#g>G*)OlBΒ@4c#2UE6>W_Q -"xF7\Tp>,9A?O]vdPnό7ʠ|ЋD0"WN8R~S3`1}p]ljR5"3u:wvj9E( hf\DMbM"^I * ۟c%lW8'M(LԲ[`y -aSqN$b! -bDG}x Sh,DhYG7A6!flv-75G/ͯl$ap^eH"Hi=g8v ޿G!g ņ#zdt#b#yJX~y2 \JK`>-9 dtkb$5 UZӢ"0 `+#H &͒aAu@lVU2VEC~ֲiCh6&zTpbѽ(U -X'c({9V0Ppiۜ3R "~8^h] I<\hU̖D.v7si4$t Qp -5'hIʔ_!mn.>%.)DV3h7LͥU!XVR>mj1 2R.#Y*|F~շ_M. -A&$#HD&#-bl,cb6۲Zɸ5󩗭iT$dyC+*Y\͓dAȰs1(KIip?۽e^z-li2?_Cߖ4\ҪO:%јW6ҕñ/RD/gڋxZ5Q\R\N'6(R)v̚*Vm|S=j:l~*c^8%#b:"dS}hC̄дI k~Q_Sr]}㈳;]Ąn,&Z}#\c'Rګ1.cNtМPEIg(vuRD͐5[%H<$(K*Ϻu\Sd3G"UZ_LZtTEZ1:;>^IO6$1yzD;=bHɉ΃(‘pSq:cbxi,OJd /4C#%1GWUe[njʏǑ*nhz["4J=~ݏ80饔N߆USyRIH=6ޏ?>[om&u,3?/1rb+Qh&L~HiҾKOnB/6C-L -%E ĄDLXDUh @|O`ٝh¦Q |#*, l""1)nlU,UOK!%5_K'#\‰  IDpF*iJ[Enf#*\+ j CRіN - -/1 O,5F(lT@\ \"(b%5/up; ^eg PgJY< (ЧZ`MI~Sz~Mǡ@ 0PPC a)> -@b@* kVf f N{FPQ%PFz_n4F"7:N~R221BJ$bM ]d\W=Hl&ȩ3d5TuDe ֡0T -!*jToS+&3RD![P" K2,U$ -8l)P#у,BN(gaȎHAa -Dl8Y:7H LEanX>_сV%/b&aCM@a nX Y$PG0 -ёp8 P!2bA -,`&"r -3C´KX(8biyo+.f!Ơ ) Ez{BOk\DC|X_-XAO:D"&ZEŊjV;Hq- J'u(ijPq gp} 'S[@A.?Gn)\ъ &U 0PR".WPm{|U>B*ǍEE&5;q@PH -(88zZ2"x -8dY pl<~!fn<]xVZBwBq_oňKJ{ƺ5ƷD]_eIrgv(-/I (Þc fUodT_$ $@M¢w] vQprMv׈$̯͡ĦfXpݯ"ڒD-I[ɪc[-UU -f:d~gK$?.̞d:DT+7| Nj/|2!XC(bFg _00^>0u -w t5jH"A5P TAQ)GMS3{ƌ-&TMqJ6LzvhkICtAduOx#Y|k_lBcfdlg?dFAs9 f`:ɭ|rV.$ D: }FqTDKd5^xVjD=MlnNY۪`|e~+8٘Xz\:~IJ0lV.lA:nHz{9E/k&ZqBc?e^?$ 栙̜hGֺaw?Yjw̶VpC7DS Ug-\%$Wg|h2r1==^ cSF9 -O,2Hr1N; l[ {^~=ޡ"]t&UDf}[Rp2\BŤ"a6 X^7}MOz7ܾm?{] -ɐ'JP2OhoTؕ{y(}ɡ5`)$ikOq! )t"4wqf_~o_v'N/E00XE)@76P8՞ti/%~$q,:o 67 C; >B %;+]df -ٶRDGP'cKڅ.X,. L endstream endobj 20 0 obj <>stream -;2 ޒX|5 H -MG.ѦS& HIü wcO\LD99Jqj(9r6PAItA᜞`o){ydնP(t}W⏏PVx -n -6(f M̙9- i$ޏj7Qbxm[QTj|A'|>jCon;/9"xHnQog`d{4Lq5Jmk@cfI]9l E cn_!-O΋ +3bƒ~Mp$QӄȰ>]ђnIܶ'i -M)Gu0p@gf}6 -{j ?'(D/4*i 55Ʃ38Óu>E Ebp BjҼŠӖH-e! )E -Q#*ua*UH Lr"ѩq#hvg9;@ͪOn.ǦN ś\4/$^psWF.r/@HxyMꕛ=S^'s64OKƫ6Ͼ~+h{N'ʉu)fƀ\n K&Ԍb /(086|WƇ9> -_ڕDN4+ԥL19P΄!x6Mbfs2{_+rnEo#Y -kjnP1hH: - b" {lq@ScCkB yJsSއ! EB:! s pa ^ƥ׸)Fl^Jr]J%]M9C_sTIU"uoW͖p|_|էZ.r$/OIaI/%Z2bX hoX`gӸR]pfŨxDTwqkL7eN"M'WJ_t~cz幅DZ89i` {Нf@``͐$sgXZ?\&)#[h i)uE}$l}@Ue3RkM0ܤx_ƎЬzNgw/:Ây1[;+\(0HRǫa8"c{B(E:/?Jx̰G\d7Ͼ9e5cmENWЛ+tbm:jZoCNw{2C"RԠ['u2)0y.N-B תK><ƇrjKhgpL0/դd|UD$L*/8gxP!68"I'sD" 4 t Y 5k.}N5ܴID+LIFD5|쟚K+NË7 Y"Leqž}'=xat/L볗9+ACKw&V;V\nʕ -.DEyo'a0uͳPR. w#Zr ,$/uF:qAJS fJ_Z`aCXW#a] KQ\QXą ,+Vq2w&.jaLV¤a`|4.618ű|K+  X0L+3 &. 08qVA}3otm}x}UXq^109^  g\a҅9kAB)vaZr@]& mإQ^nPO}ۖJ%ۨa\c(jüm!8F쐘UbgbX—STcA.Y^158-c kƺЍU pl,sOc-/yRuR ܸ(握qȨ!#-ƴ1F&6G2OP2 $Śdd e#(#%)m\gk\Lsm\Tn7.z2 -{Ыg0g٬Y2߲eyճ)3*ˍUAg =~19.FW:kYrE=7kzY^r [ϙqoܙJYQ|f1>*LoCX)XX{g=3(M}&XǍ [`Q5.GѸ4)2.c, -<_1\R?A4˸:O Mzo/_4.XQDB!+d`&ݓۧAM"!Cy_> -q" t^dh-G&pK-X5 Tz>#3 +ZC&--LhxH'A ahL ' q7I-AHE4̞ht!7.D{B; Ό gBQtfW =P75qQF&)DTD@2w-E?Ίht"DтaN[ @E_jм Bt o\]TZB'w7.ZqaftKm\кA7Z&Cn=h&4i"V2z=r4<6kCZ=Pɸ `o/nL:eろq|s*VȏؠoWեvZ  -LkbQS΀W`l-`\˱齸[x -.~ PivX\ BxNruNs1ϱ^ۮC@ bٔN5(c^"s:7%:LOrc{ΝȸlӲZtF?r\~U Z(*.&.I_!:LŅŌDq&zݼN;gbIJ'ݢ2Cq[AHUXyϹs}st],.te/BD3t --Ɖ,Ʈk#NM]L]M茞i+y\}LnIΙN@qwfj[\ 'W:}"GsIgEI -VMq!Q_:=X cY'LiAPjquVZ]ڲŅpuuJ',U:IuMep2Užt,Eu_$Q\|噸ȫ$/HIKBN"."ƒ .u'z$VCIAp1PA+!{]ʪ}}@_[!z".쿮'p(^u~Vw&Dpaᢼ.];J=>dy-ױ1ڏ̉Ux0·溑Z -^G Jq"v4̨e0a9g0 pN^]k;ƙropg-w ]3m';DOwt뎵oѨD &."0d{  JNk{#?OGqT/Iq!i -_M8T4B^(. yx׊xYiy;'p xPDEox&CybW0x(^݉WFO\=P&.T(,$ $^)8m6xuݯ=Z< 8qv|, /9DJY+ 1[^qHy*=Ѽ0A6v2").ZHŃ=u9T\X"Q3N\[4qfJ\0ثN>Ӥf₄`z%PmOm ܳ= t/(.>~ Czw^B{UP\p"|m4|r 6+OvOL*ΗbRHY#;P\̛`?Y}]k}_B5}H;g[{S'CXt-ԖPqow{#d dɧ-0iiZBMI2Yjxn 3Jp}E[lQZ}kN\tCQ } -bԥ9-2-4.^>۷(>W>) =<߾mޖI+DQy;|9nxKk9S{H+Dn\jp!=%4Mj[2kmVo_rE2R>}>D),hZ[ھfGӭ>bWh*SgFMb`9C!gT+jl_ *cۗ/)Pyp{#Od*{`pQ?H*=B'g}E]N[V}[D6vk=gႄ_".` . .4B18σ59hWdsյOCd3|͗L*S=\=}€p!:|pS٧{.j_ >(Q߃ ~[ 1[e._\(|"/s_i<}:]/ i_hT RR2^3]r}Ev . G-\) D!sd_Z;E*>D_Ǘ:\>3GT'㵏w -~BesibNWA굯k*_}7VVln}Q_,v[Eɵ})#oϒC86Nq0 ݾSs55YRL2ie>"hpq JIdk\ u4O y\\" SB\1kp!FMCZ-z%<y .:!ҙy_@/Z6 hmw}!)d\\j\$0(nša74 .øf> L~sw\"}}? އ3FQr\{Y-M>x(ާ^y{uE|\4]6CRnv|$ -\>lL`ޥ%MͺΟ _:p>kapE=^.*<ߗ>}\I}mXخ7? .h/A Z(h .X?%eF5_>"cEHQp8C\%[}݁_.\Qp0)sJ_|&h+IY(@pZ?{\C%PF: kk .n04Ts^~/ #>]j$n=aV.x?/7>pq$ v#7N%TNpAK „ .V~%nm/"X3B譀 ǔ'x O Ċq60g.8$ǁogm׾r>!/}~.@ז_q}zOn/p ĴJ-#p,~pZ_o\YBӀUbg..܀ N]$T>~Gx.ڡJ7R(pm.Ĉ.O?~_߲ >{" qO;B`.D:eX.;Bq. -l3ga۱ʕ -\ \>G7?x.2+-(xc%miVPۓƠNq$)?*?{`oU~.S-jUK-I\}@: /Krtoq{R~ -P:d.U~{N》b&R,?&F+P)h?)s8'*I!+ < @Ά*?x i\uO8tJ۸+ ._x5.t#Dka>C)9 \I8//-8oE~#[Moy ~{o!n c~W=- 1)E1طoOߢ9*`ѓoy=v[ _~)[lϽ(lҤo_Xst9} շoϭoQU3ȃ^߂S%ڷ-(a]/OWoaД$炳HYE/~]~c`A;1-} %-!mQxlYA[߂xp؁-B>KNWa~o+,oy< $ar-.υ2oQ~Owoq}3.?d -iK/?dn'\\p8?HѾ $am p6-oz Mv'`boփxLBleoF&;*V-M~ߢjo1­\&? -}OYzX ?-O5_zbh|X/@n L#Ohev8+ʊlqf`aBc8dԒBqADBMo"ϵ2&f\tfVI'mC- &eoAoB(C7)U;"'[ToZLj\C:Tm?Sd:[o;A'U'+׏􌤰tm]PdSi&T[|"2_4 -vdMb1i M)^\ ye]IM**EPܿZH{C ;km'Rv4Pgi@₃Ơ4eoA'J.-]BD5r%0(Z1]3-|rvz@x*av`?r_fnQK[ %-Jm`5~^Q`k&$dɾ? |#{vzfM-¿<g]o@[|-N$搱u hP챌‰bo(B|6$i^o0m-)&)߂hSÁ&Mr -.a^ZF\}U"C> -20B(n>x -dMi$D)hߒp "R\7)}Rفf.'/38r]ۿuG%۰{ڿ p!f*qAMy8Up1٩wl@K3L9#+`hO̢%ѹh8J&`x#f,dP=$ pAKEpՍ.Mip @F* #'nź<&W.-N1+ \Ãf\q$D뽀zcCd؞4T 38RVMmx&X)^(`$S%@8zM\xwP =u/A.&C $ \S "*FpAx5$ǵny;@f -|\Yy -.9tҬ`(P\pׂޫ&PpAK+ PA%vŬ,=\V/ɂu j"=Pil a#TR]@v4zENū$Fp\;!8_T\Oܯo2C H\.h҅J?'- L&hjl]ZPixA-!E(s1ȥ*К/bds1vf\dSiC` 'r>.8W^p+r.V`' Q_5FC .xMɲҫHpQ%\ -.J[N;(!\BZ]d#Vl\0:gDS.\]b;wݏ{`C\p-#aH7!L6.kO"fr -V}n . ~ErO҅p - .@eBPX>]pKԸۅcE s. -UDʏTò;d2@;b -Di+l>iy8T}ɂ5&Ȼta그/kJrt!cQ TD:.4x-K - #>,BdwQ݅B#'\!LXRK_ Tk! !"}U.] 1X҅{ ځf|'a^&ˉmB,_U=!壑 .l"]qs﫰cpa.$_<0 xV7dKZ}rۯUU< U@ Tq#'K#[`+#lpAςYzzop':ye* LI. -YBwq\X̮ta%9F5YɄ'PW@F ^ְ4nr5I BaB \qR#)J2sfxEnV.\UFO"2B;#7k^4j/E+ЅJx{{]e˫3/]5$ ny(I0]|65nPYiLTk#keǠB"ˢD(;>O-4]q 09J4tw})o>T&drdk@BHB+E[Yc$PY8\,/sx -{pXj4c\==Y\GlKt. !aVsԪjs!#I/kpΤx Bm6`B -7 8~ "S%իDsi7O@TఊPr^ݙ (z4tT_.j'R)%2{ykMOO,)uk^U)BA+ӂ@.()xDp!?:-ڸ!!ۈQڙdN>q -}JIO#\+0h\HB)b͹ y $;͗<,,b=5vB .x4Y,ws.E'8[cܠ*@ j.aoE5=h#+@BQsࢼ`;]ŠvwD jpTFe6>Zw AY#ը4d):ԑoT YG 35,WIȖ.\_-nAzcU\ij -iSfNJ|YW0X.🰝#kpA%\`n - z*KG0=lpa.4 .Ϲlz,T -ҸO -u5)!hMl(tPLSZPis.@ٳ|"֓C:_Н&=B'ah\c6P+FPpv%S1w˛sE _Bڅ u&|rWnv%1kT{\A`H!p}΅*Nk:7E3`֡LGcRm\(2*s.\ -THߧvn:?IZq7O\.6gD73?ͥ$N{nKQXT:]ɇrU@EuLp3"6c&zp'0>v' 'OW -KJp}?@L1`hw(S:bⰄ!" c2B|ZY -RpaSYR𞂋FZHUE=Gu$TC[I$C^w[7.T[<[[@C0p_WǼMYnmW!\J} [pMɘ0aǾpNIph\PF@PY߯t BcHT ..& - cKil`zEA_p s6Fjl/k8Ii(TੇQ#by]-J$2~ ݌ń,7yƦie%ƽc=XQbpA٩ݢjk,.Syx$G7Ƒ*1oI)l law9W. .(To6=RQ"%Wt/j*X6Hi]vapa=ʫ -o*[^fpdnadυe4x\V \T(XsTjM=2=dqbⰨQ)\؁t,Lj%h|A?z3*YB93o!'F ߏ^3b'vEW \(86ѰCЂ m4y>O\o뾯]> <ѿ1ls+)7"p9 .~:fpQd-5V*둾1\b-*JӰݘ\IMm7H==n)<&ee vr/Gp7kkBJ?.Ƕy4mbPcft`M%óBQ  \0oψfxa"_: .LyL>k\.i\L7 -iԍW 4M*'2oS2\Wn#:~jࢫE/R5LCWޙ73J - .pdIXD[~=\ˆ M]A -| -q} - .Y,o .&yErKӆ3L`B599x`pآO41`{1[ܤ犻XCB3V*(jb;?uΤ-\PCUvҀF4f"Д ;E* V W9rzUoGpzTSG PU78t"VATA,ZtHV4%e qWh?b7Fzx DnHt4yeL .uZ 5ghXI%/r]d~FQ Z~2U> fAihm+vt8wnO`fvXG05\ -TXP1C .QY{ Zd@`pz^XdYF>]$06G_|彄^/6\B\7t:֒(]z<wa?5PМ!o Z -)-^ޛou\\]ք=i! -$0qU*xKIJl`6*侔$?0#B*D|4־l Uy=A4&eL0; .rkq3 OP"b.Gչ .Mfs%Sa-TbLȭlԭUPT!OW -{ -8<a@8X*?ۑ -%e,''<%  rtϯ |vɦ#<<#\<ău "Y$`5[p9q"dV *[]-/TBGV$V67Q <<:~t'IwҝtC-b"K؏(3_981'P -䣷9A²)*CyUǧMyLqQ.&'ďxr̒xle\"(.D#cS^5S~: U؍j Yt<Exⓒ2"K/}#$nx0)h5U4sؿbHE c ^M)m - C$ (:`т,+Z&ܮ7ߗ%QI%b%a!*n[jZFJvĀA"ҢeBW-=bUAaEDSoYƠD"h 1CƇ*-b&X4CE -hG F dC%&>Mq\Ѱ ֈN0}L:ǰ- YF>I_賉ÜW/o\U:<*}ErE*"RWIٲ6JZWCXP-(9 -첉/Ә> -KE.Z'-#`H1FV/`'oz3Ԣ)!->ZJbR!ObQ\LxZ~v,$C)^i-KG*EǻyޢjIVc'r?u-dZLO ,!2'lGzWϔz7O(8] -Ѩ@-"=(ygqHz|#DטּmprHTW^X55kH=WjH;LcT*)+ ov`Puj&>^*wIzI׺cE0bx %$x%oDž94P"x,AԪޠ:SP/[Z5ZM̪|tķx[9j`wa-ukvSxų4}ޱBbc+R%xצW5Ŭc8)]ۭ{3/ŏg96XPCڅ'x]kN<;ZJz~^/ ^Cmڟ)^S3e>G<ȟ4 -d"w ]GW1[gYzƐ!zz.,#OUĢ$W(>r_٘ ǐS̮QJ2GHiՓPh2äE>,[rt1 eOz(7]"P`9ɝ s2eH=c<+]k~G#m.&{~RI#HaR#+"n8W>zʟ춅ԿFt:6ĆWqKbU]m#jF.!Dc6Y̞/Cѫ$WeI~;9^j.0[6{\o77ZԻ^YBP%Z yU&jǟch=Gn[{K뉇\JoӈP1L-|Wx:vU:jQ6;l8!}rW QԪ6m)GG(dSMUN+eSs4 -fQ/9ah%-N@;~Uk#ْ_H=1DulmGwa[Rϑjjak=C;=H{mlKm>ztݸG:BKՊs>FrvJkG~eӣu2@Q; ݠG%%5Iq'Cn='ŏI2t%5iMiqClm'J_wZQ 7ŜQ2$rvI9RKk=:sto{J$h(=Mڪ]T'6PÏ_'.$H5G)źE0oM沿?dO!$hUID_u|%{o7 Ur;RMzXc}ϱSpA:`UvCbբs/JvO*B˒Tc,:j2ʇyJZ"D+Iob[j~Sqe5R<~؛cU[~܅*, -VCr"}b`6զr?8ŝweE{Glw`nlNNlIOt%<*z1Y'{9֟wzّz!Xw]u!xm馕7[{Nq5ǡNfٚe<)b!mqqס7яyWPpWjn;mCxwZzvȓ$uboO~2,sl:pB& "zXEzmQ/w1嶓RAf#RO̦?5zBslMe1&h-[=$Q48amfClVM:xZxv:Fr8'VMk5ղVNGtN'͸LtOK;NNCҡ1;ifju*n8)[{Z&RUNV@aYvn8'ȹ᠛ mYp'lAp8ss"$Yf騝qjffIt1OnqF{ei! (XcBO(fǠIA؍K;LjZBQypЌCuXӓi0yLs>)NRt`ǟ}qq\nq:q`O%I}RvC\c.Į(Nj=𹋞S3qi]frŰ@WTΆt⍋9N:ϻ4RN,w=1QYfټwi:y[V PC[H; )?nGd MiN;)A@>NezմEeuơp"lm[ 8WZ{ݸ} fSݺA'ꋣy(pDYv:rg&kYyj!ssef3n6# -U##egZSRVAy掻A:igZYD HƞwD,ZIVBpp޴$Q䀈6TƜr~ y\ZS?N{-7:-=""#u"drNi%ˑ} gM8iAP;L9x讋޶)73uaN?Mݲ[o-8o_j[i\wv4rv:0f] _p:`v@Cwz頧RSލs98,wݟ)׻V?RŰp^ɱ)蘟=RlmͲ5ĝ 5Qك鐛-}9[vg cS=O9exr+vu2KQ!d3%(V GMclkqz_w q29M[|EwzB?-3TU\F{]yᣨv27fOTYv8jfrj37n APRhﶙmK9A@P܀"*ɸl܀T@ӑ?4Nl-=sPñ~9Gwu`XqlwL; Y5Jlߧ=6MK4B&̽~=pl,C H+ʢQWv:$#r8#u`3QĮ5A:RjTyZr6aWvUb޵'}Nb;9ͷ9n96z\-??Ќ3R'"L2lun?O*ܯHy^s̓uhђ/ÂI\ru0ksUӞOђ_ME+ې⇓u ,=wޢhi*f7-C]qt7-p -zl;V0?p&ʹVJ4@fv>M6H' 7 F{ui#e^w:eNs5MͲVRMKݶ^EEt\8n܇Ÿ^Ǫ|$WLbT=:{_ey>9_ѕ& {hU_ :MQ%t (\pk2q -Vm`RM/8{pѴC%,ŐEZ=EZޟo9 XxyJ_π357"5Mq*gPY_'w[uN`7CڗNx(ۆrdTR/lbӘ?ROVfsӢ)TDsRh>ugNeQLtqqEHIf?Ûvv29{U33eKS^ju):Ck`XH})wu.3-Ǐ/+.2kYWz[P:bYjxhp[kSsv$oGo*;-?ٗaPyAPRĚ%Zk$ߎs9-6ⰋuO,}cOs x$ŮuYQ/BS l>&>M0dUrNt@' HxHǼYf Rn6si"gá8oZu1양Bt/ǵZfK  -p7N݀Z2]K˧^APղUmks>9OZr@ڬ3{qlr6_We$60AP5Gmgb.x (HqHڟד)%(ERL3Z2z[RH-GwMfWˏ"u<ȇ ~/Z-7qw؅P$fWhwņY*o~9`IGaezaW"7 -^SyŇgjoa^+VjՒ6kI#rT:KvO䲠ѳ.E~T,qvV(ulg iџbtt8r6׭YCq"CǓNpv@r ~jlM:my+3APͻm|pϻM3;Xnj۷xRe?vv:oT6@xܿA1eq& EQ4(VsYG֬C{$s?619srr6"Y:תl$m7wl6;@YbS<ͦW]R87<|qo;;T&!"t%w}=7I`mݠdMltDcȫ]QTkJ׻nVɏDkP%99P*`䪪'6F%5E^D'jU~GCf}MC2ܯ玎l ~[~F#u9ժUgy>Y梸C"؛qZn#*4i3A6lܭCJW=o3ǵv:jٰ}nNᔜٴ}Y_~%u;)PT"cAO6~Pm8ydM6nAO4F`m(x{]ivTQk)KyzJrI3ep9.R8)<_$J=E渇}Yfr8R4vA(sqzsݶDgJ(:JQ\.?.A-P%l$gN&xݗu$V e?dK~Ik*R,R$Tz;FIJ$79M=G䲼_zC'r&:E)^cfR0T%dugJ^(-Mj$vUM˚^:]x^w}[ъԓ7ǘhFփ0Q-V fO%j='ٓm0DZ2qMEj~L/GptůEqw'p'l,7 lf٫i5ŚfYi:O$kOeu(zHNizJV'q;:qh_emq5 ޶x'NTIR|J^Z5IP%.}ժ)5k$˿+cz/I-\}oiMk&jMIi ]T.-~.HXqCEʔ1:#5?h٢vS~oqymW ӈz"?'Y c@9)q^2=6XA}[&{"5y(7bQ&7z{%)|W.kGizZzjKz)Ӥ&~4"$J=5}ճ Xs(*e{R a0ZSQz%Ɇȝ2˪?Of#n@NG2sR{]KM9MA8wܻilPܪmy]"O9t<5L;A@Pő; 믛687TjzȐ61f.$涙M8Z6.޶7m>I v:loܹ\$yQE|3qb.{,mgRngC$ȏ r䈃1Z4r/`EUu-C;M. wm?J8|^~})6j KGMX"V,1%jM_.{BOdN=nG'EPIؕCV#-SVsenݲ)otoMsd1}y9岿 U*BQi㷗o4^ni!AVq;$xNPlE()I9tEJC|u,/~;)zȱ:oQ̣yVd^CI`n[BD>Z-p,}:#ŏ-:{Q)JA~ ou0%ᕊT)wv8(cNHUOKw^mk'K96γC?;? -Wے\#J q4_&{>(ZVn@`'EX-cN.UGQdb+fM5ù(aw+R($R[jU*UGCĞ{3WϜ_IQT(~rIqЌC^>~̑j1I-(˞cZ!rUjVgM g0<,ʎdؔ$*oQd.,[v=enT4|/Ͻ,Oɮm Έ~RԴtm& -O`v?<kTD1wo3fvŏ~9ڠ7u3ѠW.~%|k?| Rt)|pi1'=JbvYEz9]Ǜ%(ECgRKTZ\5DeQ,jUc(=~m4)8v3Eenc&#wY-ڕ^}b2ZŪ ,s\;w;~Ԝ.6=qu6nٸ9;:]=7Ͻ4mQd5:(\O-k z!e%4G)ʋ"/9oIN򴞦jC9wDi">)}?ZY;m%*uםv%uŝs r!S<}5ђE;<䨋"iS.GY M AZԳ;ZƓ쵊oLjIwEhwmWEoSMQ$Qbqt^q~T gҊT7EQ<'Jn2myR.͐ԚW~Kʣ}f]KjjєuӤUC,{sK:t2]W1y8զ&ES?~Tԓҡכ$V)I_&ɛinBҤML BR#*f\PaJ!iepCE2#~]CkNxm[ii^ۖqyek]u~kw] c4_=:.mu]mqn|z]M-3mum>i2{Iiަy2o^~"qIY`Bx]˴㸍8߸<}.ӤwO`d\.Ҷ]^<2|M !if`(V 2O7_vn-v=}9^6.kz}t9} {i\sZ{e{ueoi\mqە~}mmu}5;2]|4|׷omq7qb%w<>:iqy{u|ZFv}&u{oy}y|[y9w]\mY]s^o<{]{;w{^oߥ[wok|mo\ouߺz_ymxm:=]㸎8纮}8};x˹-9x}=yN纜2t^\緬y۹n㷬y:mۻ}]|u4rym˻n7xz׵nww^N959N8/yu߹^Nӵl]}_;^㴼5׺n8Oz9M55N5ӷߺ255l7w}-۷}׷]mw;nۺn7ߵm}m׶wNt5_״.{]^z]m-w}}˷^54r]m]׷|׽mw]vy]vO|:]t/8Ӻw㼞|۴Mӽv/t4~vm׶Mwum.}6=/z_ouZs޾ۖힶmٶk|e{wuiY{s\K-M|]uu/6lӻ-۴|t7.|x7n7㴌뵜|}{9\̴tTm;3˜4I 2O$qKS&NJ#T]ٵGoU-jz|}n.OTnpXQiQbRh9UH]ؖ7ZC|øi nn"Sh%'cIPJ'~U&. ~UCvʤ"ErtK*dh{֡n8j[Xll <]9】a"¡BR@)|֑E5`A >)|._ܶnm׹ zŰuwL7_Dס]u v[,bX NU4@uX-?ot"5MwΆ!޳OӜE&En #3Ƅ"]>ȐTBǍ 5LLkxNStݴ@PnqzIkm,u+*"-R",ʧnQ>oᤘk'~~(@L+9^{r6%}ł%rN 1Z\fBH;AP^'4(Qǀ|n;n un)\u1N`-JDB1e(#;f0ßv/G~M]]\|{j#;5,Xf3:-BX'亻Y$) z*~/Txo%fRŀ~I۠3>\E"N7uYfot g -yYW-bR)תLʌSl0>)Vr m֣h,}YbXjeߞ>ʡȓ'Z.s:'_E) ~ b1bg wTk4j٪if#r8f3f-$e3Qr|4ARjU>ňG#=k4w 8-`bz5S7>ϔ']<]ysN:[o9;,Ԍ)%E&!Ά4 'TXB.C^$!؝QjTH;9NeyIz^i"s49^H!>IòKc]7L MG J2f=c[qOmsT>}`C%ũc$kjn}hBf#}7Iw-(Xv5O$ChM ф:Í"b̸PlB$ [&y Bz kmEz]h=Y!ⲑ*䶟0${'vaÊ1+8񻋑XxשS38uHΦA܀3РX v8( -y~!ZQbBmBpqLեi~EGѐ!x } 5Lkڏc_l( viάRie('LW<:u$ ¥$[˒ّ}+& -)Yz4K?K;Vou$9` iRs?ꉚV@(%1#)RƣigQOĮm84KHyA-$J6hLOQ^;> <4R8b -(qc2Un^ C4-v~8kլnY -ԉ)!} vG -+dRR7XBp(fz'잀v=T%#75ŭH{t3nF er+w}yXdYNRce$^ȼB7:P @} -IJLFU˹[r6*)y4'mYlKBO֣ƞtm/tUKkUh.\E{jʠ7^q/TLh1A7O;,[; P#^[No/$r?I~6CRx\[~ޞCCqDӪntFYzYVzGNj G J kW||5(MͮE,aR22) z#bU  n̼R;>j)^o5H$$*Z/ۣђCyƟwv8:hMmͱGOU⯛AJvEY0XP%-^* Lv{p!!x *D^"}i$Y:-:Ԯ."E*DsŘHzI Ů)?h aS@H%*|'1~WBc۾=W^8*=ȠxJ0K`}vj<)QT{Q?K]vKv]B/e1RձMWXFi6ɰu]=O՛,e͓亡K?4D^&)-{P?,Iܧ*-((|h!qp.-Z6811A@R1D8TXgMʺ~K~s-:"4bCHzaRy|[n-~SqED -dBdH&:#3`1y=/!Q*,# BaØ>1HX3XDv`D:p9˱=4^fZ+z Rs]\`r1LeT(Ԣnxp"lpJ;c#x@ ɇW4MaV$E+>v v)z=\F" ԢϪz݈Oٶ.#X -FjfUzSHTl":JG4o}ZEe2wiuv5>V䶩٤erdDeJ0i~I@PB -LjBEbr ne1D3|qa יkMrYȆD#Ҕ!tvJʄ&xQb-r @q H* -XSt07qIvK1kIE˽)R2G)!0e7  >(޳}j٢Q(g0:faQ"B2|vNT/N^'_V&%QTDjZUu?Me; -~YOs{BMH"}Q[=o'y9Tp$-j,3NS)+o7,Ekulx$[KZQVd%ǩ=/2ά3r6}Z@-yn筛Vۯ;vm ->MYS9.C_=UJ/b,~2J~[q3%4G<wLɱI&} e>~ Ho*E$D -Op k=kz>jxG>%cF~&Ћq)M]M  .:`5gMR4*` lI+j]uLc,Q4\ b4cöyިu+ӧ7܎k9.C G efr%'QV5}zߐԴ?:47114]WI=MkJbW,ߎrX=ǀUgyd]zH -T @Z8HR3DT.`'R d["C cbT˲8e7PZ>nކXiu'Nl4{9n8i'J}m׉ιŰP|A/{V ~RR#q>zׅ3!>:r:k[qkƛ EHm!BK ؊5ˣU=ulRTմiK1='Ek0OANx{0S3dEZ"uӮ--+9fͲnX'r8&:v~ߨUWz_nuFr 'hUx_On_/KJ˝ S[>TnmjIjYF&lNMMzZl}ޗWM kgJ6-VnEI]UU RjT$׽Q2|,0.Cxs.=D#)):^ /\oV3M9 Eu-7OTEN @4D9 -3f|:!gKgqLpΎFr:߆roʚimv.z&u~XC k"Rt^<"'C3MʎV'-3#//- (EsrAAD3-ǽF{?.Y>q4;N#Ue_՝{r H&|NRMLDCZqI8Tl}em 7 I.jimǍ6fSW/KdGSEe1T=2XHTUr$XvĦ]|j[ֵ.͘i̼a8 u ,{vZ wi}DIҢגim,S3͟'M?zn8ݣjښub -fM{QP춠F4Lb)?׬-(u斁SӷYJO;atby,Nffnֵg'R ~OY-1jz'@Tmsu&x&-UA 8A1Ѹe6Xu2ύ׊Wս$G:Mj ~búdG]x굛FN}vGUvjiX|$mS;rPlRѶ̶2D)H  -(n z)wqԲo|I-llAJ=yi ~ךiU=g^qݥ)b<5s4RzMrE.(^)H!,M#52BwK$ñ.mܾ!(v:e֒Au51ɍ}tuoPKуy9\OLcNږg"t(Ѳ -!L=o g\{U[g:hӼ'22"B6E8\4*42}H%cq_uo|/ݸp@8։lpVTR.*悩H/6|kTN-|w'ILԸsVsԶ=pb#)uH!Rl\nK>=}4&S;M'X,v{F>ðV*Q vޣ:,۪ðE4ysңȂqŪ -VّI -K ?&ѳcG=;e5tCpS4 yfJ?څgԽQFۙ|ĤPRC)sme'@6+(WlG8#3 ` A @ #Yg[m8nmIbóĘP - -hp !UP*AxL,20JL\BZ> \(Zg϶]Pb `3a oxC@'8B(4A,Pď6^NLbLJ\\.Vƪ";NJ@)@)0! lHCP+h -kX- :(((a7(&&Et::+Be:)@@ Ґ4B ``)4> L? tTH #4lJJ]o/DX=܀1t@94a T 'da XB@D Îfp3]Yjsi&/(Bс TM,= -pD?j)>q[4y,mig\nJ6ҬZ01 bPˆ#衇<\^ZvCF$D$RHĪquPT`B 0@4a$%. ,*@hzD&(Q Io4q~Q/I-Z7R0D> @( A=@, L vؘ) qb 5UӰ^t /I/Eׯ[ LH`JT  Z@4&B d5byfPBXaC.%-FX#fE+Rj$Hz]I.^686GZ-[>:Peum*!SHœd<-Y RX's2.)Vna\ -bFjeϢvU.E^5}qO=YV˰~ʩbbkQ<]>-qCP4x<붭ZEjq"|yn "xv7͑~͝M IJ-%]WBv˶}D1G',~ƣzM.\(!R A$vW=C.e}U\Ń| fIizJ}Z@} -fIZYT < z1\J#qU?5yq+ -bSElłu:Yq*OO3\Fjj#=SkrOmcC&7ޣd^9Ve:VJzXE$FE8bh1B -"* eus, -RA}2e:BGԪt5^h11bKUi59 Lg,S%%NJɊI䷪GnwиCD3JZ/^G< IԿ%tO'~QWu<-;&㿞=kک…)Qe#ruN/I Fn]xHxű?Z7HV #=jFZB/+i`bdT'UMs E(}/|Vo~[R`xaNm0'_`RD$!>DԫzN`ߗ4vUK"u/oc5 g!(*Q>7.ú5/grA1- 0"ƠH>p)9N\-=c6,'Sq8@8JvwS o!h\Bj99\v&~C$U$gEb}fR#n%}忦ɮX -u|juϱ>YzĴש峓 9^ubS3>iN/ YrbQ{$$$8N=xhA?ĜhaP+v)H!RX+F| V/Nkk(-XPh@|)1ĐiRFB?MEyr̚\U5?zIhWb,oԅǮ;Vȏ>]* a$*'/Iwt^&_ O I@q9DOchcbC% -rӒ޾PGG_1ZBI .R$)#.|a"0^<΢fU15VX)A1~eCFGn .''Ϣ&l{d2`T<+vG9חVi&ĕ ^HF-ԫ~S1+˨xI1K5򉨡(HF [hq~ȴ\I)"IkG*GI) J D]Y@:hj4SbWĦ AE 4ga"bENj)R^Pt#EL ~ǨL"^''|USXPZzVNE@@Ҳ*;Lb2i+^eR1'3TDb}~g! S(F>aWXo6H1;:VD\D? C9Ӧ20I$*rM] -qL2Cb*f`Hȇ!iHrۃ h!C-+RKh103.OU@N]s,1>~ -H#`H}^L+`(= mѳ9bV(2\$,H5" =zŦ(5;9 - `L$0#ǰ3 -D}Kp)}`@ -OtgSS;Z(R`?pJ#uRM{G - 89hVLX AǏ0Ԍd2j-v`Hˌ"%54 峧@dN!&*"7RDLH  JAl~{1cƇ//(QçM[~OeY|;o8QBEdJ7\P:2HBF||YFS(㠸JHчDjˎY<>xx+oV $n]2/;`#&d ͏)Q'?q=h ;̘?A#u1j3 T -<-,4P^J`Ccu {H/p|HBP &eJ뇘#^x1j B 8 4Ċ bPQ1"F(قUxʼn -Io91*$IR -̔JMh z譐<*Z#YJ "]e|.S#XLJ(V*C2&2ݲT$z}`H|X"EEHK4ZHEk%B >-`-1"\x9Y2 J,BduiZ*!*'Qg\%SH-HZ&?΂SRvz9X5B%r1Fv[Jē\v0(jRrʯn9.b*䣻>$?r -`Ԫify aD~Jo|c 4/>ȤШB.^#Qf!ʎ{vŀhz0hR4ܺgXƋ؊*0`9ƥzhu%%j HgFZJxHBċQhC,`XF?=SHX4bN`7 -BDTrzחOE;"QMR̠B$| >v[N!վvWY -*EOcft5)ibK?mjZŞ$"JnG+jrN%(cZJNoV2EUDʎCZ,\--xH=?取*9^4 qXųȇEbfY?\_l~iNK嶘0<4?yrNbӫ'N1إ(Nvs$8# S -RX4œ'᫆Qvڄ[5YuPp#?')s~>BK{Fm?o4Rq͐>'n,Zsd'U:dv[r[rtR,('8T%Ŀ`T|OaOϫ~e?%z4fid vCAIRZȮUiGjOq:f ,,.gF싎Ct;UǠ6e"0q@``>Cnʧc2hND8I% 2EX1jK…4!ZN1^*Ϸl/^=Ep:,+-2LIq7Ǔ_)P<|H^/_%nkzPy(y'AYnT<+&Ev[[D~JMw\QbQU"6n8wM^qꊓ$o(R WQ@3.ϗ3~u|;s)_M/nOU=-C(BO$U6'E!-{sjϾ3GEA_,kfUskb,)Z5V-#*vGrגzfYIh9$V]ɱ*~_Iϛ$UnCN+*{9Y7ۦf?ɐjf76.X%+RH^{Pe-qŕۢʶmt=?鏡M`v!7oaR}5SrKrUYöB:D 8PFP~7}ݱ'GoJ-&z6b*tj~_zi *LWH?WnIc~t˿5iE*UEP7K˪4\GE,%!|H5AiYU__mTBB.V4]SzS+$?XѲIfaD=7s-b+ɞ]Hj]HWΧ$'NNnjz=);(Ifx}uH  UŪb%m46NqlMUP~GR, -"e0DX3+ ɳar 8NM"/XTG k]3͗e. ]nKu+"OG[tBuZ,M?z)jzcϪ蹷IJo~XWնZϫɑDOkJٔy%7]1I{?QG뗞W!$bO8o(i -ZS$15G<|+[v͢eЪimL9 -r=]ZjЛ?GӒL$ٟo'm'ec/9 uOU'GXĦؽx{ -iIo^_-_7f^JN>^k1ъ -@!9_#DE,[8=oYnl =3N&\"'>(R(,DZ$̪U2ۧp;vdd'OR oO)p֋{傤C튑"O}̊ԇux;7ȫlIT\pM -ezLC/Ns Q^?%I2f94jq§+M&'2`robw{dOWmrHvʹw߿uG|d$3+@+4 -"?<7 Ӄ"¥_T\?WޤõH a|`0h!vdJBaqGɔ~Iw_}e|E-ONBrEC R/><1E{W@H! 9X kE5>nuLd{ Mg%ӛKx&;^8a@0:qbዼX='a =ahU2!LzJH-@G0)Iv$\( E1hHq#YEN/^m}7q?tBc -`:/0W 0%lNL'`0.C|NGQ`=8@1Ij,XXcMѤI9ydסT_UnQD<4xA `d >T0``#pЄ` -4HW١N?ƛDY$xJG@<`-N(Ѓ cEEhBR0 @C91Ȁ D耫JyM-#!/YxU{ĆNnPBl91!@ Ѓ(0(U` ТT=iKxy]Y'vܳ%"@b; 8x .2@ ^P , >-,/P! )=-m> GӒ -E5@Rz` %~XRL1:P&Bځ~ 1pS|7O.1%{m)2t", l6FX"+@ l((N# [)q:Y;(X~L!B p.B;B$r!LAP(0@ сc,^Q-?qA|A*.p c@CdrJ0Tj=u; 3CPpV#7T^ ;8/{> |X8 0 p჋Q[-qC":Y~EQ\kyOLT\Q -`J8A0&a %<1<}RbK}566Gyl)Td^D<C #6iDkQC#Uu'66ߘO]$٢di>|8F>ET=$ \w$71P0Ld, FE  -%B$8p`*!EP[%9Q$TF!0$% Z G,`2NfPV+s>-럻wt6PF+ -" -5 -F,/SXdʼn5g 󧘂̩GDzH 2; cwܦ\f<".q)vqTt.[ @LԷVD?4,|' ]OdpD(J m̶֙u(6 c5U]>s%U{ϫȚ[ۅ '34T.Ouw~ -x@J HnbqzA˘LwԭITIZ4 OD[c$fFr5:vOպ ߞW.7v£~`hOy~w,<qTEoѻ_\^LZ!tL = -#'kCr>WUy)By~bT4+ׂ}Qu޷5߻TMSNm6^Bi"=LvB5{Љ=&ҳ~i62-Զq\FFP Ng:g_,SSDЄN!0ݿ ? zrhfFV.jä(bxEYc%%8α+("֍D,Qw⎾SBNƯh=N̟9UߘrMΫ7Yt8S贵MuOOE&r#x>ۅ p iqdG ;ٸq.q^ _g54y?=mzby(8e։MNY>z@#SNm^v)!\I}WW׹!j]M|΢I%7qpHLhgc<AEGl)ǝyA1IqIW-ׯ QՖ^aueSuA6QkT;[ tf -m9ˣݷF[QD#7N2'0N>]MkbyH⩪wR)ay6K;UӰ@6z_+KFr u2}kץGr:fӝ@Z?W\,l+-G۔Ff}a49DOG_Z4OK8d#ue's/?ϏzVOYSWtuWu$qo_!OlwMm4ѕFS~usEr"ZX)Y}ۚ^ ߮뫪]U02M6Jw]7:ʒmh*zݐE.MD}W&T4'`~&NxϮ隧H?}=&2*{םM%RI`QꊖE.ܳ xr܆c}*lξ-h -zߚiQ[7xۦh9e9bY$oɷZ{ pu -Eg~srш("09RE*J'WO Ժf[mPKz=k11ӌ\ Tq^~!chĦ)Fҧ)5hHqX5'iBrgIulInpy`.K&GˆGA;⒡RbUA议'ah Ӌg#A6nUM`0} -ŪĒٟfn;7 69^ S7uC-;u.th1~YJUI -̇ -*Ăk ur~KHQP j0)Mh?ӛ$u?n7$< <(_˷H]Gޟit6Q8ZB?ȔAc1pF+]IqԪM6mA0ۍOsT7EpROREP!fRbU2iQ)Zʞ_HßD  -vY`"6 PvemB@@XqmA#g06Ɓ PDh12) -C(w锜 K"X@ȰxE G $0n&i -W -2ӇLDzA.`"0|F1*KɌœv;jx8y<1"$tA8 %Ҋv! I@hWH!`,C6Xqň=. %)[AcFczFS t]$K LucK ɫE-n2аBH9J<-n$qߵd1) QFX`7KP4,)XVJ[ŏ qxT>t#_f[ܘ&֥CpݸYWr YkFLuUtIpqcThOӔ<&Jr:"Cv29 TǶRD"&%oQOM}Zf9^LO)~$DZ}HB>(nMN/Zry֥PE=*{%Y]h9mC6$ӡ6H^׀T>:i~Oҥlk,użX@`axONyTftzrZIƊ4.M2U-^, ~8aj Q$oG+*EU@~ŜYJ -*np4V``EBx>0h8XX 3+4\Hf^߀EˌK1cƌ)- ߳ @X&&˃X 2Vbť2 J -=-?J4V$G("8V!n`CR嵧e}u?̴dP,=j_7Λ=# E"9{em|"+*#31J4Mjr-˷h[=A@X;i[)u!FD1A8X\r]kroLOR<{Tn]һ,%1]]:>C%{Jp;,%d*bE,ы,%5RDfb-{eQInE -& C]7pRA>$B7mM/Ya[$#2I]Beaz2bzHʈ*]$CQyڟ9͘loeTI3D‡aenp'N-!mr] pAB1Vj%q~%p$QDU@oi}I0 4,[чL9[x!C#IH.P "Xh\. !~HI^kJlEdVGղ$#T׎pz8C ϊҴJ> a0!q -KEK/< 0C1/͐_I0eUeMO<&/~]f%B@.``P!˪J2VLNv_T3,=VHRF(~0Q vG$V=Q1rYt$-ǀf$}]N*j% J -Q*鳺T3.#DxQjnqQSC,U<< nܖͲoŐ/N0l^.'(c8Ppݥc΋;ϣ"v%J2*qn& =d(  "6XXQ!`X-?Iج#{(+%mC,)OEC'# 6b`D>|jp26I-EtZQTpHFJɾдlVV1Äe5Iꧩc2ULbf HءT׬!Rc9FH&jݽ4yAQ!K䠑DH`ߨQUGO#nNߺ#ꋮU~_&UJxFYSȳB$Ɵ寚%F L n~ -_v2v3?rI~q?O]vêw)yFK RΰT2RTHu'!)L!-y"qea;4V XPAMWQ>^G yZ>-K,LJ4?^LjXH]IQ[A6b5C١ׯ~:v -v&:=9U>=5* mh$8U=Zz=h|^9/MVm9n8k4,A cdILE0TLJp ̀iQhX&8%hew=Q/ѸFDm7IoےeZj֙mߣ$um٣瑺~}{; dÊ!\l̨?Gb.(F޳vުuHڣk=)שzZʖMٵ[>O=ha"jUV(*(1a>i( XE,˫j`QALn5à%pgGͱy9\Vd: q72vϫɑ䶞tU=0T&&Sg\,*&&>_o-VtSHKC:pFyo"U2pu\_1jEARS<"uԌ6ɿbFr2ꍐ1Az y^LjWˊZEgH4#j@K!*`wISԄ{f%85:qÉ?Q8 U;r2d8!C *&,`XFWP-V&Z5䦦ɱOѻ4mrTd4)cv\mi`^ \0dOMw2}bBu6 -)"2#eR lrYIv68r*-2)Atx9 =`T^x^]* -O~ AP8"f[SVw@qZvp܎x-͠,r:'! -]fW|[.i'-l>/[v^E2>) -:KI$ȗa=nO|؉Fų(==X=6epIn -`Pp/E}_Nc7YB'r6:ȕ0+#)B< VsS9<qL;X1;Y[G93 z?œFZH%c||ȓr׹ެc2/<,6:lG2涾YzdBN-% !?r }\XB^7ւn_wRtE=}X1#ȇnM䮱IQza%X,:hu1ղ-g՛0YE[V{kQt;G%IEÓgQP8yN%wM}{=Or]'si׍`8<몟fI-A9IT~Uъ"({u?z\v%&۔U7$E烙*w돚R6 h~2عw\mYZdAfiݫu- -nQ[eK旤SPA7*!:D\0<-{;ZRtRc8bۗ'ME\=dhZKT -c{ވ}݆jvl1 SlZ#ïD*jry f,AjqѣXߺejGobik3f&i'vnֿ/6AmqױZ9G.Ԍ*X Qq(Ɯ"ŗΠ@-F\=ϳ80IA帗$qe`I0~>RQ} ok.j~ѻO5@Ȱ0a15Iiͱ#$ '$ϒ:{ۊP4PhUˌv-[Md OAjh5a+aBUI'j0I191Oz"\q%9H{qؓ> d+LnKZ:ǝDeB߯=`.ͤI:eO,*]RQx<&Y.U.h=ajԴ֞%;rUa̚_|;YѣEձ  -?$S\[IشĦ|I\`m"-!5 e܂qj\$Qg|c6h]ݬo vwd'RhECv(3H^'/m6Q5*-kfX!]4|Oo{5z:P?)Eel6}T=Y:B+>3X'Aax]z۾So{zYmkE0R H5O axavnT5iɷ޺ܸO׺,u]shEG3UT(#ѧuAʣfhES~+ofwGQ$L?\rtͯ S7E\RGES+Z$q9z@A9xvGڣ>L~ВEǦŐ\PbQ`/EYn69ږUӫ8K26 $UwۨPWa&Ԫ"ߚuhndz%)EMk`qgMYzų{R='ʞ4-ɞK0rУAoԲ!>bWSےZW,CzqY9zY穒c nZM[>؃V-/U_l*-펞.$gqֹG%)]O>y AA<׌cr@feQ[@%~WϓGGU-xΟjv1E]z2DY日 -,ݢ,K.;Rwm;;4[trLS78n1DZDqb=iXR붝N.zY({_]utP.U(=Av2=o8~(PYvMsUTSQH@%ˠjmݣv}ڞ|D9>k4Vڴ×tUK9~}ic~]])IWhðմ^ Ol߫Z7ǖX[xl ><+H?ʎf w ~GPZoJ3L3KסHAbv{R "lEm\l zF5npHJrr=g]b(b,}=]1;JIS%X$딐-MĦ%K&sCˈGwpECI+:.߮UqkK,vu8ZlE˰F${ΪDm?O^U?lkOrn!z[&B侰't %eHJ_m%ȉ`uXMCflv_{ZtIJ8]'s\.`%4Kh?dH|&nh$$<ù2iEnGP;'VfI¡v=iڟ%.v n14Dyr!aez}R+"{!ZT9n-C+e;;`FI>h& 6R"~nv94E]1jQy'ղNx)]vYΜHMI)zٓ{m=*_v؅Tr/C|~V=xxvWF? -~Ytlˇi_-ySmUSU 7meAi_o%-+_HϳE]EAlU:Ԯ}z%ʯZ2&F - -f@o{jQYEAtH -GSR;ء (Ԭ㳬K -5za -W,)o銟u,gcZX0VFIyz4Ӹ#e 1X>G@eubMMr%|Iir[ ^X5mp$8%ee@,]RM,keۧM ~V}Q -}Q`T՞_ǚ]"fXhb2^69ea{N ^p#cE8P˪bwxrUSb?QIsCgɗ#.z'4U r]oN3X)UۊryS$0.~1’"\[H0|=5 .fU}Te#x7b/,Պwc>Ӽj_,_~J)KѪUe(yiiF nR6$qr * UM  -趡D(n3-:\$ˏZ7ˎR endstream endobj 21 0 obj <>stream -6P?BI)X6 SˣKGWK(]MDW>ggU{sqBC &R>H!q1>p䘢r:e*g#w\ -fKi-,dwIgejˆk&UhuaJ˂d"4o -+ ->`T~;FlN)K.]{jC8^c$A6Qqg&\EmcЫ?K%?y=5[[bS9\uVTyIҳ!`)e$M0۷},# m.GM^[D~kS:^~?lF+;}#w]^_G"5X` N`7u͉\zo,mk38y:OqQw -)ehwe(^O,O -]Klړ!~:f9w4]%(EU.EaKRôùC0}YV]L$u=oi_UMGR3 %xLwu%6 ccPtgʎִwr ^Y(΄"XBZnn~ _x%z)\8mTWw۔q_ndw|esM.>PCEoX 1D*r{rRBnT~5s؝E]_W̲\Ī6Igv:!6C@dմ AZR׹,CAP -ʄjYq7o m}~*"ɍk=*e,i=C k -~_je=)zN/Z6u}tziٮ+#iL(ǃUAٲe&_GzY, Ńcjf.ϓsY تoʺv^EMxAdJ!ܖ -ms 3 U\VE+CevDZEeWݒ^tJ-dLaU V eGٛ%WF[@U7sZ(5Qtox,4X君&^=ÆHEiمۢՌn|a{Smѝ߫v[i- bȊI)8 [F/nA*ʓg]D3#=dGɒ'CÓ􏢳('z[7Pr]϶ڶ)KM>~,&Y,u߉" --w_?4]mh?,q)g3s~pm4=pN!Xn$"d'nDcJ̥Y2s'"`D.ŕTiF]yN,zϳ/,Mµ"-ټƊە>KMr\0 G&9++nSZedDU$}0%eS|&!"o 5eB=P^6LX:LZ-/0n:*1%vph)7H`?XLdDMhjgICnei=_k5b)-Rʿ˟ekNyMPn  !c[T3>iSD9V=Rb6J^/"_l&z^m/Joh]PhIvuDj̮0 oH^{L7KPj\6Do+S,wo&mv|Yx:ѕyVZ,%uj5/5s<2#$  ˢaDH-=]},mvvţhYD蓚;yQԦw-MOMkX8<q7I*F (xm,^UC[e+`YGEdz*1j={"~vq6m!Myђ6IHCjʐ<2 }G9~x@b(Z˓{NgtbNJyOJ^양քQt59ش"bԪ@xV <{$NVn@Lz=(m:Iz  ĚߙTɍO[{]upkSp)IJ@xf$ǦxXU&6qq;ų#iza'r%;}jS. ʔo(GrԦ=Z+.JI݆BǞCCZ{m^ZPFvwίCxARn߫C9z¡w[T?9wRK. !=B69m-U҆ -I 3Qx{ǂ^~!^=qU_5MZ"9AOZYN0 4 jFI$9x19s܊XdCrԪ\,h-aR#0G==HZO6-dAP*BWDKCx^L"THz^MUsv[Lw2c"l},0N8x؉s dSF]Omڒ]mlqp(#52@l;"x=dE,zNu%ib hXvAAKw$&9`d4mn\DHNV3RHF|Oy2|!"QSFA2b]$E So^R#|, $nXr?ɜ c:Mcd3V!*j B=~2#Yʋm2O>@d㱙!à -qx*~Y|ȠYiZ|o(䦺[4WA"2SudM> AR -z.Ð|6m$Sr۪aP/B%?<1,TmX^ZuĢ-Z()VE0c?Qf`e1Ls/\v'?EX8iq<2& gWx rOJ\cvlrUhۗNvIMU>%x틡mޡ蛧If4X DRS-Nu#5m)t/- jDuj.>ov1-LbvU UK+٭ERʠFY&I,R )`7eJJ73)Zr壏׈`N~Q~_Nj iDG؀B䮦W%)nSB~Jӣr[aUUX-afHИXHX1 o`@B@ D.#O -O#fz\6)`$x0 ls (AY0qޕ1}L d'xA5O˛HEIJ^o4ӗ2 -bkPjjz/I6'ybYUMs59VRb8w -.xdjbx1uvw,~ejS ip&j n4zV9DTDIIhZ%Jv*i=iP $E%E)nY1>rlny`Å  *%1<ѭKfG,AbVPi',G Fi+XA%:E |#ˈEUN%2 ]e*ozPҳ?Lnä %f0Ǎ&x:NjJ~!^(#MWJ~-^\RM/^" -V -3* H -.Ԉh-=\Hde@)A0Th`zޯ -D%iYH -fqpUQ.K^.j#?,UKv_9KqRav :+[ߙtq֑"`ZD.xe2u11&=ĈH+ztGLb>Xb;XB~h!a}B,ڗ@6Fqw`22P vPca Iݑ4 g>ZH^l2T 3b*/V"Ð~OrEUN/\(VES)%[ +h1MO_yY{-$m9&b5z2v]<>C#*#$e*Bj" ZFPyŷaB<ˇ%oS+zUͶw!„DE:BŠ*`Q*:(') C<E̋V{ړ%" %?ȕ:PTAČ:3]Q+#r %,bíxs+MZ5Zn5ʱ"b%ňE -] kpE|$bIk5Aib)#0xƈ C \HhBUUmË &e-W}ɬ -V̟%T<$RN -G FǤ]m~U@;$6e"-Xrّkގ"y(=wYR>xn蛣 *!y%eد/ȽP5XPJĕ,x)*xRjΝvQ@ H5Y>7fB%>%XWV @&/`~@)r~.aF3\̠F*;zZxi2?SLɳäۦ7GI )A:hӞ&5-qQÊȍXJ~=B%f H #Cp#%f& igO )b`2W2+/:1VMK*cB%r5  C@@D!Դs?>vb!@]}D;Oߗ>EȮΧh >9 |/OnD %(397H oJsZMNL:D^1I_*=WU'Tx"J&zpbNtk"LdUDBQD܉"J*=WU&:*4EQ'pb&e"OdUDMPDyD1%*1j*8]Q'z0L1&:}"Ld)o"NVDMRDQ%*8EQ} -0T':eE&(w"NPfLTDQ%PD*( -"|4\s8F/ĨED؁0{pra tRkܑj 1Ƿh4P^Sܜf\ (5hFrPZ?0ӵ)\btAo#=w ㄵKgZC߫B+#Syp,XF5k;A)4Ty}O71AjEKT!ڏn`W϶) 7B e/pNC ,wr&=0mJ@7} B0n- -w`YH2z^& U`%y4L-/n0ָF=/`rCW[d}1_ -QxFz*"Ïw*EɝЧUT._~7>;Yb;d9rXAڱ&o"fP,x!׼tbOi?ǦiE$Xz3zay)blu.S8d] ǨRHvMcе,zhO܀".U.K6muh bfC?e!"k,w=j@嗀'`P"W`BtvtucZVgTv5(=W% i%B?*V/H>`>0yi -,%P|L'saZ@!4.5rj&24Cj<9R2ռ' 9xE^A.PI2C^/+_ݒS|-J; /P8ܜIKPT:KYV+'h16'/];di2nS[S="3' ( *FbY{*Nٛf߹ĺBnos6yW?QX/L z7+x^^!_М!v G[`rw{wb9GS7) q@ԓF!1VA=gՈOp՗kfeSji'g$ -Zǥf!  ]ZڹBu.&7C䲂%v+!4NzR%Aܿ}3rT+WAp3d>Ȉ/C ZOvqfXPiRwlV;{Ȳ; t3-{aZMK5ai> h[Pص_&M5 }md,E -`BRhukN[cUFHLB qP-(vqȥ"FQX. -3J;yYoXeIcXgu£CjV_ Yaf$0u Cy $TXcrK+`FdYl""Ҭ` -\3= :lSn'gN+$f@eE} ,l0/P v{yO$*ZƜhd.\ғ~OejLVIAZ{?YoBra l6#j`XYPHu>:^r{]K}>P: [g۳Sm!Z@|rȔjfπ0%Yb 4ftϛ1t㧐7GgEn yOo`?,Z}};dd+W{-JUXvt_3 K;֖2g7ymۉUQB=kֻtcwI-k,ЈOG=jur.0c5C(?~\(e9ELB\nڞLլOp2h [XQ#f C uA-+Or?Cbn~jc ΀IKNOZo@/Naҕh1 -u M"&ɮ b5CZXيRy+)6*:&cO= rDBmh\\\&2_:\DNirȊcA|W+g~*={0 D^ 2(\lp@ͳkf#.Qsc>N "m_Ѵ_fAV۔ꤣڰ$BgA?.Zw@ -%.^ᘓ6RiH֞)JitA]@T+h5Lݰ(BF&Q#rGHw=qѭP,KȀI @$N3 h!nGo*%ּ ppiWΟS(V,3N -%Ɍ];s])2_?.*ppA[l]f4do+7rS҈۬:yxStO@K -î,pƗ|<ց`LB8zmJcݞؖb}_9ǫmEʹ| 5vuKl3*yOϜ& da-6PNG|![YM:ow%9//s(*'NmkR,D´$J~V4HG2L *Q0F~Lsw4B k;-#@&_Lҷ\To4 ^I0ZSCZKxQq`8֥b@YEFf'OFPE \q#3!r|90Ȃ`߇0r`7VD^&:L2&BD3Fܥ[`,0]U -MEMd '5^3a'@%\ cO#rE@4 HٿC~,n*c Z*+78[?&61 _٠<4C τ';?0*-3;چ1u}|ҷ~tG:>W ,nt{WgAQmԶ]!\8G3׮0<6Vw*dBMȎYn¢5`sLR?}YYj#Z^Tp<Ūs#t\a i8nq׮_z>@YګӀb@d,L?CL$5@6C`_RWmFۻ':bjbXBdewiGJGXj, T"RGdL/EtQ}LWo$/zA%v3Ȕv[CP5+FagKh r`VQ!lE1% MpgVCwۆeqO]>fTH Ey,s$]VgEoG5 ]o>-k -[͉X^ۚF £Ӱ'#kunxXq4$pVu((d4=++14$$ z1/v 噮J}Ks7wȧ<2eIK4WYAoMӴ٘QJ5؄)"ۢ T&憇FTFk4LWk `Dj>HP Լ:,L/3 PM1iF<.2@@ocx4O{{=V|<43xznӤi}\y}c8E-" AJ tw OAا&@>%Z>Ι٧" $܅> ;a* -̂.w+)h@s ^@U9]5z?) tvpܷ -%8_{x~tNWȤW:2L,nӺ2.{DP*!Wɞc9#t;mXԴBxMo6K{Cӿű"/\  -9qZZPS)=ElM@U p Cx>}!i ~6bi8TH- &od_a1f3c02400-1fae-4bef-b17d-8c6fd5116b45dc7-5127-4226-9c7c-cebab14324m10SVGFilter / : /XMLNode : (fxmlnode-nodenamvalu1 /Intt/ArrayeTurbulenc;children/baseFrequency(0.02attribute; ,numOctaves2result(turstitchTilnoS,feCompositinSourceGraphiinopeinwidth100%objecthxxyyidAI__1id/Def ;4fractalNois4GaussianBlurstdDevibfeOffsedddoSpecularLightPointLz(-z-5xy1ystyll-color:whsurfacespecOusConstant(Exponek0k1kk2404313litarithmetMergNod42yBevelShadowMorphologyradiu1.diladnbb-dbn0b2DisplacementMap3s33xChannelSelecRyAfeMatri30 0 14m4animcalcM(lineatotofrom1d(5fillfreezrestaralwayaccumunonNdditivrebeg0sn558ccc1ccccc8cc1cccccnn14-54CoolBD_63erErod6_(7spli1 1;20 15;200 200; 15 20;1 1 1removRrepeatD(indefinc50 5PixelPlay;20 20;Diffuseyellow;green;blue;indigo;violet;red;oran5Dielev6azimu81dlre110001122nredBr5#( -4b*O@P  aa `a0J!CUP /䁸m/n:/gr~2M!GFL/ԭy!4^` ExWAKL !9-BIv+24:,S DNJ̐_tp~Co\_/^*Z(u2j^S#-D5;c4gj Luv4+_,%(GqkKHmZп/,j?Л>qJ(E -#uK(H9})#$) 9وdkU,,eDԅx sjǕN -x#+Jl4`a&a8f)ulԤXGgܠВTθ #/D69fQp畼C,gnZ,&0`2u}T{i1| ØJPnjsн6xxV]4)Xؚ*-Fx~, wsz{/XIc@Ns^ dY(7P n=T4Le1s=X_mUy2x =7S2@SxXf)Ǭ 8DKye 5Ma&*1?X7l,!hQb_KTQ;ϫ;UPb3ޑ)Y'4pIX2EDo$|GhǺisMAPGd<8oR8rU+hׂ =;I6.lBpBX5I)Zb569 ؁##bs(/%Pb!-=hSiZXXXAY<,gK%Q|0TZE]Ad+zy4=~Tr+d(IxU#w(q-!_~Bxo%2T#u"`O&HGh H$~r :sۧC -l^G#ςӯ%mCUnfa'X i-aҮ,b#5ݭ[)4i(xeTiho(yajr6C#LNBUy g+eҡQr$EñM&1x1DG!g`@^buhՀBjbƎH@n\l+?1O{/;Ep0ΤJ;CO)0C|Q`$0nQ/՛A7Sf #Fn>.|g? Q86i`go1MaQAdP]|UBؾCf]EPO[43FD1jF4bL@/>zϪ̚*awQ4\aۍ`T_Cep:>j6 $^7jvva$n40ӳ4Bd/JIݍ&J% _/9 8Í"C K%gtVYlQbekzRˢ89>qȹXCnok_z ')#HӮ!B۬YaAb&4mTxK! \@ J g )K! X':56o[àv8B|rg(#V^ -G5\|MҨŋgeoE*f˙gf-b5EjbZ2[ 1I b98؂Ev#ġW~L!]yȌhF >tF(SfjQj%t7᝼Y}MDב״5JAǤcs$EKIjLfNvDҢDW,gxC΅ceYy)ihzqRX.Zo[`xg`:)*{-ϙ RIhTroI3UzIzӻ -nS%kVnu}ƄthfoP!9HQ[B3,Ix5>MX耓@HYtW5G -* -p0ӐvW^<3 -9PY{VU H # rw )lāz"9v3ێzW6<'" X!V[kPS4"xjP.cXB>36> 6-g} -6`Vh ->C֧0BS$ -Sx!0aM/MКIt]PFf-3?LrN< @7+ЬYXˆu_4l)Kl`0KK7ӹ1 J=җC' y\^!yŅ \،"8 S>M'k&kiv8+"UZp #5#, k|qÑ8@ Q~R1?. Մ)âYo5bD9xtsʑ`"+%VC{%E5.T3Qb:*Ց?bDնz\1>!C $Kvy^H;DT' -2HZ磷|!?b(*7DQ_yތX6xPn DG̤/j&x WFK1 ©ťxF3.RNK6bQ|e?4jAfhY˶DQ[ZRY{H[r^;mdF10g FºFLuh#]6}S4Á?##nuI`ޖO*ڌj,uTEo)gܜ>=rhQ \g$#@h no>#8(qCJ8!M4JAt$/<{-}.F8`H\}:@ȥ ?`!~.<##!m/^$*xw dVzVNz$UAxy+̾NݔdْT:\U~$DpDُ|A6ǁdj{M'/M?:st68 LP  - A ,BP -Lf*HpAń 0bBD`ƒ - 0„3B .HP8$ '@ʣ(`AB -2&(48!L -TYx`**!BR  4fl6& ̖ -9m/ȰPt sr|_1~T@oAcO[h_3R,%-c:WU%uS.A*OHuWCX( ,@,Tp$X <a -p &4|L` hr* v,.+"p2ơ$ru >oظάFѠxXfFv-  X+v$0^^45DbłYa BBHGJT͢/%at#bAGH\0 -aKk-f3(n>b:DpeeQ>@ vTG972$YE3v(496`bB~7gM9O\{v5՝3o_z^SQ(F1Q(FR -kEq+Wxs"G1 -QbiQbI%E9v\X{sFy66.08H(FAx#8R8e(Fмp-/iQ()M:Ď0.8\(@-)v`IT-+Xג’V#G%|87UKp%-{M%՛ˋӖ6)=Ӵ+a'[mJFaR֡AQו -nޜ "o+K3aSJݖLSQSXgLn> -Ӽ].Fv9F۹m#*+ƅ(F1.(6QAut뎉ig$<. ˡ8aLbh{enMD+i lŵ6w\˻b*=&2fÖ.!!6\"!!6Ԟ[>t7:xu{p;z#]ٻ*UXU[[hHyd1wiВ ۖV8Kvy{V%kR_[ݻ'j(m+Kngwf?i*նA3&Ukm\0H@($4@0-X  DHBBH@~ `!B̦¶%[ry|=%˳sTxٖlP&눝l6ja%<⴩Q)MȥkLz1&҉OFVnzV\T- x(yqIGB9J?won9v[~$;)7ۓ/%v>u4+5=;gͳbתh72u/g=u9)·sGgBcVPkifت-{KmƎkk/_#mj+ygt{b[Ef{VI~FLkC*72!o|?I3jQ4MzEįբ<1f$ 01>emtيT|I;%Κў';4٩Vtޙ_~,@ @!`Aa.x`D 9;ai1Mί F!w1Ioh)7@a $, *+\TjEmI*-DT]jݲ\$];̑=mjӶ [z[Z)3i[DkıFCn'ȿ;d;M;JF+'d`\/GTSrG-g!G99NěMwo 85W9T#`(kںڪ9z-#sx0q :;޹v33zSen-+ -lߎNqHu)GRg9YyI@PaH  p -$Tx $  d(󭛪y1+YװRꪎ1X{QމQ8ʁLCAn>UUgu]TT_n^UQewww l-=+p5ݭwWlfV f>33yJDT4l`{_g_Oç6);eRfZӖҞjW~wE{gf3gzc*Z6- ,- ,,2,Pծo3PٸH۳f;ڻ[;BD޳D^DgLNLlDKL,.2P/NPOoXO!d:H( -2(lVTuCG8u0dOdr"^F -#li4; ^;6kA14Qj%ˋUP썉4U턮cRAXKڣS#R後W:eB3FS*c;Bh0Paw΋A%BJr p# pZʏZ_8\W% *ʱX^FiNB$Bhaaۙ0''9 k6Iu xΤHřE]z4=[Ep) B6MV҈Y BF7  3S )<B_;q0dNb}~P/%ң ;\h9/}e.CeV8 tƻ,hz-$BP4^\6' 0ao`*z|lRadpk1 Z䛿%w?NtRH5sIAieݲNJgobjKv\WDrXߦB*ղsD:vq#CQk&E5cu9#-3ԏ f-}'Pwy8Jt1O:9Ee\ -$@(~g$]Rę߃V+b.) -1r- *)`N=J& BSYZP6{Y;`م@HZ&-V|S3H4soIO୽icv14* -b~dL{#o^?[|*< F,[ZE)ñp~}= hIՎ+nĩ"pOo M>{vkbJ!D6. Q 8Hipbf:θ?ul+~͘9y -Us<j;Ǯ]jj?8MV)Š7Jͽ ^L8'6w=.dg\W%hm_ c':%ґSfYJb/(#>Z"&C3I T_65=MPkdUPbA6\Aү02QeXV0z,PEV5~Ve#K -L7^ -:c-9Cd-\G5\;5dE+HC~Y#e `vQ0"۸F̓)@{BCV!Y,9M59o*`We S'( -! ayU&YwNGzk[uCn 6| T( KXpM@3>㵪c!cJr\j| - dB0 1!e竕4L(29: yΒvFs^+ !?-%aCm:sYN*yUUykV(>4O;ɶlwKm\HPaΎ~xhe&xj,MJ/] I6_UbpT<[T:/@i$Q &Z /h=ey|7"1%H_ڨ)X"[{ صYp}*+dYk01}S8ὢJ,tD+*>k3/d[&!rE.+r UyEAKH.0(8VSm ^QeMA;}.6)UՑ*,*nc$ \Ih0¦X^p&CVuHCAѯi++(^@yEaF,-|ӜpyPE;&96eɜ]Ic izHH <_40EoDU[-LuK'7`+Ш: wDQ-y - -0YBSZ+>pu&Zs:s-!!W<H-Θ6W@0D%H`KޢU,%H*Y^ܢ|D0٫&Wҥ",Z}@/lI /ӿrX=bNmsł=.g.ڒêӃy i^K0̖輫ڵmLC4Y.sqD/ĂvK i; y~7 -1%wyH~1 { ~7J^㷼R >w - S\Wo@'섊G۴cJ -,%SES"թvR"bG(ş|.摏4D'!PXl^ְB? HJLA X FWfep +yzلιF#e iQh;dM}0 HMŃT2[M=!IEu1 ^i7H#f$ A`9Mlpx4V( 2~^'W2B\{Q]E畎0L1 UīİF]_csR\} 8't L"y:~-6fY3]e ̱D:Y50Ya'@'Z*-$MYZTl=ܳ,6)K uK'bdD<ك͡'L) -T jj*J@2MHc5˱LlUeDQDlLۨ%qpIJ| azR/ 7v_',@"ZAk6 *):Ai< -)g1WC!>=@ѳnYus0<+Wc16tb5ݴU:q3EAQ}q*(S5 Lzh|D5l?vR[z%+Q&”#,XԖ;\H0DaoGp?ph/:UtSY:GXYL_ha;ތ71DM`yQ[:Lsmϥ0J}Θ_0:1P5+ -P `Å> HrGJ JmI_ӌ^rP_7pds`wdUp%I- Րʆ$+!yz l0PZ-zU| zY!ӯ|+MX -SGYgX5Ed b ݢ6"`.09 f Ɠ5x"Bh0[3?;˂+K8ˣ FPĠ?1 h>l釻a:KZ .ɏlX.3Ab!H|FJ!'CqiH%M Փhi0Z\>+J7I "fsb1\Y5^Cr$h: I? T=31nJ <%bU&hAMR -Dl:0Y^cԡt>Ge=lK_qs|pgc1 -k?[@^%`|]Յgk:c< dh10ؔ^r0 CayC/{-6k.)oKaR:֥>Z*,"⒉> 24w'0=lo~)"wr8)М[U6^L~g^3#tJ{g|W8t` Qs,b'\HgQ-YE7NF/{V*l{f - .t zAЭ"1nuv,r(%W0V9dso>]B.ـ=LP\|\̭(b\'2}$$Tܹʲ*Gi+PY.uVʴO -xj$u䢘+ -#I"iG)MX4 p|B(5EU i5$Y>P71h4C -Mo*n>&Tܶɕ{'dK+0R֮,KFzms!)jȊ9bH0cݐ!>&!9KC6KFjyC |;dstZNSu C-'}&Y JXw [f~6[!;ura""CC'B͠7!Jq+!"@3 xӇB'1,v]B4^A&*U͍H(blAz6ƳXw'LJ CΟ7&oafyrٸ@vڻ@8@'9yKѱ V@YLh.ַAU~Gҏ qw n (ۮ"%D:h¡JFV9y4Z ;W`QmJIֱȜڳꦨ$fmiC4H m -5ub-+kf};ѐ8^MHgqVkGRҞ90(jyyXPf|iThJfHC -$,6p<6ׂBh.Mbqkxo#FZxA}=aNE'3*nk>"@kɂi%h -Ȑs>p) I7c4W `HQzNCK VKBbH~b* ؂T߶uQs)BuùZ/wn5]m[A9jrM6U˺1ƅ0狱YIjo61ǢxM1h_m.9Du9%PQY]`t\y_ -=F⣔5M%u/R2ᥳS ȋf=w,7oKxT3I!_~NMsLeL?ZVBM4#݉4Ta٘c{C. -+Sdŀtr_&bG}ؚ#<[O՝kDŚ*~oF7 -U#zGZ -y-q{b[` 8W7|^9kJ#W}JEe}errUiB׷yڼxZkl'6i6ߘK:Un D%Hx)'DXpYf3kS2ɤDG*.FJ<3 QTbieڪ"!AqzŐYP@jG>4I6]L$/[o#P5`3OYӐiJY5lL2At8u& 7-hPO)F2G>/ # $vrQ-I!CxK?#QpB(,W"׼хmzPi+?5X+|Ok0)cLA% W3{żxTLqܼ?n㥳NDϑascV;-">l p1 -+{~-P ę(Zk%B7HSVElv"|smZ`H. Ug7 -?y - L }1`Zw  n㕬 -ʘb.8_YBd}NLk rLMx9i|o"nyq`؞ԦK;C0alhN`D՗gOL{Ĺ6RՄNU|# Gds kWa6Yz Ȩ}'L"W1{ӟ q?4/Si> 2- -țg_Bƍ&kJc6BA$d HPDL1E']=Ǥatj?棝ӴS̝>(VЇ7 I0TJa:ugR?G.1AWBM\g+$U탋BK$64bPe -k+^&ѣL"N0o'_ԧq9&DX'ts8۲.hDu8}@> g 8GY$P4kφ/`ɼ4?z61 ^?̓^KFW-W~onB$@; Oi xx􋝩G 8H,9YI8 3em2&M^M$7wg#H ]]d:${Qu}@iK}QfKw8'B_ȴ)E?N^۰yvSZȍt`3.]6-: .&2x@|֐Db2McNgd5#͂rM~@ 9v`QLu=@KrqR !!}Sᝢu$pjܤڲfBY`'}A5f+1 XS#)~24^%A|g*FbގG<8}1adqY<:.I f4iYcw*Q[֕w\p` -WI#|RTX$`킜f,@$U&jE?[nc?z{ -o3T'0%{84pm!|L9&ߒOlTӎQcnw ;\k@"nrB3)(nfMT򔞓{ v>`2w4}[nZ"d1 J-0jR\rC2jr.m}SkB-ɬ^2t+™ogC`y㓿H.`\cqΚ mYg0k^yoLv+%m`2l`G>zaՌJ]Ywvq!-3(KrR3z=W~M*<H*E.5"`,-E$9Nh0,&7ROFk Rև=8?#F4_SϒK w0Ghy}dtlKsӨbKNbj&qEwB#G)NRe,H@d9ı=@Xi{]i[BϷ{ZcIxʃ= *yIiAMBE(K}6 k]8.cVEuz9bLB\{Gp@ߙy/A(=T4 bGWLXVOQ8pʤ+:z- >onel¥H`aU3&SW#lB6saڽٶ@(0*M -,çs$H0ҷoM =mbK/RME"A˱Oob_-=0UOJm&o8%VEifcdK+JbcDU`-3-d7q`޴5@+xv7xk¶:n=R^y6r' D^+9.

jg8ש6^˩ugO[C%aH+洖/ׅTT~LBAN~ [q!AG}[Yղ,-cX! -3Xġr!}2H\X$ɇ4 fj_(!FU))gYU ",HݦV6,+%dsCV?\NuϐyEo*-7VXNUc{ɦ Ϯ.WE*iWSJ+Rˀ(i-gOU y,#sab.v4WLԮ>Ne4񃢣 -$ƳkCc$7- ȫv >7=Di·g{xuaX9~Ѓ7N?!"! -ߌi. -`,LFKk}eok4]_brϵC-~|J -#Pf!J@ˮXK_,f l;܆ÝNXfQWDI2h>mv -ΡHZ0ؾ)X Zdhv(WN(z20!loP/9^.P%DY/ -nv^Y&]+Y#^%\3a%^:AJ4.%v*r -s}eFFe&U~4y 3 >}h ܺp+<$Td@zE1O -@#5ov~ÏMM@fY$Չc_+Vti-AZpPSqKKMշU0 qP6#KHZqY0ji]GGr.mɵeoNg~=R]1DkJ&@Vrs̎IhIj&)C;jl gY؉'Ҭw>2Xm8;W8gyFMb&!eWXޗT(<0@4J#u!f͔(BfQ\Na|熽9am{}լj34x?h(ae3r +3)'--J@^jm -Xl.2t #b$~1p@c-,'nHP'M\@ `u29UȻϗVv0%/( &=dmC@6t @Oh7 -gEt ࠇ 7q1`Kig}8 =Wx.U\՛[Ug$ +jqpv6Q -_9.!''J3:X=BZt0<}S1VFpl;=$:tB8xEsv/{h e Ps\("Xy"0 {2ܱ񬷑I|pY5Yct) -KIRvc`rw$ᅧ2$0lAtbj zFOLj aq ݃FXnb + -H8H+3SMY2E-5@CJ|D9 C @S󠸍Gr<>ٳ[`Xfjy߂ԙGa -N~ǒ9˂~vp?PA,L$Q@.Œi,XKD (?#,2Lu Nt0|!Dzg3<;wZ/V}j4UGK#qQ ޚ/yo -)ŠLP ,.7\M7PP]YCN\xB*$׀O%DžoVO|3xU׆54_ -,m 7tC;Ȍ|453E[.tXu˴L TWiX?N Ak(g*;dcs5H@9GL|M= nmw#`d݂ 6 A}^FX6A2JQ%0wh`4ԊihmH3+?j 82bxX6RpWJ&;Xx򧠽hʱ e|t&a+f:aQ`/H9iHuۿ\5@̳O &Bs3. -6S43V$n=r^$u԰F()v).R::u/w,Qhύ JȺ&lf,F}R2t$ةwW4s -p#dSI#U]97!u*"Mn\~KYba1`8$Dt\A%+E58[&Cnhzw9@Ui͘U!J7  -%Z"*d 1}RccX>d.KeZ_\ҺW8yנ :mtw{:c;+ȲZt!I dϸ )?MA:{so,/M8ÓU[Y7܎qkm$:<‡>[1^h `.2؎;LY]UofZj3iPYE`i̻5 -l^ڐD5%҃UkPHĦ$>DHc? - -#ފ|m?e XZk:ӎ7|ffۧη'SǓqge*q"z,*A/@˲G2)^<1D@O FZ?cQJE%XaSM&R]tDV8ۏQW U:ȟ|{>mM^Vمޜ-؇HgU7!mIm߄v:[t-[ąQRY/OX4GWL5{jӎ=nohȐց@} BEiO$cX;eBv?Qf˟H2~D9^QNfP*(*c; H2{!=,EIYDD>ʦ5F>[vgD(q}dIA)$ֿEp㎹hEn16 T\;}hL<~I ZFɫQ3-t-١: kb/kQTܰ@€.5@)t3U]ƀ˩ý֡b!([RhzB8Rr'qwaWfQ<3hfut%(5Hi%p]GH.)|]%$nAW.xxhPb#H/erUv4FrAյ~xI#6o҂xUc$1֓g<0XzC+b[e*ѣLWU]uk\'7~؏ḙ0[;Ac1DaO W"gоq\y?(_k'5ٺ}!dh+Bo E,L:9g"?ᅡ_ygfz|ktڶ ,]XGfLH AE&7=V冮m̴ἂ,Xԝęa $"v~qDOe.o1qHpAe:Y%:hnpV t/L_В0kܭ)x"N,h [tgS:3BIq8= U$JIu5 BmIL' ފ"A_SM'*LvB0|Ӵ;T- vmFƆKT*ѵ`kzQCKԱ3 -앰)IeY!t|Pkadž"^n:XMي$@sC?(uiộ#`ܗ,h˂F`*opNVLPEAf FYRs+abQw"68W9 -? Qf\Q?Ƌ" +$9p- ƃ -nK=GDdaIjWS$.ux{yagP?;lns}/:~[wma߁} -18F`hG^hq57g"LQQC$!pQ5'S[5UGd18 cƘRRie8lbq)Z:CVEPۙm@6H#>"1Bke - --Y`/oPub&E&&RS)\YA"{N}sȯ@.U1y!]gb8M CvR!$<4 a۳ڴj S47!J:;d%\wajY xU ;g0T(BfV)0G(_d𵰌C//cuFIWc_vesjdS{YMAVGuJ)4Q(5bލ}&HM0flmu͟ - -EOH?(^1::YoL8Y yDŒ s?f A+w]jBuwsD Ήg䓎D6(4>Uhfq ("|+[i[ D>V;ԄUEeGcQ1jK42pk?f-:vqkwUvσ u - i= .$:UaR{VMvq!& -V3tcE[TC;GYR_ 8j àXXQC"?)"r`pL[wG2\]ҢpݝZR l܋hyRސ3O-[ͺ -S$:ȕBn-7f8֩2tر(%_%dP‹,; ͧg5NK7u <l'dNg 㲙X[J|2Whr"b2cn+_sqK2PHaq۵1;-;?ł C2ɼ_~J%6GqR8cBkIōP2v4~5U<[8N=NLǂt(7H&3NUcAlxm>Li8Z3>Alah|KdQn[} 8b5@}@Vye^w{j@$56.yHjG | Oe\0+R^K=$[O:@f/D*'nkK/r+eI!aGFjy/޵#0T$4d#[Y\6[Lz=KW+ Asrȍ1]xLP}V :\,k V`IQ1EgMmJoQ7D'hl 0RY .u$imlCF l -9;+w+m{BFT HEMC^ڼA-O.?Ig 0H棰.}B0FZ1ᕾr `3=V*ꐆ02$CE3bc &D8{,aȑUHJZ\%/E D4B;y5rݴSK3sLnFR S(_V<"3\E ޅ8x8({yd`ZX,ws|#ǎam%Ah0TUt-|4m0B307@:͙0GcrqnYA YRy*#aɤpcc7GRO4+rªS( Arr4"[:0 -5*{"n -U#aُ>/p>Noan}pT/37_{l_эrK̃Xj(U0PXd?pu]>Ky,Yan0Z2U j%PXn(5k> 3BF2O967I?L(/vh3 "^"gܻTr}3w?R@V"q25=tezY8ffN&Lo -qHwMzaCy+GCɠ?Ȩ:2,Ρ$ gX -UL00|F\tS87=6%mCo -3[}5Txw: -FS2nF*Jї&>RJ`b磾6-@4H}׶8;s}p-%=#u(rCT~"rݤH|m:Xkg6f,JKܤ˽H"Vk^D/j|b` F.ف7O>#@uJ])@94%!yI{eFܮy(@ }D -a@(Є(3,- -  -M \ {wXn]W<\F@fzԣ`+a*bi+]]F\bv]\d^-.;FmImmmtn)j k0VYdmZ<0VA}]ƕ8ꮭbl.ṱ>]@]v,;ֺbm[ܾ&,ul}5@mU7i˺!3y~[`~ͻoTw]rպ0y-6cg 5@wo\35&`W ´U^`>yfCZx y}3KCW{b ẋ1@O~=`Zk,hm1\}EG> Pe5˭&)h7Qԛݛֺ]yr5˭hfwy7f{o訹ޛGn̲XGnt_5\GM--}קy+^,Qwi}oԧ//ϿM}k%{.?fY{on4ug\O˒QoͿy<ɿ?;ђo1O;D9syM~r[&DMSo_(?wYroor&h?M6GQn^{]ۛ|k˳\Fec}>^;\{s,}{y(G^\&皗z=7Fy76ߗo7v8u76zZs?y.5w??QtKToT -jto=jr]?}\?O_o72s8u_uO'ϳQKq6ui=QoOk8u%GQi~_<4G}}뮿{cis}~%?ђo޾iw=irs&KEG7G?˒ "7Ge+!^hi﫶Ƶ};fظjfxi-[M[ٵRHZZ(~&%uݫ&]~ZStYb.yV8~eoK:%kZd+Wl^=h&.nor%5Gg\6okHm盋0!H\+qݖB:56GR^5֍ h>6yy[w 'v$;ݑeGv իv{ARWkհ,qdute}s]AC{Kh蠿Rvו]nC uJwӑ6@+YټNuūLH:r^]Juno;^P7p;C+t1릓ɷ댧>ֱ*WS(\{9n_47hX/MESO?r9rz;{{NeS9Fϲ4=99jsͷ/Osn39^9;{5fOsu%hwΩynr윪ۗw=Zٻӫ|mn{z4rw?Q~}F;tsQ;MN?ѓ'ST]ye7Dܦyh9|Ѯ4KDKܾ?(ߜmr\T>/ϭO[,Qt}9[<^E-#*9ZER4Mmmn4E{x9&?^n_,M'=-vhEo^{E}4>LSw-:.r>rnqwQ6]EY"G3^vG/Oqewߡe7K.'V*W! JiatDL(l_DGtTf sb~e/N '7 3?NwJ4Q@S1=}jg!|k! 7CWƄTj79};^ jl43qSӿZ$43c4e=#n<6 -0R }^tH妒:$3 -:42Ǚ1-C9n"b7Qg⦄bI s3bƁqaaLTYtK= :"O(\(\!@Ǚ ƦM)t% -N,IX=y!!v@n+bSb} [[ $U&1$_⟮ qQ"2BT ,Ur RDxBD1DfZQ(Tn@2糠.JM(lFz?͇EC;vn #EyPro&r@1>Ø"dŃX Bƒf l[Zπ0 icȐʊ@H0l  ~}y ֪+ۂg4Nc4C|`:B򫭜pL7.d֬ l`b-xH$PYBCV -n -"[ --Q I  --F/d BLU -0GgPA 2Aj+-c Y M‰ 6 -DAyYIC萅p$ЃcJ; a7|y`)C"j84 <)@Nv/ i 0V}HhP߼:e3* )~ C:@x̢>}X7zdqj8d@L֋7pJ.W;g;-hEf޼2O`^6_PG#8Yc5MHȤG\B^ i}KixVߪ 71C{<&ފ@z"ⅻb `3KqThY<qzj(={ֽLkxhk1C+D")z##Ыi l"p@n -ݚt,mCXp6012+SkC,053`f[f.5I4ZʔeBb/ b^0`@=baH%az ,*[l?nO 'N9~:B l0I, (H_$\ uUe$, -I -,<P>&xD2M!7eE .L~)z|4nx䣞筠-eMđ-fUd"hɭ:<(s8EpdVH<|_ c omVur {;VuZ.v2M\ k7V[ێu.ܽsbZw{NvvjܾخvՅ+ˣnH<׎u[XW[X ]cvYXܱڱ2+6zb,lKjY^);"Ȋ"}t`-wmgt5β;]yWku ]Z/fle ƮfmL \k,F\oz ]f6t[ka<VZ;7Y}].zi/Y,kVf_c-h1aέ.}1vi+v\.v+v c]#1@1 ð;˭`mK^[8^[ZVXp^,Fkkr2εuGX #,n] h[ (í<5ؼGc6@uw`1ƹ[6buGgJg<6~W.vG!PN);ڵR7͵cQ;;Z4DZPbgyՐ))ڭ}Pfʘo|th'M^ oU]U¡ߠo;up_X[%;sټ7Z+w1 pnc}rjX+ܡH,v]kЙe ƙc,n6V[e2]dïȽ,][[yys̬ܺv;0U)Ju[{^l63K[s^"}.fyyuYcV&m+BMer5#3!pxatlVm*iHqLgr8_R%L#j839z䆗VUK K҇,4O% BidYqj҇ ѽ"2"#;#G> G,Go}lи -~lG,C1pZ藂 -"LNq^Sqtf2/w&C7-9UQiK!tNÏ)g4?R"Ln߈αɂթR UҐjtVy:ǜnh4Br4!*ie>2RH{؄ih:eMlDo5WF~\ZPX78ILE,/a5J@ Q FDr;&I1Qb' -~@VF j>Q!0@pG*"RIVV'>0yof"hǁ+6?VtVj5ZcOⶲhϨ񔆒'aed HbG@Oin$M&$zxi AM@8U,-^ZMj(i, -~4QevS^*e 9#H?= Bq$e@N[QqqQ ->!ǹZZbe`0B)BZa!āQ. 8y'A,[<@j$a#0㛩ACܐ X4ʭjXI -(<, @D2wB1+̼z= C>NcsȍpmXqmڋL#,YZ4pj؀B &ܓ[tSWCzaÂuSllU$fU1Ƀ8K@")njdC >ab;/HB(J -٭3|6.k%i4PEqFWh -r橤a8^:! 1:!Oj׬rj3hF.ˆ1%l7O&u?n&,o -c0g"? / ڴHTLwz0=fl2H}8.s>x gJ{P: xJ(]fJ W^8b@)Hb@դI_H+jgM2 *|8D"Ҟg|EcM(~13p >.q;ZRM6' iyGě%ыFj -lP⩯*`!9ts>V@(?Ӿp(#h7n6( @"ponql028DzKOA^jyR>*^eF<踟"zCu!8O2c҂$˝pk4.X7 T4  y>B))(8Y(_&)t($d_aEzh|<'A&ȖK|gTi8aFHJŪZ\SGBMŲlKM_LYCԙE$Dz$'K* +gAAzCʓUve7?` epmHǃѩJuQ 6{HC]^J| 5zXM4]Cp<2fsXY|oX>e@bqny[H8m`!I/ LW -, ,=y. TLHb!`"q/)5d!" C2 A7B &)M |g ˢu -Bz)3e4y\^L 0=dDB(j j4L6@ˬ$YO_|<߄dMOCn:[k5څv!]; ҕ `]u- -y&[}cqiP؇+fbR#fŃRu>/Z<09,do[0gR >j^yn(CXesMlm@Z%0(#A 8/q&%#!cD -66jM7$o#6$&94᫆fn I50$&%0!M1~C` -ZpQ]Ks4K:,#T[bDhl\_q!qNWWN2 -*#thvP "qF&mj ' @dd;阒T*-琚j8D Ψ~\QEb g"z(J$vzM -!ʃ3}`q&AV:]!QPVGw:f(: p gnV%ᤩƙ"72ҪᒭH!6X0u#O@I3)DĐ RQ=u3IvӢ`ހX|Nmb8a4U`YlAa!z2,GC@ 0ҁG [,gOH%7~3LSFU1?BfQ  "7D6 .ņ7ak%>Uk [6)-[SDˣ`Yq>VيQUG=$Ǒb*(6AA?T0 l#Ke KA*v :G`TN̨\gp?NRq/F1eDd xϠ!~lIY:qYEpM3 :fSJUR(@_&uZ2>HBђQڒґ]1Q61$ -(6XR^2&,:A`Y4AbBGX;RW#!4}i؉} *45\VJ&9 2c:Ú*Ŧnd֒STSR×FJ I|LG/N3c&BvM-y"==ah;40d ؃e^4Ԡ:>4m+ j$:B^O@(<z)zJ7Q@>FI4> RC&mkJϣA+pMOVّnOI}6 -qDbQ>>cS? ) uꧡ }L@Ҍ -*&_, ʁ_0+$}Uqk5Ӱ1&~K? VO~$\,Lċ~>t顺8k~jk`n!HHU؂g|<"@ xSC%#\H"6@pQP"h! a}\4' O];Q ڊO1>i)eGǗ)8-pTIp~&lmVUT#%8\HeK$-@SRb1&!i{#Pt -])Im5<\|Rd#'0F>X-/HX)VR+^g&RkRc;ڪ d_.r$,,UIxp R_Jq4>rX`&R<,|![ %|lװ8ϤyDʶ>N zHOLڛbRܠvWU" d)W&i?'ފBj'z4NDŽq<-P1B%Ҷ&iT})ZPB,e=ML2R)`鏃1%ž,{$5!l>]%ddlj</JAN9QV eEc\0d"8tdq -Gz=AvC\.pppJq#lVkp H4(xT 9HV*7c4EX^g_3ppxgqZ cC }/ -=C, -/_f 83a`S~)X"|eXb+e<-MǜgK -, ?7)Nk`ZB -ӣGOg2IJ`ݫ KZD&[=4| >lN0ɑfKzIB4͓)g7r#3z9:6pl f60. -v`:64\1iE%fU(aeŠS:QM$4>QM)N+h X쮚EV-8N6X,ph2Ѥ JY V, r\)»!{N 0 T:LȨK!@fP'uZNsw ,EA*jHVG&C|&3L~I$Uć$D"Ȅ,V$@ˢUL06 B\:acn|܅oY:ͥaKp19c +SDb Xq19斘MIH"qZaP5|>g(< ֏{Poe D%AMv@@&{LT o$}XPD/Esɣn1qn1q p!ǨXȬuv>B(|Qd`z=/!Y|NOrifȈƈJ3&щ2 9E=cIEգR&AZInEIxP1Q4cLlȏ3J k1bYt@M5V LS'!7U$2ۉy$6XkKQ$m&HI4g7YRfK}hWa#wJ^4rk YP+#9ԖCsZUvG.Zwx/VA5nb@XGi0|`[Rxb8(lpgF[Z;7֣=7M>TXcR^7ҟZ6+=a퀽i׺+%l_+߸ rSao#쒭J3P$_T` q(DS&2{?QLdCNLnި'xOJ9?ki0qKM񔢹ys!U,LI4s;Ⱶ`줒il4Lx@jSe# Of xoFkCYɆ_ -BL$ -QEK` 2 #ӦrCn:|]%.VtIfpbZPW3R@(CmXJVhP\:gu$1lL8{av O?Rt<9;~v9MT:_"QKb(餑)ZT8Vk m-A(C -Ҩ&Ѭ64WXTHſl6@d\X8gGb]j|E)!QI L+`;{OPiX,%YRex G@jJI]x쁟 zŕahѥ"BC>]nVg*=6QsRZZC55zNe=Ijk%)m~'ϢA?6Վ*$J>O ]E^XYiTfD0ɿbmTj= !h*'PF8Q72e}] K5x`V:qqrܓa:4,!ذ@: ř Ao,vnFYc.vuQ"{ -}{$Cb9/9x:|P57mg>̛-&5b3p34Q22}bM 2`7ljSGOZlj[/Ngt(; ;׸]x זdS*C QbпJ~dψW9 BnI hPWrl |WV5e!K@&jxeŽ;"4ͫohwШi+d}痑lXYI/"U@ё6I7T) HM,yeRUFL.c-x,J0UVFRrW7g] YuFu_)di:+u_Srsmb󍸂.L, P^$Xnb4$7RBlI*D* }u7\mctq_VEĴ ԂùJۘE܉÷ +7|ďӼtHEܛz>Ė 8{0z$)ԛWvwqz:^(L䤑_)QSQZK!7{+zAd9^:99V^CD4^S4a~Ի̪:B:xbjBM7nNJRC6i oM$=r'tQnGwWt-cg#3Y8E2HPI_DFVڂW6#|g -[pt(TgrR]YRR/ibdrʯn.F?XO옓BodR#o\3Ÿ:qOM3 uN1k3P$Aq{׉E1+gR[!ifE| 6_bZ%QL$w H,)ERKV3%.1/u3& a0dK=A#G]q{Oas2[H;K6}~J#P|UWoOB;>{ջR4]LݮzY|>4cdl2CrYہyےzן]~쾲rv!Kv1?H 1^DF+цZ7Ohο{h tg1VzdjJ! hv7*߰epfQaR R-egDe&RxcoRVhamo4HL*H@ISrGW -nL>GII)бmҗ(_ -mUQ"(V?MſPh}w~\Yrqm>šuQÁH[:Gbܻ;dE?&.ni0gf ?m!E@~kؖ_ͮ)Z۲*'B9FcpXBj&wtsk2A{G[(Ϭ[|We.uوHôGɠH5]ߖ"S -"jXwFh2 y6,o 1L)tlVZcĦwYh|nT0gЍQ5Իv /hy7 7kygkǍ [G(D:p=e WqZl5 -SX ڻ+ky-+m]=X^!&2ZsfXq[K \^luI르caaU86Jw+u55DkP8vAȈ$V.ѐAE|HCb[h/$m%QSr?]kRsz24bPmr$, i8˹lTFIuȏvnS}'W!e۬!*mqΪ:$k)aEj/5ޥQ~Q5x 5f 1^ _f[U -:0dN&϶Qj +EW+.uՈ^F,%^螉i&B݄X%ãPO^)14z5V VͰ]/{.OJ>X8Hn@( ブ+dw!0=|LqBd@qGɂ2'-9?VW/.|tcޚ1tK!kE5QuGl5Qy&$9q90TSTޣp- $A) VC+UQQg p>@^Y܄dw9js~!Msmv`hoS]` H%42T*>1+dMnո8WvRQ [O4eppHJ=USs*x 7oMpt$OլDW&q.84:TeM3y1J9ts ]*]=JockR)]X(kRiHR6T=I{3Ve7;LWy"3_cKmZ[ɇH]k -,a[~d$x΅/ĖAIHc~> -%-Bn! e/?(1וOK;JņɻRg*B-Z./}K{0hvũIsCb9J@?L(nxi"e`S.Q˘A^qPY=nT(Fi.1ԏ:bCwqK&(.' /j(cb}Ft(!)Vb -xD{RL\Q mՍwH?էsC/%Q q"|F$=v?N{|"pl?T> -<` -k ¸G-_:_r?XLzLU?"-dR 2VGi4%b& ->\c5d`ʻ a*X%! "͠vQ/(]A)σь!8ͤ5j6+0 -]Z wԎK]gjs5q#Y1_vC32ve=fn~dl}KgBPu:__0Pdkq0SWZ |[5'9-`W4&UA%݆lz|݂Ʒ<ص@*&\""8]}kf^ y/7q+]nZuRRH}JS%\ 7b{X0BӇ廗ÈZ5+RI Z7 ,Ƹ%=x`8F+[lF1-fY;&Vqq@EQTbAU LTZV j!`*J ʫx .ai>< -.-$"[s-h7,=zx*"LK4ŏa"NQƍ/`{DsVĠ8ЗFzx6GXd\FaJReHe} sh{|=)-Vl1VgGuQ2$ {f%@SXH -8?; {Ի$zA:U:D"YtʝPW  ׾>PdQ<˩BuC{2,cF#mO/sJJkej<(a;Qwc*óX$ o&kR21+7I;Ue FEs9xp+LUJ41-ޢ0s/7yONTlA;H`wbU';SIĮhd8yeozk~ݾIf;$pfEլ+'˰FVH (/^Tq!p< kXƅVfFn! Ӓiĵn;HzAfQe2ft+,#57AsLet[9WoQ9L+!?yxy"smYyl/&5j#YmWݼ ;qC^>QVo.yI,ű9UL]?K^4ZBe2WD =X n b<"`.ѝ 72J\Fj^[~]Be@\!.Huϰ $HïMz; ໂ,oӛV|d8_l%PJ0tQKyr dfͳe^KX=F x~6(!sք:dbe<{1`ٳ ֈ҂yWןa0悏.iQk -R*|RJ2,@*ʼngO~?eP~dF`s/u8Rt9mۀB'u&F2vcuAu".Ӱ??Fl$uֈIbя r"\Gҋppbw`d}бz3uPy *(yJ6|]v'$xсxa:XNo#7D1U%&FQI1- -FIb*C6fO{N"x3SR~/M:Ҳ57eld&FC?Fp >wH`&,wdD'sy CCJy&'VՅa œsrFi< >U|prw ЍZXm=Ѐ&Bh9ky$,vEġYpqRٱ%YE r=(s~ 5p@Ieڏ}㱖 IWjN4t\Ki*pQf3y#ٮr~= wm}3>KĻhoċGƼeؗUߏKߪ om p0Q[;X">u<˹>Pf\UEaߏ00L\5?,WN$@S:c -ʹ`@<.7RP+anW~R@RWxѡ]R7-,۝%!(4!ک uaCN@) GQ9:MLRV ^Էat7~Јf:,/B1dWY#ĉm -I`&HB3IޥٻTM:68Uwt"¦! sB ]1’rnh {[ o<֧_k.0}0F5Sي={>_L^G R74eԯR.qm0N${.C-4/W~sJ8L ,lxY:X -4gςD^ -vhpetW8"dlL")JOݹh3bG-^8n4Cm j@q#< 9Y6.(y! ^ۄsZcӠև72? vC=MOP·#lϲPCgLr&C>?ߔ% I+/,1M.1ÅsHDɐ֍1~D [="U[rKMmPLy!>.Y -Mϒ@PjUwGm}?Vgvc2 wx9Ʌ~qs R!`5I@P(^c<9 1- KF*Y66(75J!e8BBv_tFI4y)Rm0m!4~1peu*:Tp 0] -زOu Y*Wiiս!XS adV54\+EMgZ֪IpzLlZp*擄r .g^V\V5yuI.8Gja;l[Q} -\2O\0&#ԏp̃Dr [a\ |Wl'vԮ[Ք\C X6{8UOI#08={sG/?*hc s[o-fF&{gO^bS{cuZBOVźS$GrCOug `xzt5, al{2M-Ҕ?ҪH =ϙQ -ЄmC=@A+f8A( 5jLr[uN}ϷD:C6쮅wAIJq+Gw|f#X5 -I71.5!G=D{-&Cbe)S±85ȘbɸƥaaqlD~2 Oӆ*$"YM̅I :%9I4Ӗa5 ANҥ?9d f9κD<ZMǹmIѽNgpJskV_9j7ܧ>6B1"ӟǶ@J< -E% -ZYijxSںKZ֤gVEIND<'νuйhtOuIPbBb# -f!X\ pW ¼L_ҁ l 'CgO݂qopV2>@b,B]SoM?$dBc6c4+ kꢡ'^ʍdQԹ&/|YtC&hLR7{b71 h:L` OTYȡI@p8M1 endstream endobj 22 0 obj <>stream -x $&/㫷z-l?`= |iHB].g BlM1,_ _%_@A*R "N ,A:Y 3bS ,iyBΤk]&w@T/QTaV< ypfPWc֔@hPduiD^~i)`jBEX4@&~_  \5՘6M+|֊lڢ6EU[:t:F ,K[`>\8?qj8kSòWBͳJ f#ILd{dZQ[7E,ŸY3"?J55K@6Gmëo,MH-ZR} ߝ [m(hh5P(m_3\T|䤄7G-M(?窹&l"FWfamRZaah*Vv%GL<_llWRz?ĸV9$%&qk$N999Wxe)Q+6ѢÕFCX Jw@BWz3.q0AS -KJx:d )9%jrydIzA~LDL mR+sKtR{ڕdµ#81\hbg&إ3* ׃c3IaDWA[jQO!"q#1M-Ws;bB"}]00xY_vRqEqsR C‡n׊I#`.Ϥ%q#; u4TUH=9\*#wYm$+xLϔ5rJ)[NlL(tU=pFA&XlUĔ MQ !J߭hGE% pViiZ{g-vdMUC8էE%%EMDIpjrWJ2_  鈞j{{F W(ͲdM5469rJpRy@TR)1/ڢj AK+lHxV R[|h?Tk M"ť eC -*596;TdZ"aiOа<4-^%HPo[v}ee:Q|-p-p].Np365 DD-z0`?c%tAk5%ϑַJw 秠4dܰ}qh9\O+yg0MIME`BD!v ݅!Ӵ*ƌ -ESN]TP'loZ6+lW9M yPE4x(B0rrO'W؅(jrt[{uƣzB2ut Seie ǩP( jP9jԺO6 eBIb.)0wOhvܳrϷ,L N;Y}0-[ibC}d9hFrā02! -2 w=p;k>eIpvQQZ?+##ݙs`qRpCb&Y>QAKp##:Et&?R9 -V|yqA8x )b6waECH轠krVLD?6Y%DZ-,6nxɜQ5-#AG ~O - p[ 0lx؈e| CALV>*2p'[ϋlp2"Z肌 -aI2VSboPp8&"|x=>ژæ)7u#zy90 s IJ:ΊKkC|1H 3Tl؁_WBJj>l1Tb]@[32j'>XYMl.Clܽ.I_}~!En -5 [@I -j VI oJg{h7{3RJBQIXz \h<]Ln|:X Uvtd[)Xؑ?~+Z=E{Rz{~O=9C9AL!ToEtY g_I8:xBZ4A By#0 4|2}g[vo7 흹nR`xjfN;(ЛT! B^Ye`]=7Oq{lR2?b[} zCvNoeJ*z{+'Y_]rŜ,@tY's^PnIt(omI~&z2pZNPgQ_Y"!18˚pŁo"Q{5mg+pBQ@ߠM&Hвh&%32zBOl'Fr\-K˭f4a8G'ydaH+&_KVՓY%a_A)i R?(, i H3Qgwl <γJ0 -jրG?"9;0%ax>ܶ+8S\MOQz |]Zt,Yп=$}@W!u^+X#É6Ua:uSD -Qh;3ԎTh8>!ތp qǒ08mΚ#Jq0x{uWDv tcP'{u vM䏔Y%ѦG,p >=$*%}`:G`!|W&>eqM-Y[Bd;۩_.uY -D`$eugHST/25-s$OClA(r̬[kO}dG#?yR[@F#l1?g?60s΃x2K>Z) Gsw9hQi$7>9xaA)&ٽ8yDl ;!-9BP ncit$GO IEj]φna;hiud!ǒnF:)z Ev]3Ua&Ip*ad/Z (v Ȣ.>8=o Ȗ$)A/L[dy9WS#y*xӤд0 +oXB? %ThL%З,|ԩ='Az4ۗQlTPn !YSĎ1{gH!E4(Vc܌|2BŜ7рvMѠ,JdT1 vi>^My7e +AWUS5*`JJ>V*#nh)h---w%/dWuR[IݸUIUs ""l:1@ywXrWAC4<@p1of|֧BX$p|vɜ L+GDxmfjn -Ni/$: Lt8_Ō -~o&#Hb\HK2;Cynqɻn+#VL [=a2~W&xK.OI"Pq)zeڊLJEn(!oǰg1j!@$1v/` Y5"РhI @v]Y+[6ҧ7&ndf hYS$ &a8Sjqo0+2`q3#+c{WY@ҙ7vqHa)_kXWnhO~ƈ(P|g'74JDgA+UQֺ30<( ͶeF> t֑ uG52X -4oJbvխ@pi$Ӂ)}0$4&Ed dY$(qKIUDtEɃ]&&Y3Lɵzv#)} Daی1n ºrMFU dꝚA,*j<ؼp^_yF -b_GbdeݺV2  V|Q  L$Sj(T= ɉ2:j9g>p+|X3x<Ո +h=q[loάus1UJ+U-npE)'ĤM@bLЁ]B;'w ҇oIXc#PɂJ-S@k wL5[p9&"Ynô ̓Mf-(;DGyj 63"M.qzz!aU3cfi18#x5*@(dZ~?V;Wq'_[tpmw( Y=^i҅=Vޗ>3˝C!Fc||$ڦ4*UkX,B5ޝ:D'm1lmAF58F۝+I~Z$J{"( L=\{8;zy#b^J5@ob1"SrVh.lV -"la.$4Jk !dBh?kz.BKw0E-P:X3D=%kţ,3 -@*K#j~Շ71&]@75c1ԪӸ[lOp%=FwJ-c1wVi -j A ,P{cZC\A9 vw.~2g-&x,H,_6.賮zjvHפ&>% -, Z?/h)vn|H!Cr6\{=Y"8FKkJ$R#'y5/wU#U"T_fSh=GJ)L)٩0reR#VHz޺2B |o8{|[!aLM X -䦢a! k+5Ӑzy ,Ќ,!UFt ha&^0g}BNp<:^0Nj+ -IW0:5il,j$DgDi>K -:$lqK(S)P.+[9+]5W8d@O@C#X b -`Qx!(ְ -4 `N:\re}xKOI;e+uH?r71Piڳ}z\*huIs*ש.nq_2lv[Yv2Nϑk.Pkϟܴ_e;ݱ'_Il%f>ǝ+UQ6}Qwiޟ1.)ie*"\ vB- -g -)62ڜՙmƩFӰT Sbƾ0! OhUy <$ o&X4MTLy\1eR\tk]:)Uڑ[ko;{>Cek˼㷔K+;qXnM;:gdYs%nKrJ]J{l꒮kRz()3sTr\9f~f}IrKgsY.#]e4Υ,7]rq_+ko&=r7)o=#SobSX2V3vsU)#s  - /!`=@b0ˆ1D@X HmV{k;`d*)B` ,(V$1 1a<В~RD@B&M:|d37zj0R|+4p :y?25^w-r$HKjOv]w E$d, Y6QϾB<J»J/NuK*AqٶL"dZ1C}&@2 đ-=BDn/&e4KB.NoG!)jSrUbWش88&hFI]tN-l$z@QƠR9Ge)P$^@ioGp90tpWvu"6&3I!!:^?qKu# c.%0B[qia)!{B[B{hW!<| Ǥ4ǻSq/ [qۄu - ,ߎJE4$wܾ;!|O$r3+7;ggǃhq.3 Y{;Tcw&ev\;(S2kNjP=kL{FjqN9Բ=F7Lq8@t6w\G0tw<Lqn ;^5}̀V߸3㕛 8؎[1ГLwp`)Ưx=癑6zxH=~fˎ; --H;kVzǃa>70ZcЯ 82=޵1Da:w\K%tc QBǻR2+BaS bZбX{ I-lAO˘\i9:ZϨQe$v|1p*K,Ղn$U,%P4Ѵ*t$UFQ#nAjpCjjgvذ%4+fdXƮ W>( ] uR+n+ ~fWyoF:t<#vǖ\Mď_;0cL<ȪgV6b endstream endobj 25 0 obj [24 0 R] endobj 35 0 obj <> endobj xref -0 36 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000045316 00000 n -0000000000 00000 f -0000045367 00000 n -0000000000 00000 f -0000050327 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000050400 00000 n -0000050640 00000 n -0000051784 00000 n -0000117372 00000 n -0000182960 00000 n -0000248548 00000 n -0000314136 00000 n -0000000000 00000 f -0000047344 00000 n -0000325890 00000 n -0000045758 00000 n -0000047644 00000 n -0000047531 00000 n -0000046388 00000 n -0000046783 00000 n -0000046831 00000 n -0000047415 00000 n -0000047446 00000 n -0000047679 00000 n -0000325915 00000 n -trailer <<274365111D5C475A8A6631A8159E6938>]>> startxref 326114 %%EOF \ No newline at end of file diff --git a/misc/branding/no_bg_light.png b/misc/branding/no_bg_light.png deleted file mode 100644 index d0fd9e7a..00000000 Binary files a/misc/branding/no_bg_light.png and /dev/null differ diff --git a/misc/branding/rounded_square.ai b/misc/branding/rounded_square.ai deleted file mode 100644 index 647a371c..00000000 --- a/misc/branding/rounded_square.ai +++ /dev/null @@ -1,1827 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_rounded_square - - - 2021-03-19T18:11:20-07:00 - 2021-03-19T18:11:20-07:00 - 2021-03-19T18:11:20-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8ANP8AnIn/AJyJ1TRdUn8n +T5xb3luOOrastGeN2FfQgrUKyg/G/UHYUIxYSk+WtQ1LUdRunu9Qupry6k/vLi4kaWRvm7kscWt DYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUTp+pa jp10l3p91NZ3Uf8Ad3FvI0Ui/J0IYYq+pf8AnHb/AJyJ1TWtUg8n+cJxcXlwOOk6s1FeR1FfQnpQ MzAfA/UnY1JxbIyfLWpahdajqN1qF2/qXV5NJcXEn80krF3P0scWtDYq7FXYq7FXYq7FXYq7FXYq 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 J1B3NCMWyMX/2Q== - - - - uuid:34e698a6-82df-0649-b7ad-24c5ff94305e - xmp.did:4ba76e65-c4b7-4432-9b1b-5644ca605c6b - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:4ba76e65-c4b7-4432-9b1b-5644ca605c6b - 2021-03-18T19:50:14-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HUn0 +ać$4)(æ@:mm-3!5dn?ݧ>ܧuIw?.9[ʔom[8^okqqV :e e$JR -T#*j~z|PfRq兊: -vaL8smG& j>Q>Y9v סwDKqcƔ,#đ4|8&qGU8ԍ\}d+e }`huvdo>~GđJ +p 6N?l`ڦ>nSL|# ?-t}? endstream endobj 30 0 obj <>stream -8;X.,b72?3&4AN=%F@N^JC>9d:MtF3aaX!o=L+cR&l%*qK;sJueK5bIFZNeM*Q(T"CRuc\X)fk71O@hOHYTRX3iJ -"h%TK;B4"CX;Q%)nEeEuKKf?Y5On@D`4l endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_rounded_square.ai) %%CreationDate: 3/19/21 6:11 PM %%Canvassize: 16383 %%BoundingBox: 10 -292 291 -11 %%HiResBoundingBox: 10.8229665071831 -291.043062200957 290.248803827744 -11.6172248803832 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -82 9 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/X --m* mm[QΜ&" -NRj0A  -̤qIu%QQ$Ẽ|?VA찢"J&(##6|$aQH$ƁqX̰QHűFɑ#^EFBA!FIRRd@JVO<˫HX)[^Bq%y%PD 5D6&F-xwRG&F,x) $U.1 -&(h`ja H$\PK$|=|1؄m*lKD0x٣gN /{LD=YQ&U9h)yyt KYҲ·L2/mgm޶dN+CF 봶PH/.ʛ~%]vmR̪ٞzjo+LYWC,Ur51 S~2 -óJ^I -(no$#ą$Z.azar-HuaÇ'L媺ĩ(.\vŁI8#F!sH$Ld"I7PDM([k{[tw{$>ōGwOOlbMYc{k[^D=B ^WC0 -[[SC;3%*)*굥ueJarBTВQPP -P!đ rqqǏ{졇yvQG> -t$@0 (¸if #Q$RQEQB - -+p" Ø!S$`0hȀ ""`aø8pC 4` 4h@hp``AC@080Hh@LAa20 !"@ Lhx!0@@ AQD@`Hxxx L0  "& "D@0X..ABC 0ЀD`$0  hD`$LF @  !! 8Tpa ,, - ,px`D4\A 4 - -eBCC<8$ - - e :/:Sݦ=kJ1a쨩GtKoZDE"9Bww.n[I:$[~(3;M{^}֥Ÿ;»Z$xtֿ=-e6ggzW**E4j},+]§ݦxKFu6A*ĵ:hK;>2JW^tBy`W*s.!ĺ.L54|iA+s.Mǻ[E?Dk[wCUvCMg24h?#eݏԺ*u*l箌4 v[;jseӖ UD<*;WhNϲDKGLdG6INYcyhXgyImBcgO<6\y$sor>vfųks\UB:xh6D:4?=jPc&.Wo3/sjţF׵_Zѵ4-ͽ,\P( 92Ψ*] PP6XXHxx0`P&0 `px Q `A8,((@fAd`&! T, `̄܂B`A4@ahAX礳j&τ[z;=kW  0DL`Cw{r-toyYJ)\$ғÊa7MYaF,],Fm%,.$Fa*]$@CD HLTԔW9KˢK;"%=]<*)Vl%$uxlIږB:Vt3ci`=c)TVҵmZ}ooxʋb.Hʓ: ajqb I,Ł$8t9$aTQ-"z@:YЪ$E5 -$h믩j%%V9_X󋵼0bĸFR|qa((J]H1=>Z$%IET/&ʖC5c_4ܥ|wwh^.n3&"ra#/b +zR R8$r VT_ EQ(.4J Y()EU&%a8EkU<ǖ+ 4$퇤{W[h,k|m^m2fe{w;{S\+=Vof otLm|䳤V}be-<ڒ߮Vdc՝5nQfFTMz~xnwWݭ;[IL>Uӗh+NEs&.kJEx4m5+E"Իl),&,s\zytJ7n=[ y6Gޞ? u[sήm'"\WޒЊxT]mx\B2:V4ħH?LϦnOv_z;~WqmObe,M<HmNg;oUc醧yCh"ʣ7ϖw^V2kNzo3e=pW}ncy޺igiq?OOz0mdzDXMg%c\"z,J·vZs9Ow ]]Mz*mu[OM">d{6oތ>YNVQ]L?vl+jәߪj>l]mi)I͜ksG'K˚iS"+~<[NO.;hi5]wzZc{}t5Q'Vrwj{ʘ.]gE$*u=>zs$R5=-*"]^ĽKL?xth)(fnhm>)VZKhc%˧hi=m>.D^Iyhuae[F?jM}|%] -kS*>;HF{xZSH#Y[G?w:;h(voc4YHG5ݖޏ4Jz !xngNsYxo[F{^v>xu-QY5{:?;k4R3f2uЙ3㮏"5<5{CV2seTtx^rŤ=t[gllth$%;iX;Ju|h],sͥSnjj5ZLٖyΚ)ғfn N<זٷ虵ږPdҏ֑ˣ=^<1֭~\iovg+]nc4Vm+RtHx.̦kΧ?[dfxH>7❴2ba[|$eeWfC^vE赻ҘGtY;Mx<\Gyjy}|z'l.( vTԫϫZv쪼ϾSʯю>uuWdvwkAPu{0>\_g]խX)JO:p -(noAt>>y)]:;vUV>RֹSZ$RW{nw0q *S>Om{.~ãv|'ѴwhC?ڵؕhWd:T3$1eܼr^o-iOZ%4YjWa&֓e*==OJWeڬcҴ/(\#F"U_{tLM:ǴSyJyYM2wzmz;x5SQ:Mݽ4C:_!4_^P(kuEK:4YxiyO]z+h=y0 (}}z3x,}zU< m&[XCr9}hoZwTEcU:V{6*i1nUEtF{u7L}deXwʾSzJDөk]N5u޽X7C2wZi7񧛇Թud_gi;="׺^P(|<#^UIC:Mv>z UmxSݻcT: ->{-nTeC3//=ޓg*pcT]}TUxvUvmVZҌ1ʟ}QځYn -Md|Ui-]J+U;ݽե4,,;eٞFX -x-XUF찶 %g;+2˨+ĺ٫«G|;ܕڢnV^ѕhUjtG+vYiKg68DACC XP~q^d{='7-ly{Ky9יjZh~]{s4ܫ]ڸvbs5Ϩk\œK;JvE$\'坐WdϼwGDY#=zxʌ(Xyo/KvohЈ~r&etJ_tny;vppy\Uyvi=gD٧HWSeD koA[5hK߳#:0mϖS~nс:}ZfKD?UFUN4֫g-UN^ɷLq/ME--+lx4 Q^iu75,4O]KՌh0z>HwF#ߩ|Ǭa..~yj\ɽ>_wBu3M-1fkO/a.zlheiAMTjF2 #0 }n@lH2Cx$CaCE.܍, !*Њ*qm<*nF2ߣ9,nF ![1` IWъCu|rBɊ'ږD9x=meqEm{S@ )/CiVvT!In D z iXޗmt̍#hdaS͖ϔ/)k2CG@ا/Ŀs&€)bjavZupxplٮĆ4ӿ'y$|"9߁|Z]PlJ}&p> EgyC-m~`iZ+aH8H36" M,- 䜇a _F Yi "_DƝxƁo5;?DV]P{T%g$K3:Q8h(v +`( ]#/E ȅ~'Jc-W}%27#=7i?^*}^EqrPHr7`8@in'V7ӟiO>jXY#笓 >ZEv)ۻmRXYWd _%74rL74tŕ*MHL`A*܈b"RErxte=G4Ii\ͮ4VT&{(AJa*VFH -R 3 %`:BNZC<`,!/v88nq0{}  |# O1 B.׺)? s"([ -\G j=X$W然mn})+Mv dtB>i.N<8C}u0C$)f=k=iI>?4ԮEjJ 虿B릹P VPi`v`C=?'BVFL3Vg.f6yz%,%pgf*\qk8UV 3& ̙9vla\!)(4`W.f*Dq -u'f`R6݂Nl#lԣ;k~(+l{,\$,5YCbҞ/eoNdΉ^Whg[{ko9ypE1=H9rQSU{VeѝD>^rr O/Z sa mac{O_#Z }g ϭ!BgB.{'@OTǃ>>>Or]C14AMxu6i0̚g]XgAJ9 kjΧ*Bp$ -;nb}~O/ǡrܤ00kiO7bsMcc -ڌ+-G_HZnDZnIn(\r . ={},1v%RYg[AShKIE?E;Y+ap'szJGH)fhM\K!h -D2!:G/c  -ӽ,JiXldb7%.,h -|7A He6B~ZC2 m2e`ȅ4G `l7cɖ906˒U8Z0־`%%OZ"J *;BL /q&ٔ=0sҡ%GLjRmNuZ\|U}kVAbol l琥᠕.̄SPVhx$6Z 3 AS{:T)k؂ar -baJ864Ĕ!=Zn{oʬLxȥj&en$LTiBQT~U=aw݉VτlDiP}?Hm 4 ԓъ2ɨ2≐d? \OhwpK*f&oqKx TB)wboTP>rв+jOδ v2|a3ŀQB[$؎VpaG D@maeOh-B8j~YMkۚG *([9eak BstW/ش-\h" %Hg+ESH1mL_ -;O,?+iVX!k]ԜƄ=Ɩ t>AhuV@%\E;f]ܬXs=%(:Zpp};;jnuyM}l``0'{kTȶxD=rl!k3( 3 eAT S0*ēKآ_ߒӟ$% {j` ZaAF"%^]^9OF^\hֈPrå-7!!eqr8p#RŁJ]h BR6v "zot_{΀O݇Fg1Bv"s>*t;mN (;JY G䭬0͆"osy0v-5!}C~M23FˠRꌦ4 tRI-ܽy1U`D"vd^(`٩sbT-|ߵbFӊ.'L!/g^fQCOr6頺_4jr b6U_ Q[("b08JK-T8+S֦ 7Ź-nJfr/y 0 #IBL^WhyMgrf bk,|cgD7TQgj< Po/>2;JzvI3(S*txxz{+]9ijlح9\ϴ [<apK43Bνùu";WAfuo:`彄:W{?7lqy.|{ښgH3!Xvl"I:nō1&n@ -F&_ }7Pɭd,Obq1^01I}+Ѝ0|phOUU6`D,;FܗۀzGV2'TnN_FLs!35ҔםnkZ/XMN2v:/[,^(?D5iV]uH)<};t(/\,1mݱԒBCb"(XRw_k?XWKp`mfnƧ=l˜"ǜ)7K(@i”6SͳuouTަ4č("@dMtw^UْkַJ$:sG Y9#r*# i(*wz1OvY.ۺ[~VWHȭFPn\7=; |7^q\7JZx}~ $-ƺsH1⚷tʽXCL[@*"' -n3/(aٕЇ@#Lo-H뾻}Nǫd(QAV{}/R ;xGIJhy_q<,[n |3i#i^o0 rvEWwe.TZ~H.^0ڎ9\&JD.P.vf.qBs\1eeF0A[Y_[Ek zP]*;X 5y'sc2 )eb4. ^_T"m~⎈uo_;K.ly+_ivj (evGu.3]V*Z - ,90MYSN< DG$brx o4tnPb@bs -~S.*\j - b8 ;'][O[SdlWh/\ݞo&Sv(|jsM9i~עbe3n+g#L^o4l<Mq9oJD.Qk&dC܄X{hH 'u,6)&y`'֌VJRMY=͊|bA7EڙB3chO=-R|#P*!8YD4O6Hė3p'+1I 2-j]7{ʈB9Rq?i~lj4K{A0(OGN4 TA9l$=8!qa }M W-h2#tz\?H -=rx-BGyn!pfU>3'J -m㿃mw)ch xq^ X0:k’!Mא[2e? )giT?_qwSI?7c6pfOepMIL2:J̱,v<4>b >4D ,ʭgDW/>m+$'Ô.;vJ|v!JJ)=;6+Ymٞ4T4N[4hu8+OsJmVbCan.SĽ&M%(V&yesQMb'ߜzMC޴(Pg+ze; <K a& (^=C-wS.tq<k:saaJ:DIF*rwaoPpd'ߤ?s'Pa0S?ma<{gӼ+BeUz'=W!^sd笼zc`C&x{}kI8tsGTl*zU2+T -G%qFa9+~Д -n$QpCyePZ-yǓ%t(xuˡfʰlyԂZ S^j3ou`'h.ч_ĺmҕY`bvO _P5f}$=Y?h`?hyW9D~="y aG'xPr0s!QiZZC?V11r-Mn/gqf|ڄN!Q[l~%nHdWۆܲ FkXŷ<()WlAwnz=bg@0ӀQL 8S83.RP#K3;uOuV'$Qv|%Df -F{7,#=gr^i|@T -<zo q7]IJ8"RG"PH 7d(ϺFh r5vYY 40-GUT 5UXU ΄{w5; TV !=jsyC`(GIf" 1$ػdCpThF;.l&n1Y)=NJx/cx[!E\Zi{7b9~eE-GƨQ(1,qDpR%M8~w\%]Qw$ɭƒ-)^ jd487 ?JVNlŃ.ȭwO(Wa,LeΙk*CYIbq"jo_[7ql$Ziug2CBSPY)6)|:i_2[M>  Ǡ P 2"WHXRp˴Z8PqoyUp ה2g_ 6c(\|0Pi6zťrۣ.̸=S79 6ҋrKd8MИgy:4? moU>P:^xpZz3St8jՆD"#JnȀ0_] ]#8y|MMC(7}\6r |fJ J)ѧO7 \RZ3Z#_q3 p=f5T[2 #6qt j ,ؠ˵4F_Sң˿c~*uV@Yߧ'SJ^@wbR8]tmrEmZ3Ymy4Y]ocHIbei#ϒ S߇B ĢxaA|+rK2k-Rr2ڣZ' gBdvgf϶,TL*Sś(;$RO$3,Evl&#!d q<w~ ZLoEq+ ‰*+,%aqI|H,BӍ}P`yzzO^>} PS$0^tz{3e="Q[A;QX#'P ?ʴxn oq t+TW%ṍ1ͯhC`1dΑ$[ӈo\i|&U5Q6v󽁶ԛr<K4tp9M eZJKR#qsfhD!U*b8r9.g -L"-7dWyTfRjzuk+_Kh=sE(h维 o+u!DpG_c6Q 5I$̞x7;jOe۰ z˩~Dq $zVlk{0r]d~ -E`08.`d{ݠie߶Fmzϸ]ʒкdMg)M F-T\63{,uۻԏW{4貉] ,ٯn%)NDp}[`Nޔlm,udXY=ғ#ssXc{;\pF}䜅5S^xҭHr#ܔ+Ӗ]A~ը8SyU)d4@R^uoHE{czۛTO7:)j`|/]X;Jkq妊=# >cwX2dL~Wi}ȶ3w}D XQx*ԁ +l_d=#UL5?%6](BM#La# I#E>K O$vܧO{)jKH=cN d4:ӌ&8"ZIjy]f+:[((ꁲs9T\ΰrBC,D5˘b҂[hqJ}k+yݑJ",; Ɂ+ܾ^AxާP('ݢ\bԘ=Gn|aDKj:(5]x9-)NZ{M\T*M_k|eH_#9g1&S$bf.N$qB$Q-%.D -@BEh4XN" 'aHOϔNn@x+uCD32j冝lF%&e$/ABJ#JU[3K{cs9!,p]F xB|ox; -eh\iŭ,<6XV*8q;!W"|  P٧rfUF$%*l6x:,߁0@µEF/*A10+Cxg̀2qLhM:)D}KΙq*I -7AUX?2Y"ONm!(>M"B+T 8WZ -')L -yG(-Sі[=_)a$p{ȆξW,g8}^{6BYƉZ>a PV}Fv-\ي En*K'3Q1@*Y:)a(=_iƆ$ [Go5>> /<10yq$O&ɺ p0fBSoї$u׉@Tƙ#nAqXzZGk"3pQ|Fꛉe_1NIp7rb&9HA|)"r9Yfnogao_ˑ]9;w`#ހ - ,ы}?#f8σRq#V5gg22 axts|P{{) 58 W)V@xlL792ꉴ(_.V|S2w `,W ǧTc4cq yGX^[ - l}--UBv@bJM8#ݶZbGEdG_ee4S6@W˘>@.#)@1*hQE-.T'1bZG' fØwuwRcFwmMdpơm6{PA9mĄaSoGő3o֏;|zP;D Ecq9r<6{[T1C<|.Ia+d8"0܃pVPRlhvE#qU mGus !{&0L6Qӧ@Z`HWTlkvTD 3UmnZ l &iMR !n#\ҧp"yۥC -̙rOt< M(6mTQ)V wA'bҲYU;D=n⿡/a 9oE>(p0'NZ9&#_-vq}'$u@)$ڲj_NfJdgOĐ+D)%:CWKM)Zü62\ [9 uΥ{JnJT7ma)b7ܿ10U);yhMɖT -iRyJQXr?oEҎ-Sx֢\2ƃ8cr\1U==R\0RGW(?kZIF%_MgvaV u0=;|Եg)yF?1bAJh#ĺk=:r a.bp4"vd G('pc{Yi*+`EᄆIR^g"֢ &+Py_j 2D-gߙ)/v&uިv\/Ǻ"Pf]i-"nzNM`f@JKxk:_ha ҃EcXy>`[8   XIg"ccuOkP?Ԅh ~>FOGr -򇱴*_XF CbB)-xdGMF=ۯm[sՃ)~ϣހ~xhj@@>;!d2 uY !hBb~fW zOBvYw>bĺfD2>PuW/brJx6TU{{YK'զ(qctMӳd9's -+xݳ7~@!$ҁ+[r6HJ99;A[Rsr6;,d#ƴ[}NѮ&`pP-XZDDZ&ϛl#74%0HE߯wb u0̫|RМMekJ5AfU24+K_BeUofQ_ 130N [ʯ-b4c28ͬ!c/+ǴeBEh?~029%9Xj(-QH e{x"(m ζy%]qUb0]ŊéY -S fE)d<9)|CbD:=+|+AQCa(D0~Uma]a$u3HQԑA0+v}/n3}d;vxhT$lyަ_ԅKQЋJŐAC`*7p1 & FCV4-q `4NF=pTMòl\B6-h@\$=@PdBd+-0σj T">ׯw갢 ' -+ -c{+|jvy^#3t(z,qb܅GE,HCDW(ڦ;)0 -Xtq12.Ɲ-i9n]o *ٯʯ\.Cdn@ gRR%l/M6s2oИRG*Q$Q$H&B`BS SI9RMRM[ 6EL"c>( X袲aDQ 0Pdℸ k iܸhxbUŻ`rX\ -bA-~`-nAUyl U*^х<fd)g].V)BLrs-_IA1&P\7들R:G7TlһXi7.ZJ|*RPBXڗ)$~ց6˖]_ ^OGTqj6$\=A+S4nz;@@d$knN[vjСӨ)Thټxsy9J^l/6]WHjڝ$A\Tx.eMEsꢖ.*Kƹq9nSI@N)0 JgnP"v52O?oO&!:G/ͪXr -"6`Fr=w<5Z(b<4Qo7YvM>fg3 Y>:Wx$@=mbT/4ϭ~(Thw$:nnQO Lu&zQ 3Zu%6ȃ`aj':Q B딦Oy8;Wp4|`Oox}5WE߭?*CQ,qneѰd嘽rwLJ&uq.KLi/}(=?OO㧭 mDfpv7Ң)H˖8E9/%)Vh RBoPI#+ eX!6:Q3; O=` NbйkrWj>/hmCu.qsë&ϐb"0vIcpJz  -k#=] v],PQ!S?*jLxYNn.L bû] R fcytEdH5S4en}L #Z`jUQCTFz^k EIob[qJA#0y;Qm(q`ӰhO()|ZȧLĖBthDԡwh84´ +d.RgyA7!.O{L/)yB6(Ԍ!*#0A!wIP@ll8.lA iZ8M"yD6d0D1Z}j| _‹BG@5Nt -Wl$ȈE! a`"m>P6Fi1W5"FP7.f-skѝ1STri/.=>%ЂWpypMM FlEKC4dԼI=.P_=\`O El\ku;9VyUǞoFa~R7p8;h S0'[P>8xA yds->sj;l`Q ]'icMI/PVCLΘj, m#B\Op` -Lyי'aD(ZP*>"EhH@zIk4)zנa aU1 g:%:3YY%X c7P+"FM -yZ"

:.m 1wl牀! ?Oy@h]d^NB?E5]2 -&\s-=|p#:'9Bm#*ɡ!#m_iwЀE_Egɢ$.X X0t=nܗ3-%sVA@]Ш#Ջ*P -W LΡE?Feg4ZZ>*bD8ﲦ'{:`Ȱ6q/O>/X?s `gh!yoEwdW-T$dFE{AHdZR 2\yhh$E:;6ל -MR|]ΟV ?Ey맼D/vݘE Cw9`e#N=UKOG 6 -mҨOw48rRQ̟[x}wQN:AW]TPJé-(ڎA܄cjm_ -;TCsDn/#Lx;/赥#B D{(mCb}v?0~0j7g+ {Aޭ|c!{!٭ fI}OL'tXp>eUEÓd͐dv)֍9R,6Jθ&;wc>0:,YWJRqTSȡy@*z(+9Ak*e_s)7p6d3Z5r@D 2@nP3H>zyZltii HuɼbedfPdg"x6QHpdn[ -ՆЬ, -?2͗e%e2$>2t PnS=nnwleIA+#,7NC43p{-_|Ǽl׷8r[xzm$R5fqFi9}]s$F׺iETc"l?8yI+wl5 4·x,*yWqm´z~Ν, x-c4yD,rq|=?Q Ɍ‡arL_|SJksq0Gf -%2A[֕( w/U~V _ Qo;(WTo⯸9~ށ'\!wAnnCnuUJR B' xiىUU _Iy4R-91]vNhe oUQDT`{\ܥ2>+ќu>$>Lq?vN#E;gZr^ukxCf/G#DԄpž9_%LiOx,-\ӪJ=P׵J!V܊9b$5pbxZRVTHmV*q 3+28$C7uGvъW(6c.nE8$NgؐAMf:%qT`+([ḣ2oeDE Ƙ*bNYXi#+x噊U?PEeO$N W3^Uկ}yUM $K: -~#UQ=ZHD|DD3cFL/S1~F<(I8MUQ{e9lǹjTflV3ϫRaeZn|JU5lr9DZCKq9Bbf\LN]2 -!$DCcl)U|X/ -/yKXpUJLL / m ǭ'\ -.ThsPזW}5ށk3.C*H"T *"n8UӍ3NJgO=!1^^`!U1n0+V02I$3rᕄ)H.gEbEoOF"E*WH&CʚNAʅxo*a:_I%rdEryktڊ"VB>S -)H Wr*9FH' 'Z"c#8Flč;(wE^js4/eU#& Tj$aM#hDE$òW(j^e,k9 >y/ObuF;c*7!{G|8da4+8 ;S1P:naBڌ5jp' iQ!H!0ً#7N* -V1|k&$BeLCrHbJjF9LE&!I|F6KG8!zFGM+kUp'h9n BEբxiRոx#FfZwI=JO)xLMdb rHC=7Qb'WW{.K5tN0Lr+^_nӰ|€Fy1`i]a<^n#Tmkab4\M-EAlI#ѦBe%)䨗=% SH53sӐ![X1 +6A@زq kvrD(MqgM|+N {bR<&avI[: .K21򠂤CR#mLTVlNv3-伂Ľi+V-wGA}x׷ܶx/!› éM -n0k0eZ-79P%L(B*Hf#vZ|ai1ѮU -iI -=dW)%H4wwiTB]Mpت1D9XŊP)c@55_QUiq>Csp>IZCj 2cƃ.hso"jsw{|СQ筂$H-Ӑ"U#KMp+X -đHѫP,+y$B*8xHQ':A$HK㸩eAGay)?D E1ml j)~[O?j0؋5}"'ȐTCWrř!B?Q2D;BY'Ԣ/ 7=4,WRڏCc 3k*[+΁Hk8n൞LYFB*ӨgD;>ZZ%N%uQH7+4QIXLߠoVO(t#Uc7в$Y}j~Nr(M()>}PU>Ve!z\y:%aΌ-4Z4nW(zI8[8ET{ʨ)GME -r_\d}5FSUdO~aЋV +7#w"F)ѲGGyh1%F|p`Ki,|<ɊoId/5N#$UdwťH{ѫŅ\K#; `/DUMDĽfJpX2ؽT9{X1_1̩(0_MC#qWL<9,Ţ1fjieYy yK"5I"c$زi{Zj\/Izy;e<(S Uz927N|GrHcFV K r`MD =*BqC+P'#U:RHdQ24(&rP蜹(h(RM?b4؋fryJvKycKpeRg:ѩSчŪ $"Pܫ`y&PԁP0,U.C h7jglE$Ɋihu|h#ieōaj堸kyQi%ah2cs7rM+4y畔gXu3x%E)fr\כ7$yW=j%T$ef 541H J0(LErW‡Si?}V$tX ="Q3JAJ(JSCҊ0:Y>9H5KG?KDDd6#eP:B=CSw8R*㿈%O?%_E=Q(: -Rn*E٧);Yx'F8d1:x'ʓZMAaHlDiMy0""3Ss -pw -;5Baڈzb8ɑ|"$8!&Ґɴy1RFr:"J\ +!L18jeoC6GQ(\ =AђH CBJDpŕTO1RPf]4A.u Ӽ69&j8$!MϛfC&K%qzChDl2ՄbxTP:WZA$:r\f4?^$DuUe~&*g=6V3PԸ*QTCQJIjT -NEc5#"! < +^zH^=h:<\TeeQz*Pv){JUG%Bۢ(UeMQN*h\cO׹l\^.uo֪:%8C#3c4N{|FLUZ*" LQ#"A -qW#OVS4KVI.b ETσ.QRCJFuZ,lCHj/ -yКF<UCj5iZ1FȢ\';fPA)ѝgKT2ݨ -$N% Ȅid8;̇ze/Hܑh&2r"9#k,xZR=6"vj, %2MqK>L(dGHג:M"8Q OsMSw0#D1 Sp:#]·'rPAvsrɧtP(=,GqʜVdJ5!&h@:0yt@1 &{D*Ċa>(q&yPC#.N+Zma`DTq s U(OɇrqD~. -L}F경!E0CVQ * -A`lrȴ`JDH]m`f -buz`Ԩ:%)Wm:MU"eHx|(ZHYE)ęNШ"=`) %'65fz0'N,ʭItD={`) ׇX |zdkGl*973vޔ23gb8Js<#Y5Bb -4qJ84-ay0.fD(ʃe+-j|sx) -"z=)M=zȅbe\".D xgoAkUr6࿐a)SLI sG2MdHQߪ'I j9$VQ\2O2/*.,\NI{ZiqY;,~<bٟ L+ ]zVIJUe& SMl\c;+3Tt̺kDBgd٬pĪ䢌.3P;C*ū. -YB+ЌkEgd⊫hnftbqex!0C^Uu!U'a8TmsR1b7)8 CHYTM -}1*VSYKڰfH]AW!g5E6f>4ZKQ{*SwB4$Sgw -$$\T\#H(P݌{/͆4ܫ".<B$LqY$g. Qw5D*$naH`L:!A~0]S1$u"ک dD\x.!)qͫ3ϊUTR2**mѪtERM(eFJpGUQR̓EքjERZ|ʋҧC-M?bJJ[<zq9pxd2*l^ZN]JR[}EɊ|BCl*qorcW3GqV M.ɫ9C>MjT}s?"~m C_?N4<2q֓kWOM2*BSIhp2*>~fD9gD= ayF} KȣUMBipHj&[S"ί!K~C#%RGjV/sˬ)]X"(hM*!ЩPv¥Vh$STbkB$7s'dITиV=i*;U)Z5ZDU>Zĕ?VoK˰C_̱ўvRXR Ԩ?"ɴ[rEV,ĸ7UPTSITMH,S#ȝZbԗ-ɄJ@X(im4Tnz=$-f)JR|R"A r!ZGL|(:ڞDQtK:e,<畨k\)P@&^*=9.,d KR5T-*jPlUȶNMKE\S0=zTʃ萪!` Tƒ޶ڃjPIVDY uH:SGimM P:MBstBT_M?L@8;=(qRCtfwA  «"ST#y`@:شzD#wdԇ)X^'͐bXWU= -G6Auijۍ>/"V?J6KӵBꆂ.$!GYK&$֐iVK'D(4!!P9n},~%4cԐȬG+ȑ*Jkmrm.˕~,*%*2ԯTCQX#CB.+PcrJFaq?J\<}Fsʜ. -{an{@UuPx36E5v|p0!LbE!PIPƊc1+H*Xm6OȈãEBS>SY"]"a:gΙz9B&[{^SƉU(1&5DT/xjCtU[ᗅǨDYX/S4j\Q嚗DUx4m^A尜BV7 ;tK M^U.-D2N2ΰ+H̪1슲C",ujiĝÌXB(DTܟj~Nb!FVrnt*=*[( ՏvlƤӘ>dL!/+e "*4Qr!S`xNR-.^`5]=E{pR!YV$<8-ZE;j"R?;Lf}e,,$x-dyl ;TFÄ)R'aʢ0Yс-~3k?p^ ldd7MI $*P嵃pn&7X<]xk܎GI}a'Anؔ&wlp#HľR#c*Cߐn%1EHDMĤbdMAe"&FDW#j3j #`/M -;i`cq\=Ӭ’EM+6hklQQ?VI bYV_%AJbRT ͘ק&˨4¦*@HhR<@ `@ 4;V<=sԔ8|j8"S.mJ"q -XJ^✷S:zH~j*{zYb͟a046(j?K>xq_|z䓜 x,`=W'efp<*ɁIcTGfy&*rEX"Y9V5.If n'luSnMiQJF෢|O}T8VÝn-UaBm:L,S'2QFvV2rerQ%U@yAM --zP3*C}CHa- iZ_P @ԧKD]b ݁.v%˂2Z/+Ij]tI֥b[O֑8[mI -'|IpUayx*rf%t@p.S;1g{j$IFfKD6$RJ#ֹ&aHg=.Bgi6[MQfŔ2w`dƆ$#*Z:):b(z}Ȥ/a(m뚧A058|u%+Y!(=di rJ7h_^@4Q.k!IX*+#ɔ7/K&PU=}z,o,ܗ pYL F?$}IW\rz#xlKsa,E5Gjjaoƒ_&(6M?xG߶q_p;ew59gGiSVȯiȏ*Y߇'q$\--ֶ*/d1-Q)EcKPva1#".E.B 1ҴeZyz{aGkh,(h병rJvn ,V ywWͦrAM`@+Fmq`!Dhݝ"Q\L4ei`úW603#%M( &_T}o񎊧\4on$ -(g}WE(" e(`߂ulAOð\j5]vdكP\i;)gXI9Ve=H뻯|)qn?Evmh}wVg{d[r:'&$}e*x`,u[F=T-ov_~rϕEMc1Yc%2: -UkRRfx{@n%Sp4#T%$k5T|'#V @`$5xp抧갫Y 2sVo( D孙^`GbvG@y(AY&n1 ԭ{{*Rk^n0!jP.\jJ}2J*j`9aW -rIY -(U 6 >v4MHkkH AZ;•_a򦔰]Ga͇N|* w8"X!N4@Xr^QE_{Qشwfbʭ5K3ozr/97ЙP2nЇ#9B sE#r@o$"j1Ҭ)a_H*?/Iɇ"5A Oqh/&®\q V(Eva ЂV*B<2V%?K0`@G姓j)TvbfAY=zqyRf?JCõ/ -ܫ/UIL)n,P|;Tr^=H- P.QY-L .k}Aġ~|X[TzNvXb.6s +4H8P59#qH dzE_=0hH soONȦMYK.ipqYW0"݃SWGtgSj4.S:QzE N=]7Ў ZW(:f53t7oǓݢj`'e|m#4O1dʘ_e%j:hJIn</2l, ;?XPn&g"KcGy9N~H\ |O͊,㙏E=s '%ùېdG㜂0+}2%g3 m ѐ _+? 5fo!buw/ZNń 45 R԰V$ LJ).sAvrկ|(J!=k$Oɓ_ooEΗkil4Dޯwfx.P3ػYpMeJZ#qq"djKCV;Bp:psH h7D^"+`QZI{ch@C*#PIQLVȂ@ R 7Fͷ@<4Wz$^W\ۙ愄^DqZCuv_;̯lyZ9A1y@s(W E+j ќ/ҝ1b+~bPS=dMT5n6vk[Y ?oE~Hf UT8[%)e'lA!U=S -V>MUk@B6=0h}pٹ->qԠ;^GQL:V4V㫚8q|^Q:d -ZNhj"́1aMoX< TaxFD /Meæ&Eu!;V.7Y閤5ٮFilz^ɬ \NFLi󄛅x|/t9G} p͓7rrbK~dSJGlj\/NڽQ-b m5yy7z _`ֵaQ*[3sR-4k^z`K&5}RӂUE4]Rݟh oHHn;`2 $N 8ߎ d G2x82;A{ܖAS+ЂNnB90*Om@ۀC"&8,wa1b[0U W@[. ]mI1PNYB3[d5kT\*0Ah! -^!h:pxHlpwn e7>*LaAfTk]An]cΓ,Լ5H +ҖƬ#71JG:uoS} YYF$< ZLha -%ͩf\FMWGqT!~9ʹ IMi >j a5N;ɒ{ꎞg62*Iv!ѣ:iTh±FAL#>+pCpj C4m_JA>4GK4.H5]1ƾ8D@bȻe9EH~(hurTp4tGln'^-\E|H &C3{?̃H?idQ0!͔^7SU }+hcÝ$U`5Q;BHB@ u+**V1 ]mn! ՆglOd,>U.+ -!@~7ȩiǐxrhS  A݃ r7l+~ &QҎW~J#- J0 >Y9 y\ǡmB2(3DJƴ&@.Y$AE;H-.>0 ŅN}4wZ3i2H -' +$FHGl$ IA<فR>țY @l-3+BjXDEo'ɚ`>Y8M-$қr];YF T!YQ ^+DPpdg솸Mj;8 Uń-i"7I=c ɬ6uOseb_fT;}223 zd(?}Z)uWYY #fSXA5b{kZc>BVİtc鍌HG -}|f`r[G4֧YA Tp[ס$^+&˻&!HYd88%$t.gSKp)$.O?)Bb0e3 DvpÎiVCʆDZV֠QP@eŖ!L8fZ")A…Jk J -* - Ύ,X o --VHVpPE2B^"~iQuN;*7_]C37ٷ] w D> Gk01/9B°#9zH|&%(|;'rBԏ+b ڜ ٭nB#ifBv8.}^Jqw[`ǂzïj`> -̨B,C|@u('还E pn~yex&F) &8dQ3'`lD<1O?l2BA"<1Lj7YIT}uJlhyaB>Hԧqf$zF~5I=&>bQp֤#[q8&~͎$u,Cћ`3¨b2Q~h=^Xe}R2<j|B;PK76 ru"sB>Ҧ9 *R2jmlZV_0-e9<5 -\(Rn)j7P5Spw03?`'zYꣿ,;swŒ-se[5'6X$c¡D@oX A'q+:93m_2di'!~G;ul?qwRb^%>WoQQI -hƩ$Q4uSG9 ݙ$bFe0Ac$ -%MƖsky,R4rmr;{Mӧ& Au%s__PbD}$# l{{GPp/,M Lx )#'3:{u*{Ո@(`q '1anbj; ( /Fi#Ay v]PRLb9 r%~27Դ& -xJ5MԏMyd=I -W2hB\-SA%"Dc+74Y*[8j3K;tų1N -D'SRx}KdFB]%.W0:|.'ꨆ;5D*= !N(ujmfp,~yZGZB E-'H]O9 2vC:NNf2 `GpX/ 2$nB-]X.+ LBs7Đ@됨 -TF(X@V)A'2==8wDK8~܍xe4)+G?P`bLJ1`)#Ho>!*-R PnJ = |!Sl*1 ]0{} |&Gйѓ - H÷NrU;$\Y`r,lKI]jF p2C/),(|\%Yv DTrukܗ% G[o@3UX,Wf(hKBVI@f[R}y]qC:eLJD"&n!ؤHrX*xJ;2ĜN9NI!~cdw leK"ӍK)]E؋뢦'2?n?Ǝz˻6=&)!Fuc/Ԇep*6SE:r] ֘/x~y@T w>YljTP` -Hz -Aߣ A[$rQ=-] G(R%۠bTtwD?e) !DŽZj -<О߮̕-\">A^>mg>A OeQ ۢUM-8f=TRU9ЧjFB)Z$'`))"*:jxh -ֈnΥx -<&@si@be)S􄵒*^=5uhmm |1ۓ dd& {dh5͒z_Kt$B\`P~BftsA#0MUDLHܟ\Uvܩbb`}?Ș垒ez 4"LKId$;|wǞ֕5/G&n_` -==-N[0߿DHl0>~9ˮn)|FU&A:T*(5Y\KsD5e;ct aHH> 'RlV22edFp=X_q 3/0Bᆪ`t,o(W]8T-Ixy±ci W̤^9q3QqMs˾@fM4Դ0ܟ&t=]8l -٫=᭩y{'O(<ޡ|ILF`- SqPm(gȹ1$cfJ%(H*gY/5fM_*w(4ƫR?YuO ->9q:;12r UA͢v>4Pdd8 bH$ -fe'7u9\I$%*>]n@nS{a1~'2V-@]3~ kdXES0=n# =Xc_pD@˼2ڍ${φP!3oԲ7saCS¹pnY8WnEHK%2aW\e;$k$w3Z<{'5 u;D -ʒxy:$ꎚ7iCt&Nǔ6kvzwȤ_0\=ْ᭺ O;l - G,t;LoRW@&1UѝXk>zjU̍i*>8M%(+0ʸ˟PLOiK *Bqvp5C.[Ybu&&(a6 0w! ;" nvCy:)+̂(3}ZsCRUAc7]|.fѡGH~ulQ_3VP*Q-L\4(=ZD_5p<笧( /|.NJPՠb!&rsU痣ʑ {v!98*S ݘe t+7mUR= ʃ!DS3Ak=i:=2d(l&G+ csctbSCguղ A=jF -"|z!3?`2UE (B"Rm@ˍYƳDx?`uw,S\ՃӸ HaoS,<^!c^V`j=IS<@+n_3험glPo "5ªM/;n#PAkuC"2*J@hR;}?HhHFM5T$, 4Bu8HAfDZ ܴfTreqIل4y-!Z iT3.YHkߐkW x{+d+q>8ixjS^vWV*X %~2߯AN}g$L.eX+ .Q, 29`ǵzi}X>9B#}-^y=h4#PO -LL/mૣ= Yڑ/X9N0ٚ3nw;9S1eNLk;k2KDZ|-3k~q -מ=]j6XXFVkYL0'a= OhhDa-,e&..p9G 5!2kU\(+x9^ܠX>Խҹ|\; s9=t͠tC]3sN.>Ps3vn=S/l`?}j΍IB4,1s1{ zXxzG&2Q@z.f^Fs|.P`s1$s:4h\sD}3(vMav3KHp - :[QڡTd kN歾UHa{k(_!5mO X8X]]pU:x 4#oB{T8OB7.e[>u:eUpWMsG˰]_)v&P~S. bit58ꒋe6,Ԟ_DiW\eT̊Udp,ɒj䔬j5Vk2P.P/<+o<7L/'Hk(lJ(.j9K:?)Uc" -4([z~+v]k[μA(64[6/f+q]%?pOA<&DbhJ@k 5?m70f~qUAZ/ҴP]b>~C_r=_OMہ'71_ T1Ͷ!Zc eݪWPR")F. |k5+1 m):ha%E;'JWS`B{%Usl~*]is~ZLP1 0quKZYf7p.k͍Gq&׹&lGFn7 2F- e?7F~)7ծ+H?*݅%k.nD[UIW{W^Iѯ+WRaG{-'|'4!fp'̬P'%hT1S9#3~_M+m}KhsLqSZ^!֦\v54drW2#q%ŕL?B pL;8  lYBPNP&M,Hjm90JЉ}ʵX J1U@F! : I)%9/eK[Dd'4Aq-_r˚|c##3Vc -pArIf!y+xY2__[P@$ $v{:}"b$Fʆ vi@"?5Vg3G6DU8/-,%eNRV(j -OwCҡ‡^y:"8jnp&Ch -뇘AQ ; ,bp -k ;%Ja+pzpS`^4g2)w ŦR(8}N:|<-\ՔB_oDNre\SKkcLgIz+Bt q~\Ԍz~]+o/J_˨^X:mn'T}9/Ӓ -ʉ{=rVVԗس#}?<%}-T@?{7*̗zH(^ɏl}xI^bx':!jePTs/3w򬷣ϣhGo<1=B\mk߆%CSpp&6L(Rd -=!}tKZ7_Aq6W `rrC)tǏX]62*"^@?*L_ >SqnndE}$@mS鶿ۥ/)ж+MV8H qMeJ/vcү&lzڝ>O]&Ȣ k$UvWwL9j{X!;x(_]iMbJȥ_tI#J fk9 Sh'}@3ϬT.t;<_IݚoF@/ݗ[-_ῲG 1hPS=N,Pܢ;A^'TԂڽ8yz3XO\k.4'HM) _@AILP񹐊G~/0(T\@?%uk4}MqaW?] s$lTe/!8Ӓ43pbCڥY5J) =QYU>9'bh -caN`.=D}n`K:fQAà8k [R)֘ڬ-aG2kfgY`p`6qucԸC8rҹ[`uo03<ۏ)o{_q_f]OF;~y`nv`[lQ<}9.~KlpKM^KR%\ pJRK~ X rpLCb/N]Pw'ǴAU|ĺU%C,MFpyRпc.h+ XU[Al~i+h_LKㄩX"J>#rs[Cpkćo98,oDsd [m$4dAeBtŀ6W: çQh+yxv_TS}ڏ=p,Hƞc@AlhFmu""'i1HB6IV2i4t^@ġ?dkm͜oWmք[?_#z>q,qT1yv` e`eQ4%Ϣ1D$.sഌ̂u*{9{QEX}YruU{~D!q[ۡĴH@yi"JÒ-/Ʒ;Gd22&WYsd˿)|KYyף0 7Uԃ6`/l=6֫YFj9fKf܋@+m2E6$߯l4ԺKʚ[Pvb&T3G@[`%Fq8,@xkʄB01R vfl{Aj4&1[c}VMKf  OjP;p $*vдτ  GAA~:yhGOl3gu$~.`Tz)f61涃 ~d+I_;*ӔgeOݱ5>:SL{~(JpTW*6HZ@$PH?~R,'d:g|"/Tsuk"}Ɲ4j ~T$6C'\'IUN,oo)WB!ak-yp@(Qa`"7䩨Xə=c(l=ȗvi,ixm!$P}8۩K1m꟡ -'0@`?:O~:rp{["n|omӖW#ǂ_OD zh(\g,';3 hȬ!KvYZ[S+Y;Ԃ([%qSp)O?TvM8KFqׅDE/<қO -vw1&5Z,"oea^k#ÀVs? TEM3@as~EGu'ʦJ1kSfE'$ZC%x`}0r1iMɃVqmٔSZzN\tM}rmjoH2w4{T^m i ax ߳Ei<2cp;1A.N?y)G%@tƼ+phfħeR3 Vi#Y AN~H|ESCb]tQ"#Daq!^kBLM4`7V8f% ->uϕ݃#sQcG`ez -M06Bb.;:Y}UdnD7.1We7Ǟ'[h -S@|Іs\31  π -<~F.bVJ@ki;F^ZDpv1 UG_٥\59TzyHsY {=7(q.h>JrkQsph cQ.Rh^8q75'VOg=ZX}p( L }.bx^շsm6MeNU<nD7HGg 4bӃÃTi&#KXSа)w\1Cʊj7G$0 ӂ.Hq+M\JyAj::hh6 1 4MR%Ku8gs5Lcdj.P[Tih6rIet 4@"GNOP2#w.(e*;H#R:8hKseI#}:&cix2 r]r&r]{vW!U+*̩m)Odq2.r<=\,42 E7h2(9TВyupt PN7tc>$W8 C:0`vz!,X,qi{WNjyi:ݨ,E^ԛA:l zyl暮]4mx'bxQh.L^ty\V~!\S/.O)]u&iG^8f6QxV4oMuὌjj$d7[(]KS̗¨=g;L,tgRCluz -㙄E腐0&Rd z""=ҎI۬m>pJRj'`d~Ȇ+ܐ'i2޵ -CKV)- -" -?+K8z]چnu -Êڅ9% C%pBRvZ­"M8%}Ay0/pP,">9W1ebQ;-aPA}xMAj!WBrgb 3CS#aib I8TQ.Πֺ 2b)0T@| b"\/EJ]ؾkyV 6ؒ,soW D,-}[1I"A` zbPpbb+\E`xMn6d{IX2**D,snن=+G?SƔY!MTU LT/t4ՉoKiWXk_gSWcoT36&P}A1>:!t~98v6\C4=5#->D@9738p,Zsm~4T0|@SU_.Rī9*T.뻡z%(~T&:ttdlȶ-4TT!܍h8$|V.QnD1Uْ4ݡ/9)lӱlQNI]#sWfp4<9LVe@ `mSԺo ́>yʮ.1'#5?4^jtȺJO73ɨz/IBvf~SWwGG KRX $1*mJ -PhL!O.!+\Eo0A^.࣪I ęuސM &(E4hpW4Q`V>qM#B\2A䂺O'A|2+ V -'[%  ,XM ,wIӷLC JG=[t է,4;9]nUuKD.h~S@dzm`œIGPK:fb^|nH۳?$=HJ3,%&!x:6b.~&9J}/-nAA;Dg:i;Ҫ<&Y2 k_`xxo! dtznh[_|ԣhcM! lo  ꩽG{ί_ŧ;{kѬ?3 %#OYJNpsIN44! }Zmi9e:J2p](:2g-{&EEmda^rgy_u-Ϳɥ'qIN+:l2@Bzm9FJŷ 牏# 8UU:ln">)ǞA,u(CKD8A#j8*p+ `R -<ݤ -Jw!ߧH)![:-`w;Vg1n\PGPS.ͮvj6Q{AƷG[wf<Qxf?AglҞ:ȚN9y:( ilw(BW~9M`=zk$,3}@JѢ\+W [un´G-k D4Zr}8I3 -+2 CFR5X;X]]L"3\ļ\#Uυ140SZH4-?;ih[uCPMXq qxC"NbE84OhsW}rRd+g$'9:H5<"Xfk Ps (/ЋYH[dz_[r/Lb0&ccv<@_SƁ{h -a>"W1ށ&֐%Y11Ul15 z*fOEgE*Wcwǀ0 E4RQoƩ|d,%#[eek+M@)x}޻- uؽk2w/Ɲ-.-wb!·v T$sȩ%Y%a{lM:Egf*s\zYɖaE™4&!e}FV)h;TX,*R&9ۡܯXuD(G:ߓa_jNBT8"~M]_'!1o~%%Qz{r o*^%={4&b Zf B13h䁁Xx` 83!, ru<}Uc} %n}0<3fr0"-j?me0"wTK\ޗ;?2nR1Rx"Bk$>O=(-,J$%— $1 {L'.w$Nwv\886%(~A; 0gg% µ4S?g%vxCPr9K"_6c"a?L>[3D0DG4i9 5 %[ئi2r@8C(> ݀, uD@c>a9@GZ@)񺂱Je?JolGaeXڄoq y„ L:OHۮCU¿ބP`Bv5kif0OhT0fF@13^ltfuG3ccˀ;7Mws4C> mXy e8fe8, -+]H T>aF=,hg -;DG2ZtJ%MA|ctsğsLă^M8r1R6ƃl})wjo4Q?O}FSKA-v}9_#DK2Lg~ݯ2nw|L[ 6T1QVs?Y_f0f?e4nn&G}h !l /m^al>\Fn cԴЪx$|᱔I'V'+qLTTkq_!kw[,%#C2K}%&ypi8vPAc" 1enW)sy-qfoiinfPq_[@q!cCj޽~$z1 --=91bkc9375#$d߷bcV7Is1zjB]Kz ."Ԭl!}P5yw*&*8YHs{UUӅܠ<ˎ'm(#IJ@l9.Z1Fwm @ "wX,.h-J6F^NbJOd^p/jaoD~8ol"^l_u8VAtg0v{hԗj'#:@bw2cWm`Vlat.tA(CG+)tCqU⅌Jm1HP oXDHTS#  'cpIuDBR c@/^yRxWƅsMO#w̭ʜ^ vje{ >mBp|Y,~t5 -"[C*-E* S#>WD#t -Ȍ >D,fQ`d {1D Lew჋å!pZB ?Ix>y{I؀ Gdi@g\ h0˽fDboϼaf?ٷbѰ%v@NibdDKD{=$ǽD4XRcG4IɆ,ދQGw;Kعq5~e^ԭ"(_D/S4~/'q4I!:6!z_IuٔU0ެ# -ڬӋ+\Aa〈VF2b >stream -ZU~!lԋ%Vte5a U|?zeBv"ӏ8I7lvCDPtw>`-^fd'SLofC]q j&@j_P Wӆ.8%!0|3OE791E!"x WMmհ+ǹRV3P!JblL 4x<dXB~ۀ@ /YOJ6ܾ,M~\%Mtw؇[ކF0#+/! -ت{MH5o@+©w0+ĈE0zC|8@ANqwG^YC¡M{}(ðʤJ 4&kKѹ!ԧ P,|RYEO -@"*6:j(/dHƣzX $ɳ1˰tD7D -$DWSCYJC#sql_ioA_uB|\LfYfPg/AC8_-)8xⲲIH ЖCO>v2uHC=u֜xϰi~Lx ϰ;}%jf8h Bbz5&©L<8I`8n@'5~ZD8GT dx$ة=aIX}k#Cp6}&s?+úXwj 1^A/܂Ֆ vцJ2_we==#a$Q(^ -t(?o2!0,!_rIaXFlGm@$ =1Y0tQ*7aoUGG0́%w to5+ )Y!Y3'R204TBx!1?MW+7}b|; UxVEKVE#&8`0iJϋ{U yyl7s?~|ď<4Bcy|!Ȕc2W9 -:75k1}:[JJRͅUQdBK>~RptT`=LP _T<< /p#3.]ͭgbKW,w7LQq>< qE{pf@ƖBXl]DF~iF,UcfAHvi-U:23SmP K+>"Ra#0=rZ- >5b}ׯu0nࡨ -%n)!ra"T-։O9º*CBDKOzԄ-́=X~yj!BM Ny؁8le$}9GeD"9HԵ0W/m)an0p%GT -Q uŇݡ`D'PBdk_$Ȳ? >}_]Bjh2.L[Zq/4WˣX/>08ba@#VX+\Es߿BB>Lj%'8} LLB3~8Uk¢75t&}Aگxn3&L ;h]ڔ/y֡͡HHuW5@pDɹ$T:8RMV>M9"H!lBȨp=ST( 2loDtDt@>%xlq'`J`Ap Z'l ^Cv34 [_ͥuSn&肉+ÝD+-I tlIۻU"g5W|TϽeL KnzePqtDozԙuɅ:$%=PV "=$z$~%<-^{ i1 9߱\mPSliuoprXoe(+ozX/@>Q+]MRDOfzA -S] fӟR!?tȚ`Y^_d@[|5e Vm9et6Q-pȎVÈX̋ -uO^kq=Sh 8@q@$)L)g/Zwx}w9F?ԏpBULI64 3@vd!U|mHOBIMc#gZCd.6O/<=^\a4"6gg3K 7r,ϒ\TM쨕wjIݰNVu4qriD ş7{uGޣ_sZTn3%5~TNj?TA5UWepqx_%ETknUِP\%bUf>^B*wq'H7]ܺ[CMbJAB3A#?)MiT+ *qr7,͔<a/@YD=K?4/GFs?5cCԳ8;E?đNoQE'Frb<1Ȩ:OĠϓWy։x)q[KEeb^Xn{ -SzpvR~gG]"[Ob]ʌ(Ӑ[Y|$YOAZ֓$,I\O"0;7WȰFfĎ*WcՑU/))~LJ?BWfJH9%f Š2{0DgT,e`%1KÍ픆Zq+^W㳲PqE(nBјu_z1ɣj%wIRJ֒#a\BD!~SQ>}]lzzC-QJ:iݒ{iJAO)85K}wjo|{]KH&OI~Nd\?R|6\Ej̈́|dUA 򆄋 GԟpK W=D} ){x3ه9}L00!]),2DVF$k[31ã/Dep5{m}u0 (d앐#(^x,AcȰڑ!/vx 98TNu2fEf0i!v,uEo\S( ИRA[SNHSӆRVD,ZЬj|qhEB>4хAd$a &5dUA4{"ˡ&+tm\UPIتJ /jAQ-SՙHIi>r + -P!?jhANvi7UDEEUU1Fdab_6,5DUT:M$"rzO1莑1A)R"IG3}? zN+=f -8 8$D )-0ɼ:z8K>/Hi*6%LCQƕ(]biH'(2"xUbt94hwh. `9ʯ`E!67{9739yH\dAyi7KBSʧZڿ'5rZk&#3ENG^3HG'ǔ9M9F,a%)/ -"}DL+"U/Q|Lq_"sCP~>̺3J4OU?] LkWy`'  IЇ!ICMPPL1&9ъ ",T:30`4MNdޑpx1j"U$bsfP<62[%X1|8ZR$fQV -l.|ch= B(@U : Ða؅a. CQ$ȅp(O6P%P'P@F 1j>zPADCD Q.jg.)GMRe\UlE? -G4aWnƢ+K15]'Z GH+f⟎ ) sN2(aGːȳn߆3]zYvNkm!y)c$ZwZn،^ݍyŕʨ_Ǻr -E]Z,&e h;܊:߃h|`ITQn'WqξVӊdb+*[J)2әR|/g:MڝtKmu"_85O1vS$i8Z\؝e5Jr?-PMrI4g"֌rh~#x,zE{>99=.f GVe^r!Ɍg - gq""}+9/ŭ)o_ͩ 3IT!&dH,Im%=1J46RgxFIV:;Ŗdv~zHԉw:Fe#t&ƥa8I?ikv}zs|]ft 2O'}2}N+ׯfڒ5"ludHײFCEi3(x%1WoUDs FcH~}6'<zyV1O_ -s1uTs,\LMn>g{(/tNz_'ۼ(b2C]}Bz6S<DqY &YuTvǒgc&}2yumdsVqUYMEl6dN۔ܳD*B2$R15+ TZ07n7:g(ƴImC;nm9 HLJ*BK 9L'tqZG܊D - xZ-WhIU|! -dj%pr  U\hH HFf#⹣S Ҧ"Ш2G\D&Ȩp,OܯojG_C>^=ꏜdE.YJJ}.̓3F +p#!I)"ʧJB24*ihtV͞I)4~!gRhDBJHHMzp0L*^r(iƦ!/YTk2A/3 d_Nޠkm5#$!si PCT} e;;s{69&²p,kkWlxe͗x>K̥* ȵXh2U,ʻxy 91~t,_?2 _D}Jl'!Tj# E]$11V%] vloodq QfObNJuBϼy긎Gf!>RL(snD'"3{Jeq) YL֌fZ-5QrXQ3m8)[<EY'5DWs -qUJkE6:}l9{^!Q3ڬQ1r) .VXf$ySBJ|5K1(l! -i.>E&F}=j,f"j/5܃Aj°uhcS'I7)cT+Lz+6 ҕ5NI5}M" M 4*Ntc>}u)9"eV%hDCiI ]:6Dz \9u79f)8[+ uwf<%Rq&Y $5kˌ8c4B -I~AYem2W=.lc)k?n Z3Y[LZo-Jx5΢p$M'Lܿ7k&5qq(Ϧ†ǠZPպ;yt6b-v cN+hҊV}óo2+<^謱Uƫ~IB2d|ɾMQRS%5ET+!k/hk8ETk3SR,I`IdYȆE\ɢS -g$).jsCឺ Z?jB%}YH|š%+pE>`𭎐(uR?7֣FVJ}>jfslH9aʋ+z~(a z֬A Z~[$r.r3B鰢RQjE+: hEPv(5LU$wD<:ՉFMd?!;ImO"ͅE7_#`h _Q -NttESIF9_'Qgxưeg(WZkl7m9ΕV :98$j^E9x+AsDEzw.DD#Gʮvi CGDWO$=SDRduCHXVrsn<eEj7Ô*iPd,AF0)mqXJ*bp YzT(9k= J'b xYvT,Kc7]>OZFQhÎGxPm~+(8NW^ݑūIfY v^bө)UlM%CD*Ұ蝨HX1|i$*d>Qyjd:Ԥ('jȫSkJӉx2.Q%Ai_T݊,E*VDZRQQ}4{Tl(h:PȔASՆwN8{s%cKk]g $9A#V4bohR v\-KhkbRi傍 Gjdz:8a&,NJD rh_QdZ.N:tsݴLg+V9Q=ċ h}n&pX UI$$9p$ "|)ү;@!qJe@h']7۞o#. si `ՅB"hx_RD$giH&x{ "/9+#D $u -\Ah9($$ o&'GC\F, ӧ+z:z;#a"'ܹ -PD e U?ߠk*$'.ՠUd=Ȩ_ 6]G6yǿG.z;ʍ`#ߨX`ֺ> 1Y@%T>Ib@k2CMzpp=q:+_h#n9)ń](Jp͙#[SL+~Vbs(9`l&~SX>+8Hs -F)WCb$FZ1 -MS(/{ -tk"  ̯{zFn eGvE 7,%d"|ʋ@(|?#,郫 հDB:f w(mS˯ -Nj,6$X6> WbiEIF-,͊S1b% -&np - MPJF?'o@YsMbtqA0#J,N_ p00EJf J= >Ґ>p2P6Ď|b4UʞI\S?B#&S -0ם J<_ [GݓkZ&dEܰKaWSF㳝 +*: fOBRoty X^ =G]VҖ ۈY=)h&()l.rk4mXQRHx̠>wtF53+jN9CfM R033|Q`z80hGOFvhK'mf3N=9Q =wV_)8TaU(Em\(Z7~5|&3t) /3>Z7_N"iJ9q|>l]}?DyNAj6}`A.Fa*$\G51lR^R:X%>b,}X]#PQAf!_H9 ]R>Ft.7vOu.+zJ_ Y%H,75 |g -ӷg8+aiꆈk=`Vf\ȥ޴qU@1Y#>!.Kʜ9}uTe0X״.Vi@^jҺWipaã.MO`.j E("& -WSpX@M92C?F,3XEg0<}fm_@˴폖&W⒁NC(wIF6FI\?qIu-!J?$H<79xΑ^emABS.g d?ToΒV`pЭP{[y-݁:: _ۃ]jv*F Vzp?`KXk{A_ jC.eC ޮ Ww “rIIcMǪ^'Or)C,U7~sᴥ0 OO1:/?趁ΩxOS7[d٪w=m?&(VUð R7mcF  _`D衡J|;.?ZXXƝZ)@cԡ~̹pU20~2_v&aXi 7,yT;Euȿ)BƺUJ!GL83<!J_)n4N>(r UkzETXv'P`[-NG֑Эwfo@=Rmɚ@.JlRd0_ &z-|Qسqi x;j|J@Uý,DV ُJ9؟ PO1"sw;{kݭ#lӮzm*Re#a?14M@̬DݬhesAʌmA]NsR!.%GTC;)iAfNz2wmT~ ~-G$Cm0yzXGMRu0=}Dn4[`t< o~t:k˘@%@Td>w' TZ}D4`~qrbUTS] :HGޭxd ׃( \=ndc'85qa@՝&P! V[duͿI8)H3ldžh{vȇ6VW)ԛZb-lb7zbۗ͟h 5IY.6#S-]qAj &gzs)d/=sa (oZ?5?@,\h\8FQXwk,HHKhdŀPP_`"a2Z:K)f~l7\\/»˟0Z%`hI\qo˿Q-nmSlqD1K*Ti`E1Ai]=/?t[Twd>bk\ػp*#%MƤeH_IxryJ;fJ9eQdڣSlWT\7Lr:.FY~"n&uUPWfѰ.Q~"8(!_|_*[yrh$ܧ}R4v̾ 2Ym IEY !?2/ XN&l!s03d!a? -6c%1 ̓uLD$ˠu6~/l4HwvdHh$F۱UEM$Uٯ"_~ɇ]u,B>FlCۥC&[Fq4/~_ -?Fc"7{bZ*~ -DOha` ~˜ xiG'e&M9Ì n -k -!:ݼ_(: B[fnWp:X?VC?߀9oڂLJbǸmib7L#~fdE|֭&۱: L(0X0 0#DW(bA&=jJϤI-! j? ⭣O/%1BM}Wt9<'l ҧYPR_gbD2f9DoEYܭ/4[aq}GhIϊ8gO$f_*P f%0~،-A3lta 3HPAAh}QBB~:)ák.#I -"Qv%3פ_lrrb7 2HlS-~.+3ȵ\67 -[<(+x/$k1RIG]ֆF#?5m[!σkH;fC})t~?eqчja)+hj<qց>^ )O>8[ ̽}^n_3a5\_#,4"@X"$}EGWZCIϱHM-5灏f`/d>S (0ߩ8/$Pʿ }cQ :4Zі߉6J]>D>cUBՒʗ9 ?Ƥ||=(M6"CI4N>9_򯾡YM%sT |&.^0|KN=L`l1,g˜kϨ=  QӈU*(tks_v^QǨ=5X9$V%mXj]R#NWk^kAmJzcЗek ƯT84`,i -N{O7 - yb5 Ϸk,Bloί^{'?(Z'Y%#wQ'~K>O|о'>g1񸭏p .r}?BM< '鼶n{Ϟ#? SwG~=6rg'>m܏tΟMO|`;##:dUI\(Dl o& -dߖz\S02oZ۰D.F_]=)U ׼'ӭY4ċv_G 1SZiYèZ!\B˼@C$%$#J%(R)?/!"'44ds(ʆO= -%0yRܒ'OmrON ?DU0nOe 7]Ka*?Gٺ4&öTt5waMt;HL> 0+ e| `>/i5$?VpBdw ~\ i>6J@RAV񅃾͒hg[cxGt^O-GV_U.P0 1ԛi~c!ܫ('u -,7&;Ky -u±rXX ٦K̞ٱoa`w6]/#do+jB>E6D~p6|3KHVމqih˚]Ny|zu:Q=IU9 ?=Uh^qr5<TyVQ|aWoStTkɣ#92z!(j?X`fXש|E-[vKO ȩ]8cx;4VL o |;0X0`c,/Zz.|?Lw|?/,h13AG{8WyJ"reWTX>9˞b<bW󝿛i?=F|?g+ ȁtB5N,a>7  VrKSqje6Zs2|\,B.c/cPG0AU%X*DZTVOp}whMt{3|ϭZ!YzmN'dx'AyXd=}b6 >}|+_`PB$e$@h}D xJF%؅Ҕ¿yס5H{e ڼvo՟0ku&=ދ &]&OdHڰ*ȯރ2d=P+/iƘ|P0/Iz˶WK-<7ijW0DgǺ FUK3S켇ͨF1by?&kI)uiwJ"[p_:"_B+i^DN pE{3Xy206Ũ%GqN/.:7?UܬpEBdžَ a[4S84MJ4X*Z^~|-m7j[yҺ'\4IUATӤN`zҧDd#'LKaR'sO[8齷j.pH\O+%M4\6Szo{upÐSTnZ-Zs0Fe۬b!jdj x k~K½ɨ(ӘАONErWHz)p7[7 -Vbx*@QjJ*"9h#7V^npxc5:ϣ6vвETʦK]5k,(_ϠgX -I>D17Kg.Sc, *P$?Z:8-""Fdpޣ@=" -X9FA{!CXs"OV 2DQ 6dwSj+Oj}J|؊3S)X8fylWIbaKI)N7Z]`~v\ښMl`_wtyAӰRAd~LP5P^N}(<(<笩㈫=c 4jAwJ3!NgLLs>`ν[dÚDJ.R!({[:%1C2P1k ~q_K"l@MK@bK&t0puf ݼ7RgoO?DeYcno -=O#ǥ~,!(pwBofq_I|Avz㭸y^~@?~ UT%aICN;a:;:>r:hɞjuWJi V GP0,1"V.uyy\9lg&v^U"=i|G)ќ)9 2[5.KaK:Ԡ\K -fsylOJ^)cLQ Rf^Fږ8cE68\n * '='Re:cEl^Z|39PqI?LNithG;9kU%yc4^D Qq: ֧RżQtAIf/a__P@šϞ<#/5_.uyr@&\MM-ϮqVcѿxTAlh^yH9)>{Y|4|Q*~0ʻQ5TiOh4-H1;B(r|g-ۢ3#_K\Cz7y5:/{T&3=+F|ں  N'UXB<2 M}q &U -E XI)~*fJ߿̰ SڎIU( x1 -VK |0VQy`&M5&e*~%^%f㖼MvC9*1ފ)B/Bx84B !xҝpK8'&~iYa@y„V~ yN% -sh S]v; +(O o+_dm[Ix?Wq ,%VTƤ\ ;(]߇Wɨ삗g u`@VT+ Ou&rO@z[QjmZj)YlK:q2ԃIiyq3Oc[bf!Mq A4C<o tJ`PTG-xVH܂0-<{Y/MNBE!WH >T(}8.%JGb -ԦZTcǗ7E\NYuvy̶A"p3Ak3c)n{չvoVԙ0_baOĈ^Re +p;5UWr 5a;x̀oboOLpe$3 dI2tRF4m—11:EcG v1/|T[֪2h6O%} s/t pjY#w9 =Mq7O"f<@X~GdͫBR -nE/+4Z@aƄ@єYU (p!H \S% rW^N7z'RR|UTmJ#ij3+Š!"_ #¹L#\:*w cFXT};Lr0fK،>.LS#e(7YAK# 9&҄K8C)¡*^1y h)d{QVvl|d -С1r]/>7'VI ±hpcFy!H[ٳi#,AE*khEӾH-4hm88/Uc+ށ:qKMddDy@ř1BZ68j*$(#} RQ$G}n@jk/h(hBc+M5p]rig2 Q6NŎE/̰%K <82" %Fh ,±ZQ0#5#˻,/f4q9RX6Р\)c+A#HG #+i|F@™vo8YTE9VC2`݌z%SY K/<20xU3 XJoC*Y2v<_56`ª%8ݘd✞Y,RW7uh r8O8/q`uz8+(=G4z. lPlHaT(,ZF,@^aHkˇ=Q 4VA:ųTyC]6~T [0=ؠsp3B]q%s.7(O6{T:ALMP*o_馟;DX Brgsn uXN'!gS&m&=o9^#`6:l#LBYTtыE| ^A՞eceQF\4xl}|.7yg *&iK #U9@ҫaT^6ADxJ!+xN Cјx#-A83 Y nv -N=^W<| xO[G=bF'K<,6aU[P9nP1" "q_7 =Ǡ0~`g//} o7EϾ6RwE?.85a\$oJ(שG -u=o.p!Hf$)T﹎k v>g=Ihሊ4 V|Jb"Q]yOK`IHGFZRoE.1}@&5v^{.U&:}vWNbD2NQ(;%>οBIWZ&ʤe@1(s[ -Ưe_LJ5_i1 \&-|sAKFBP (FӧWǂ}M[E}/I(8[%OvFgpsl'_EuI{J%ye)vh:;e-=:0\RQvj{b >.Z4m v|e ˺W9KCigl\Zo Prlv>"5Ʊzϒʂ:z#ZNZ z|l5߫"uy? $[צcWJ:X} f_L:'I>yoϸt(tu;LoQj4 YW&s($~ zW}RʨK"l> 'XϘǏZ3HL`S &LM_I-XBh|ݑG1+}}>++Ia>gPox%1sc-'%2 8=M.ڤ}|t& poD^%)SKDeOX&,X;S2}b}n;DAw͠&Q#KmJ/9|Œxu ~|5Z?5oæ֧<8ٻth'puph.5J?@wT;s55[ 6?JǢg3FACRnN q Iaٗ'/ n'V~^c -kvj~THg?&8:\ь>p\DE DdXvdmtdv], vu)b>}ŗԤe*5P$N:]v]}A:o$EtĒDܐ>5i֒ڸ4cK=$oZewbS!NF~ -N7BL!?x?}?ڒҏ1kl e:3WpN*|( AĀIF`"^VRhiOg=In[Iv|% >CE>QP-j_qQI݆08fӀr~öW;98uod3+LwolqҟS_Nf @݊+8@@=~.?x?J#?~ : E.&V=ȏhIڱ4B~RDbY`=(s8frrOb,UeMs:P:c(󷄍=C~-Nٜ#OAE~ZO#'B5?U]86qLx -JMא)0mv5(7vuSVP: - WNfШNثGӕ?9QLPPʢD vV*(=h?5Zx% =JuUo In#&DO*V2l'5&%=o]$t>*zf~9$niDZeF?2yKsNļ-a?P!ɖ!AS'M(;Ӱ,s3}4Kl[_IJmR-)Y~Gy@sxOQ9X -yZgeĝA -6ġȏ/d [F!wrvT*oɝv+|H츓tO*JKں!MPDy1K+U$-^ij -I,wvۧ&##F+:3A@oc`O -)Cf4䇐yy5`dׂc ;;Tj=W ?Ipv'koOE+[f~@'l)6r'R[܁㇩j<wv#:u'ඇ܆ONbӔߗn{`nOƖ`wRRln]Մu'QY -t'3ׄ VJ(FΒFBǨ -@i;.'aIE8ɟN ۖO&&J9rpp|K:i16t*"E.[}d)t?+0k~$Úl I(7{:?McucᚮO\*h:v9N4CaZ$V($rux䉍!qZ ZTBn}o`l𤝪3{v5S3-,v%kAd|1|'q7YA"I+DY?ΘďK  Fr/ ~>?PEk;R@ԏ8t$I;*Hɜ>?dQB?/)C\|7.6 T$bT)yrmgMXՠꦋ)tr9oJ6Muʜnȱ$my\V&`[q6Em*ZT#E>qU> k/6XjަG|8y#1H]O5Unc˺$svw/&}7S9h ѨfI6G҈F%jB+b-b=Ɖ6mi$D+\I1(0Ψd]4uu!4ht]Mӥ#;"9 ĭ@;}ha`ms=hah+/NԫKlH8x|i!P.F+nRyu47'Fe7Ҁ7Ƀ&\nF_8 -jBLC G:qRvdvGxgFa$|Zxc/!'o.9ٴ^~D  &&[L2M{BP̜T -oӧ2@bCM,Z$̜qtj_V4!3_ix#>npC;t{e?zX,q9G͟E*,m%$%:0į hȏ4h -?h#+PJp epS5F=C"9E#wJ - ĬrA\1GA@O;5*=?`EJiM $:&_Hz? 2"H˲7Չ  9}榬A Hrȯ*=yk{%Jy͉xhꂠ5'msNk_7qgTH#NSd}] q: -H 5:'7:K8ИZo otpytNK(p$]H;)*H892IʼA[ RPjTW}'1 -v(_9Ə4='!*$i&1Rh4t_KIN/b jӅ$!u9cExbKD$33q>RoDԉi0- AP'I/lZXN:q1P$}tzgM#@)Da RI~ q\:1eE >|cq+!akbׄ$lWnBM~brIu?9r:{+ohVp'#6?7Gr0IH9+k ;lT+WC$_$$JVrH<6ntAX X:$xD0;A -} MT=8*gzq"/QWs )½S -A\to J$$6}IYd| y'\t,$V}*R`XtZ31*nPNeS$:-Q:#Z7HPG/: YYCY;~$ʠjǬ#eum:fT -pl Ou -OB~(EY!5EANU)HPI-Hbv}x$}UBCr'+)kI8 -y5hFcVX{Ϥ,ꤿs$hIuQ=;0U$#rr|9BA`m'ԇR4SL~4)-ƉJcPzU4hU?OL%On&t^2 ,?~2ќysVLt^c J2)i*Q$*a?[* *D_W7$_d,y^k)[$cw`TGY$=]pcSO @=q[- -DX4֩sSl _ -_GmT!`>g- ZjJFb"dɿi*V”VvRSe5$7p 7} S.Z'UVAЯ )>J5L>7JtbsWM oN S%W"]ZJ-)JTZH`[TYE;fĀZ=m%K%`#ybe"mUX,#+(f[a@!ve-%t)jKvM5,S}W_oy{@hdƥw&P] DH.L,JeHe} 6DwcGdA|f( ̖\=BJC.ql5|£]4 [ CT]8w5=N y|\"+XɴtѤjUzIZ zLKS8oޮP7ΤpR6 9֘e(Ig#m5hReY*\N 1BJAEc#ӃJf)Ucc0fPc@{O 2)L\~PA7keG*1\g`"08a/ -@0&&IZbvTE Lrv -~)B ru[RP$=> =4ԣ+E/Kb ^)W -ewwC) De=e°lcNR0;5ol^ŚI&L؍[@ tF^{hT"iP97 U*%bL<_.i2iNn#>Ԁݳ]5*|o@@2 8 --Β\߰Ш%29j{H2-z0C&?jMW&|<*oUԱI[Ԗ+%2M۬( cNmM:p_ڼEBp:XmD?'U?yʁxA&$d2QI%d6-+*5Bd|NXLRI.1CAճP8[L8j;eښ~ſޏĸH1a3vwtfrtKM7_W)7(EA If^J#7ܦ1ʈrd顋RNEe&F 7t$9'K\`K @:ur;;Nx;]!x'D -):MHu8u鑧 5O9r=EJn,+!WP A[\wI*&^y[.\Bӭ*lZAQ#wYK1EOpd,EjǚWY3Ds1,#d="F -Q@,JTɬ -,og@DZOh# :R WttԸ4 +)p;o`#E'p -"*7W<|.T cÊ{2!FBR(`S?oaBŋۄɞ >=D$Y'f[<8|͜&71*#몕Q_>}a9+ާrQQ|1Jى895RTOx1)uZ /1`>'0y٬,qPM%K@YK񞓔[dE5iW,r*O)ƽ3U@Fcڭo/ Χ.Q"cxx~oueRfb8{ݕfYz&޴-FɟJ}[SASLgΥP;aoY~|MN ԇGDJ{wީVC>OAsj~}! wDZ>KAM~{Y~YR=A%k8gElf+upLQݞ t@xa -])F0\gL%jR*ʮ/r_UTZ6ϨAѨGjx5b&Cހɥ؍Ѩz|w4*jbF -Ys'ͨYZ5sxw?Q?ܗQ=kM -ұqe6P -a -KrXf#M=iVU*ub\sDOΔ}.P9:Ֆp=Yg"R]b*~T|…pj- sKH=*ϛ),T4*}lh.BQUlvu$FK-tJˮQb{.Z^cw!恣:1;|pT2 QYN] 84 -tlHQٝߨ|.6*zv~E}iB8UC#?FuC*ĭ,P;mQ)~ቍ(tbrݛ^x82OdWVz꟎)*ڙZ4E8**Tܨ;3^nT|Q+f7J DVFE>x,tK*P.]W?Oђ;H.Ej֩FlBenF54CFecZ3FRWKQbtgQ!@FNNWTG/M3gXQO)l{Ĕ4*uWQ) %FUjB&\\l(OKtRXH7@cUO5}BO*gjXV+pGVTTx<"{z@YeT,dTO4Gxu5mNX;)ʨf`yf2*,1 ڕ$U̟ -!4˨J/2:/EDx2gkAoqKJ#eTfw2*3vCcRkT$l1ZhT2/Hs9˘Q(P•3\8 Q* nq'7TɚJhX5BèkZviwUh}'K`T8*)r/EOF^TIW TE:]E/*ژ5 > yEwhݝ>> -ήI{oސ$"YGҩR R` UUQܤ.2.0l=qN坡=>o|bFEA6wO'JyR'3prIbUʔORRQq5FE_E.V17Q/=ϨQKa7{F1EͨLi#pfEPҨR]G]F;8`$u :dX^DE^4|,Wz 6;>4*c˳FUx%|"Q/D ِ=UQyBTR<*pSvjT,E5*4Ra5*6QHFѨ0T|e4*=) -{!9KQ7"ԨnCp zj`YY"ȤfPFΟ -So6&yBbjե)ǷQmGiag֨WCzY>ܿW -WAIܼT(QQ"qzqTL !*0 - ]sQA^I#J>_:vD#}5cvCNW9$BkN}q`sT*W WSuT~Wщ.F5RN= RTʈ0dUDUlj;d͚ozjٝHiY-.׻LFli枣JW+1;2Y04jS|&pRPD*+ (6n"N4bD*Ԧ[Td$,#L{X",,p/Tr7|!q%ܝQ#ZrZ֝tf0+]38Rћcf`+KBZ#ՈI8>Y)F>^YQFğm킱2R5M}  -O@㉡#ՌJ c fMJwR1H꩒kTOx(9vEb7lO*"p w=tADIu_Cͧ'ա^iۦr?T*,~uTYBy'fH:>?QxR]A6=2 :0"yeI>;-k9 O*`,UֺLTݼf`M`ʛɾ =鉉'RTyE'QuזU铪} $';r'U_jBŠT<]LiJŐqӶ J6Y6y(sc5dR%\֤@4J @>J*=UiNJՙXv V@J,qSnB1nCPR (F$%arT&,Ϛ= \\ yOFծwq(ՙls83Rh%o()ե!-jrx]8:T<R*"8Z'7ĤTm5Ihp%y#Q%O2H"fR*1}fmFJ5Q=>nT$TWpgj -dIJrܚ3Q*2/$MQQEgnQ*>R(ɕ@`Rn-R,Z'TNJ7d^J5ʺ璲R ]GK[( Zzh/-wbc(UL;@:J`J7%-`NEwJʺM:& T 3IU!JEOZnK$zRuM ve>{6'HGG2sR ETɪ6>I觓'KQIvXRժ! 8ܢKT0TF4** °E^]c?J*yt/bjL%QԷNhT[g O8e)صVT> V*vө,>V*g`Rt*rHCRG\@TU8+A[J\[.\lunY+̎+Ցƿr}TM pTc(Զ>ŸR՞ SIJxr"$m1W ԾRю[,IUJq^&oTƬ?+\ȯT|$j"LEnˣ]epFkoBMV\,21S.hTGτ bG.gQh ;1% -{ *ʞbdL{廒,XڏY0GSS1ռKw f~é#]i c*pS @MFBc5ikeSp2حKy;{jt:eb0Ql&A+2heWne\ĭK轪b,jEe[EQ-N0{sR+ &-럍n.R^tPáXRe([&sudӽaœaDrz;T*d*|4;>LɻyK2FTOC\#T"CF"*d*eLQB@ޔ塯fdrThQ;3Q,Lap#S1N*5y+*J4dLA`d*PK\uq'S`wܖu -QA@P!#*1IYML:7s_"T{̭2l,{2A1U].ST %E"gCʱGY7`#J&sc xg?:Fd8@J!jV]Sn n a"Nb*,S>FbTiϰAˇ(獍TTCS2\LJ]TʍTj Z T!n[ 7d-骤A o]d*6T3(G :3┩5 -F=ۣ'& }40JO3Սoj:o󱧙Z*l~VR3L%}HL+YIYf4iOMc\cj:f*A+GJ; -{X3Ub ch~6|2MLEo}1L(8&?kbx3v 4S}3j(n8̛T}F^Tz2UpSk(=Llj{8%G2Ux(Y|TTEPo>#j5a]Rifؘܶj+|־a[f)1/fLwԘ SufLe•AɿTkJ ~/2+l[ +S5V:^sP -y--S2%`W<*S(_2uULU*)(2U=ԏ-TkBc AkF0hcC1a*)[t[Ż;v$Lh(NE .L5T|.%"猚4U.|r>%DM%(Կb);T*o׮~' ;d8ل qƝklȼc0ᮕ^S]HBj,zƬMS}#:gSHĵq71[TsQI/ -;/7GZ8>5ճK[^S1pSP||/˩ͤwT7U@ڷš -m_Щ([iqqX:GCKy*%szSa&ЩHy WjT$Iؤp5xwt*cދ`rm?Ò(x0L"Z~-9FQNh k S 0Z"}9U[P&NT2N78u/*W/j-hg*M<;~G%HdJ֩XdEc T|q`\*S~>rSi+>!x^33IW^|*ꨕb|h 4$g >K[TMAUh'KЧ¿ACyĽѧ,yHYͷah9?*ےYaj:\SU"?աO^3Vzq*ݕZo"৪Y -D]%=3Kw<}?gYud2=L}>9RH>UBlnӆ,<%Ow֧RFXUZֵN T *vz%βrc 4"JrC .U$YRQh -]AU-@PeW(Wi9w'~ ,LeI)Zzrj-[!<%1$zU5橔4<_*{^7k kU}A+9jI=HwB"۹QgD)1TMf U),/ UЙKR&Tq{Uo]xPYuz'mqPU FTAUnդӴ;Y.ھ _ 1 -*X/ND#jh̝5TQI~*}# u%*V*f%G#y)UMd#Y'DTj -BdF*}bCU *xpwI$PYsayzᱴ_:CXgqRѡ+QR>>|UTKcD>{?E8T;Ƃ.M,`VD qL){ \aS9fBTeU|t@G+xUO.q^JmUSD~:PNxd .1rQub<ҢjEh!DUxQ5;z Ub t*G7J<63/Ugk`*~(rEQK%lhD&;jı%MpNeEoOT&*%.WĠxz~RrAFTg9յ3"4brd4=RGV w*2ܯs( DU$Nxgl ;W.?KƩt֤YQ|* \wnU9*%)wMXEeNYU: ydx"Rt>Lr[+jAj!)&P lb+o+* - ;DTCyQWgԸvU}%Oy-;Q5ftI5*2e%>p<\.heؘ"43IKHdJ\R)%%NN%TU oSuFIWBKLPyT/"HÌΛ$9 *їD[4ǹ#$Gr)REjvdΖ6VHh\[DG?ƀb[HkI^<Qłxy.Қ*^؋)2JƑG} -bOe8ة))+6/.jbQ5P t3QU EUR H U>b|PH 'pv@5>VÞJ7;gLTYK@ KRѶߛTA+95 -e7_3ݰU`tV*kAVTH85:waQvUO4 UXt1] *d1Y`Ig -SШbBzUdc>GԦ?mTVU# -Jf0WU]Za㨲:unIy>hS2QEB" TxLKR)^l!} Ȩi(RؙĩqucTyɴ 354OFږ[ji)?%:qk(/5C :)H -{b3QEvZDa -JQlnGU#.AcgUUH Rԉ d!ULVJZT"@bGYE,ݹŷaTq{bcnݨL-gDӨޑOfT1Xōʨ6^QѕVDPبʟh *T4*JdThUf9Ba/5ny*9pmT c,i2UڔFU%8;!5&ɇ!*#Xӹ=PzẻHoPBVWwHaԨbԨu9SFW) jTluP*@hA&/:[<ەKU2[s5ٿMvpT\>'i3R?`U% ʣ8ŧR(`n S9?L=odQbsSq+7v'5ޚ -rnX4K*%u>PfAAԴ9OTӅ_M{Gj;jPņ!Peb gm&ː%r>$*,",L 0 U+cRBUwNhTƓʼQhаP%Sf>*O^wB/.,'B@z}FnEUk *_0̿0 UWT) L/4`&5%BU+y -%TQ -2kُP ]DR;[fپ -PElYt{G& -ЊrB;d\ܰv)"LGZU.qjPM*pkOv뻶$?θDb:%VD%9Ge*uܩ >Y{y{H-v)]z6x(&8w}vtuN2%`0 T=Y-:~_qi&8[OwhrXJ傕yɍIhv=)k -'YZ˽S!;<(C/azR'Vʜ}DOrirY \ ͷAxiaѶGҰoSV!4 xi*FԴzH)1L"^Pv_$f*/MBCտb,!yf^mp}f +˜g&Ѭrw `{B4Ua(|"09 !@9URlk[H2ɺ?iQBpg ʖ=nZC)6mrP{E -m6jM_X` 70U%!+/%ybʳVKCQ#n{_0<-j~@Nkb+!MQ[`FY:p"ʫs p'~{11ml -[ZCx>J>4qP)5xen ՉQpnfϒ.[}}oZiSرb3g_>p1 FV>3qr5X{,ğvX*:|‡_X+1VP,Z}x_'{PYRXpu]uPA9@sLj9n -c@pY- -D -(&B^#+$X#{UdBfG^Z^.Иmw)؄0gV?rvLxYssn4Gg+"UgI hEQmk8 ^[y35:ɹjbA -2 2_ʀch^ш0ߖ-ym*'1F7cLuve9J+}7jxVGsw@%x ,pd+V[!Q/0&+}&R%3Peُ![n+=1^V.n|h&ܶ,z{EOʯ1$^uUǴtq):3Rs++N -C?|!BԉX -E. V| a$K k/)pIxq;6.\_4_tEQŜ0ґK)?>B2 T=m8 !D-ܬB?z29)G8"Kt"'$ |ǫIWR9#!a"!'2,qxOٮ!VLLDl!Ab8"kMlD&"B= l -X6d}")&gQys C W(}bsIJ yaĈ!ZV ōfѼd!y##e;AFB4fiHJavʧv_ʦY1Mf|o\&:t&80BC'/ V!DhJ1WhX1>+ jgWKSHu]{(/gkSFD`/ڡd1sABˆ<1@_PC8{{C8?/0P"B e e(bJ;IP\P >:A.[3;p*VXqmE )zCP|'qe30=JXuWl(6gQ5(4᣸t6M(|{s$vX(4YhR($Ք|C?XnOO'i^ 2#CbR-|3"HG 7 Kib3-eobf%!(=Acj OCXagbNy-)ax|j)¾ Q\ 82q}np0 : r2O;_M#|Qk|zqbC4̲((<ƍ$K~B#,5_ӸJC}?<{οpL`9TzV!Щr %0V zaixrSB.IM#A4}7+{*xTSTB&1Dlv[!<fyıwemB4 - #;!-R QxڴE Mn]]p$qSp``0xe$f  -BZ!$qIUή`pAɏLQ3^4!ɼOn# ŒE/R5r\ޙw)ԧ+FBUu$  E`:tWẩ#޽Bӯ\ -52mpDmdy4)4OP[1yGQ -W!w0C[x24\Pa4 R7i;0'Q1;p>&,ScQ-膫hրPŅ#dtee-SF .WGez\tʚE .,t|36_I*(,-4)7@JnW. -sU"eEÙfNg@Gaߌ p%:"7RfvIch Ц>s\?o(IdpAAvK?f+b*)¶5X>Sl;5Jɓ(Vmc?bd\?*y9ׁ (X2(VMpNW轀ZPE\ʴ -LN`bsk>"12H ~gL.X[%$\ĊZ)S!U%"?l05'~UA _Ȫ^ڝ>]p^b3z+\.k1maЋ$ZQa dZ#6nVF_ʈKGb߀.RhGf_.1szޕpIJSn\8e .S.{\bɛHT"G)D޿f#T躩~dL&F&|.1xLv-ǔDP\%73.,\_Pcr^˄@6 .`]ZQPѕecpTTXZj@[,\p!C(̑ -ne{2%D .ʗ7eq4>1u -%ȬA8)G*D "&SHܩZw8Kvi:G*P nռ\`ySq>S -h:^@1 s6q"Gs?C=jTF5>p3x?!=pz\&0`".0剩`3rayG\EGNŭ$z7TH{o;prVoU\c)*GQt'\@$GGA7(ɍ |b{eZTpP *@N.ib~q 0I3Z -\IFgTЊo5FVaN#dllu5)oq{5*v8o.nd.BS7\ֳQATzn$89.=Pqn6*t8UKLu! D\,2Fŧ5QLȤU E-ب y^|R p -@] \,ĺ g.PNXPs1q!t {ڨ`[=] \v]POnTSm{%pѧG (ۃ`pE'(*9 !pޣN7*h.Hq&W-p١m!%*{{-q'k;7p9=|tH1M+/p1$kP*pU "\PC1Bɗ`"[.>UBOr:&|J ~.Rp֊6pad#KrXi:Trひ)-\YBRZ5Y\9 \p`KV~sLa,.j1z$6<]Y]4Q\8EF>v"`g@& - 8ŨŲ,<, *R~~4W .*;DNі ع\8b;#FT r/pM›ŵ#,X|K߅];A\mn/!-h'^&":t:(TTFc("\#\^t 0\P`h}qB\0ur#Ȏ-X]vV[뀅 IJߪc+U Zu48Hc\xkS|FFU .s|{@( ˇ\')&A@N|mr"1(p j":e`n)^>%761J>p1,72# !wN;c; V?C&G|bOV1$.3'\RŚ $sɋ/4j /E\Pxȳ .DLRauag#hmUڮ7"c]U#Lpq - .vЏPb} ` bM`β k$EFw UEx(IVRt8籠@p!DDܛа sgԄ=]"r?jLpjl:2ڴF!PFM$98fq=M .Hy|HVP>̳(zUs5!Y#>ƨ5;;h|c ;p1:}sHrQ7.%nAm5?.N5tɑ6sI|8pgP8bVю2p=5.9\k<<Z<|Zn,AK.G3g)=jjC7LCqܓ2pAݝea>hrnЕ#.^tY֕qDM@A#@) ƞ2?uWԄ 2-c$2U`".ě $gA^y0' q\ԄR3y.,<6OԄ"QzWAMPxďE<=&-&ZpKS^šrIz -cP,3DM]m QFMq>\b Q:$9oNgȯEo!8 - Z1;= {prdti ӿEn ٚq|K[dn^&g=[|o 䣕a;/;W8įЄhV>zg±Ŵ)<ʟb@Pv{``i$=sBH_ (b7FWcwoZe!KQa;F{ b `'}I#"lSa\4 x? -M('N]!sG_œ,;i>Be(p |k쵫 {@H,^(DwN \U2L.BLo`6H@X=`PnB -\HBJ//%t^h /%c0(|.h)\> ܴK:4^KpBpS.NZ!%oÞI\5ڏcI 0HOEX \9.4s\\o=wn\ԝ#0 !H$ Ռy.>b\d5}۴7"&_t˓\FYp6  \ލ\¤H=0ȳ4,\נ[K9j.*AA'}MQ p"B֠yl Ӹ\x*ER۞KH <򅱢0~KHMPQ^՝.Xo~.aqղ œ橷md~:HZ`n.^x-.dRFlm.InSҳ%hZiҩ\<r߮, U34\t5581ݍy& rJ6\:n r.AWI-w. -'¸AX@.}s%\BcR2Z.ߣ-4p vɗDn.] "0p_@HՒ+x{\:~Z/,':)RL ؗ.Z\dJUMJ,@bp:8Pс} -lK!O%0(`Ǩy^\,|[Dp#E&=pń|g:38A61O(Z(LgCҧS].Cj@i/'cV'ppiG>,tP.VOe-"i@ٳ7e \X{S xSد -uXpEI-!C+)3fr:msVDEW._8,\aYk=rBl<:J0fpx;K~r" -']FK+a߲'${xKzvGK d[ MG ..Wucpl˦J#>m"h<1Zqϲ\nM+"d1Ia/5ʹPlW-Ws/%%,>dj _ \TpB+(F|Q_zB53/Aݮ{"Į+wB٦A4FK0E\f\`-AFh#.UND-XƘ-X[GKPJ3-!&GK_wB3;p%$Cq7 p%b>$UNX E5]B@0Q'pA8 ٗXrzJi#: -Um.y@, +&h,zLJ+YzX y -2VZF.Kc%֛9YvC#ԉ[_ʓ>"ؿE;Ų\ -ݸ2o! -'%-;@FQX wɸl[xIFEP[wwE^B%ܞ) `]8y)PDSarrJX"Fƕ bQ~wF>0'3SoqHun唠Vo&zuV锐KCa+tS,B {(/~!\_-Oũ ][).d`>hVW52NLY!rJh{|I(\.nq;ɳgn`޾C7 RBA) -8 UYE{噧 m0!&\. y/q.t&P6\x_Ώ[iqFiso+Ex6 0FQfo7;kP_e#pE[_cqKb!rmL34ҺXPglf%PFX#.8ys\NLO_Š=F[i7I>VUu[& F -jFcD/3ߋ=!xTExOP FzmA8){ԻOIE0BQ<.UF nho`* - -g$q# -9l)a|+7f.*2q~l3^#7HpOSk5.ΔpѣL0e.[AYѷ"| OWt7{LV--'n E蕒wq3F8H.ͤVR h̙"e~"|As4;=-/l"t~Bg߂ܒr[ n--M*=-SM&YvxoQE1)߷XYp mB,5]-` -T\J%k߂n} q}P3UҖHOۂClѓ} bӚŖW(ЎAPYj@qQC~ j9\}tFPm+39)rE,DxYEiZP\햽_M-,dE6%j[EQ ? Pi[\l=P:QCo ]K-k>7Ԅ4߂2y|RR& -X(G!:(2-VGXol?TkgMѷ`R_Xӷ+tǑu18;[2 з04M{UkH\J oAs D,T6z9T$C-ԎeDn RC]q֕ kș'7K -BY>PMAPռ8ҷH̠ -yҷ/0C9- #@}{t*z0,e} ,]׈Oa4B%JUS,aiDZVO}aF2ӷ|:~]ZnRzgMh v54wio8@RzܾE >9\%Rd7Ln-7̆T} cǀ=*B]y kK% -7(nG!E*uWDxx{nvD- (+@7C" ƻi{*We|n%}0FU&~b'+`-fk'K-n"-¤}XoPxH$ITWbxYaŸD+"MloKpdoA1oVx" E -x -E793ϕ8MVo2]=r4z4'CLoC/y-u#^ns5;ߢB GyNBxFF yN>w -KՌp6.KL(APj$ VxʕQJ)a8$TQ@3y\\gPOs8đσxkϺyAm:!=Jr%L:s#%ܔ6=Ђ!>Qo*˱=8)6Rtd>V.}4-"w V`Oh"Y@vuż{Aix`Z[2+07GHMٴ<_NMƿL -<-:*pqRrm6}"2/աI@wK`A (4-^f?Vw癦-^S"cQ-@oM+gZIbPJj"asxգ\-tP_̷򫪷3E aV03n`to 7E="&mA;c Y A*54t-`ZagyLD0bM{K $--1Z)ΰSۯ>EDB>ۛ¤M  -' ܄IR2d -Ψ |S`5Eq -Sjx2'/),Y0LaȦ]!@|  oxa(8L'av&waVYQ ͉v$v)Hob@1_I>S,QSi -./+1#cX36H1\]7& oT|c"4_N:kc=9G#) !݉,{!RH -d"Kv3i -7d5E-yp+85E7i~W]*u̝̇b~ewHdWfVMW})LP-QG.SlboT)Y.Lf٭hDRLaa)fVLq0f!hi: .}3(apv -Y`DI(^;x&_γƮg<|p1DIg " -00Ec,jس L<3ޙQSXg.zg #<0E祝qy3wex/cNh0Lg%ma;#a -R)6>rH2,RK[ ->S3/Bf~fRlP)XG)IѩI2¬8"傐\? -C7Ţ(q6h5d`:3BcEu[+Ԋ) -& ->+%Q\9 A$P\=ڡPCȆh ~P(>dp`&-1idAgoəFL?Ӂ@pjL;@!XiO 09~"O}?ڠOڏO'?'B|@W@ ޒ4;!b.(~fZw hع6쇝P4։ގe@Չ{ r:!/:!9̉D!'&@`É628ao7xA&M4C  @ l55} q9p~>r& 446A#&:8hMhDB"譡>4D=4f"ehN੄s62‚ T S F%lM 4,hҔ(ԃ\G.gID]MJt9F#$hNӣqmgJiP\Z/EdHKWg2%UˮuBnmJ5.H~Ӥ Hx#Og$?f. J.D;j_Ԥ!/5C )z8AWABT;KxD|$VI5:GHYm## W- x.AƭbGPv:b_mtX۞#xI:rpf2@Қ<8xmA.Í}6B]FMXIfהiD[x͇Ftk3O,33a(u/ޅBH@l`bS Fdl@ -v.(7ٶ- "xEhHQfekZѳ"nMQa q^D`H?xPHX'Blz69MU6 I0ٮ$ XFD[mXms!i`n {R![m&BD&!6#XhmmyEly] Cd!ڿ A M}Œ M_-}nF7lnmn7+6n&71o!0do5noPMo(MP,^ߘ4!:߂oRs PsCH^_!&W q7f]oZtCi]+ L=GsCTb.+8܃s.N9cnnC ' !&}$ +MMC$:Cdp_b1~:ܞ B,g!z^!ݝQB);sLՔABNz! D>ʃb6:ځ'ї>AH?:!.u.I>\Bpnp|9 HG: "^ށ-A]{A߅'\YuztEqİإ!" 8_gwKZƅE#]9^*nq䂜n//rRs/M\˟_H9PTa.y6mR>^! / d;zA$rzkڙ9 bV4'c5is͉_K^UϬuN,:DSןq θdzT -;Ox/}A6sdQ9Islf_}扞fi݁fEΤ Z%@WD|12Х-z1"N$ r P B9?3-֣$"b@Vq@e9 Av e[tICP_sA}݊>grZOG/9X 9dw 9ۊs8Ė]9ne\"1ī%T s9ԙs!Հ.e@t1:ѝOC 8]d?`ˋ?6ΆYݕ CMBhv:{}?4D"u,뇾~:NCcա}C~~.Qg~U_A0!(WW|ʲ|`| GJF|>([%+|(Deit=4{Ppuar؃Szaz&/'I GN֕qz=`a!aL7<_ɃCS[]pƃ*(*ʇxw:'t` XGxQQC> ^3lQ5߁Ui+{?~l,6CAC5BS.:!!Cc ;sYeݬ\N&St}~g./::dѻ38⥃2ؓ¤ꦣCq" u\lk}u,> (!oA ۽y$YlϻnXbn rC0 y[6l!kp!Iի2۫R*Jmu\6kݼ٠[BRxݔ!&0]Pu./z';7a>o 9 `5Щډ׎jh,ۙT mm;PRhtۭ wOL5TOCڍ8 \xdwuf3KF~ћw6띡4$Ǔ] 7R4Dch`PY <>pgIa l [hgڃ 9t͐H³moJ3P4xw̰ݎV ލ /XS|'<|2 <%)<(<̓\3iCOQ5xX"#;INE!t9 +y ngx4#ae`nMW&Z<0$<^籼DcC2:1slbXy2c(1C>z "^q6 [Q竛3x/CW[ VξeMR{ޯnuA&os/P2XT{d`$4i|eaϷ>;=|o_"u'"Ǖ`>;i.g9߲@ξ Czu0} ehNBΆØ@h1`fN9Ӕ!#Z+{2,}[MQw2,&j%P# }5(ӢFjo7WurOiC?+1cL)p X@\c !wz13~n*(ѾhҾ@HNC 'W0ax" S SPZ e*@lLqaќ -! -?;ژ -9WjNn_(EfQg_+ -l| 3(پ-l|@a*+=K.xkЖ -0TB-P!s%TԾInPT/>6Z.=dMB, ('`oSyĐP̠ ta!T#P!]boΫ\ -5kp_U5C -_n?DO(TWi9JbgЈ8c_ -оpP[h}ϼC7pOӪBJ~ -y<w QB-\p -5)x)# -Ģw.B!:z'H?=y~jM}BN-h&|" pd8@־>NCov¥:i rqN&oй'lk.>p5c| & cT#>cb0%lyUF}K h^o m߬,!@6V+TRn#ړ/'A&& \$I8Hi~HHp"A|oŐ$p)q}c0׎`pF6Bwkiђ'FlT1A}r.B}CTTs"PTU"\I+E 1I!_Ev -R[dy 3">pSqrE[]Mc(x'U'S>NMLXG(Vjpa76DD܇p& A oy_C |CA};>>n&BާC 96oqqg!FC(CϿw_ڢGpD%iy"m۠\ {[ ![b@Bm5OOc AG}S<7II--558džrbb0.BR!8BG1 AJ싛R C{d#j'    xwPk'J?}J~༄^OvyVj|ߚ|L|&>~ vw$k􀛠~ ~*/9ܻ7\DQЦ -?\~LG~l TƶjocЖ#,J&"TUް(o d92w[ô:h㤏n z~cʓcYkG] W1̚Gw?zNF0c?Ẏ`պUaPמJ5,1h  bfF'ZR!C*bm่A9 ɯ%M~O%?Ɓ+3]4PͰSF $M/Ќ-yD$?Jt(%?AvL&?@@II O~ yCL ҤS   B | 2'0{k@)} dXO%ɫKOM(^ ?0jju]w/*$V>34p%p gNW~,O S~#JH].sAWG )p߂ [`U~(iA'-_0gb ̳`Z\3 h_ ?dcA ~oaXuaAn ,h_+h1[A{'B/)ʏ -*oVAPUA~ -U0 wT `B*JG*Ts$\&n -t+Sr)S~sJ?%*$f `|@`&QK -4P@'f~{2@^ϋb`@ 4'8 Np_6؈M`3+:3+Ho0U\Zc~@)A P#=J9J$A?7m!T G`G i2##"E@֊tXU7!r#*GP![' ?Z]TTo'|HLMP`0Dj Ch@wB }'}I>`\^z<0y`֖y )!u@M^Zȧ/!rz\ -fq~h<6Z~c(M$ 3̀\)J>-K,cBi|^b[~xIq_ -p -oџp t\ypO˯[@-d.b - H -ХV`+`hGg{QI{ -_S\~;K=8i*R }7G -f0?%L_Rl|n\~$I0t% -0 ]~3lp;g~0$^~.eZ3?bF' t` -4ԓ Ǐ(6.'RrBB;|d?>KxXO;Bp J'~z:^ג-?jﬤI^Xx$*NX2#A'qp -2CV<C-P]W(f M6@NW)hҖ2ʬ%G`ֆe`zX5]z~ښ-I.0ݻ"A dE~( R36ȳ]3VٷaHї@v9t}2=K IJ Jw{BBNhc@ud&HvC@Y X8nƽGtQ ޜ."ig }'"OR 4HRȅjLԛLF?7Yz@,smFA/Kq$rg@NF Q:hN5-_ʔBQpĴkjHv!-lTS}CxԾNz:)MoثX_4Yc܀pqQ+3OƸ^.r G ` Wⵈ6ioJN%ĚBf[Twtfi('H9M #!V؀p\`jH뻂k~xI,0^!`]ؕK1y'xE;uXsQ%  1]luIFYy|@D} J\]^TbA+`uD. -t1D8n# D| ԝ4PbO@x}l"eto\s{R=`jy' i(gFu:a2=-R95ҽKxM+# "t9uly:HWJ D>qt!L "@\D~ `z͔]WmR<{$sR@ pK}?@5 PKTDh&Lp5)XIޚ<;d=@|Jl1]h:V*sA-=?|!۶PzapLԓ~5{.9.MnYͿ 3$[AIyD$xfggXJd0-uϠ:(_ّte`^e]> 4À }YX(wuW mP.@bH)dGYkHWtjᓵ`On`Z:'Q3BV:")}f6.^cG @FEďAU\L$\˔`!ޛE2 i, hXsE ?-pPh{QVա2C6̍9la1C+@`r^eg_7ҍUa|&S @%LYDK=Y~Fi"D4j@.yhuGa H!>[p dfuI /ɕ[&v -K w3.B>hoIL2o%Ubܰ5f+$47ѷb]b\ڏDb~)ܝwga|]tҜK3Zݾݕ_cery>{徒o5iގu|zG47#u<82w!izfꅴV6֬e!.G!]%UyVvE}|KtRu1ZJ]J3IM:*KJE:Ɗmfj3'`ӟeNmV+vS7IȩakX3a flJ$VH mcrXvD# ]WӞZw~7G{i+7q**P!Mt)+%Gj 6džb(,g2tYg.h(20ewbR?CUtFNO5d8aR]0z(j̀ R"W*J1:Fmj BG`p9Y3 G5. ٢U!IrE$ taH@pa(= @05  -ZկHT$W<܏Eg [5$wf[.e2)C)ަ[jƆx!?Ҽy'*&"LN)7sƼMGiNSޙI>gT3YvsdzV:qT\K#v#ctF.#SuF4owdw~gH+kǻo~siHSvmLd|>stream -)| 9XTqse3 B2"^zQ,X8p0/>(jĬt%\p0DkVvq"ĢwgBڜ|#U9yxӅ1)W/"_MHH܆48Q΂hQ7ߕ9vDVa5N2b.6v 1lU)Tx( LVJ ^2?=QWPsnS 9Hm ku>_5eAIvBƜwc>kOяvW?}3 -v>N7^?V̌Ӆ#xĢPPg g.LG9 ]ULC.uVG&yc~AvGh4fkT9XF_" #4QFY%!Qq.>Qf+T*J(\QtPKu3F7!JTPIHPVtt6w9֘\_박%1k -jԚLm.HTXEUo]/֨^ۺ`u4GٻRRMzU-Sm5?Bǘcsn,T(QUwӈ˅5䚜q@PH -0$98yW8$ -4jX [a}edgFsw$ɔi@1`6G|y|ąTMu3 wH ]-PL¨^>)ogw+,K0d4  净kxշwk̺xk2fciV0OK|#5xT-0Cur}mF_l1hҩ|+&w23BE)Nt V -t"qv08(n!F,gq*OFWnLdv;#?M}YP⿰c#8v]>:D?D: -=n I'̧CB`d pǴ`Nn_{Ŕs~/QD7Ô䲎A@Yz(( zQpC7"|Px攉l>:$){)j#Hn\jaA&O v{<iyjg15dG."fvi8,j+Y(rWMlooЈT*OVkz;.r'uZ%Rlq\] "s36Eޢ7ѣY)"^c-N3n uWo:وqYˮcpk Y=5 6I!A@&|]hLc :ZҰ%h>MM -'xh+1I+ޝjp G -W#H$Lx 0~Z]0?0k0Cj1Z_Z|v| -lOwⶖTNcCvs/4UT3TZ=az.p.qJ"Lc+ ?]FQs_fFB6^[.ded'IE4;MBOdJ:Y r 4,yW'b#;6zeUsERǖp-=]iM\b|!5e,rs(n=y;!E'Bž*54p&3p0<+UcUp5pT+l? 6.57W̬q*quic=I68@LvwY&!y5ATswhc,b`- P 9pP$nn)i(p)q]u iDbGa~t22hjյʪ+F! V=FZ gكڃҁũ2YIA4T|{ȣ, 0Y[*)n%z(L>8n'mVu~_2Gs>!% -$Q`1iɰ&^oN,2!ץȪuZTȑ=Ek)u߰"ٺb*lG֝ -(L1*S;Zs>.=uzM 9 V`' - CT#mf` G(z>OSͺt &9}z)\p|OTIuƘ ɅR@nQ U(Mo{QkY!N3{fq3>X#<.Vig `ќu_~5ʝZ,ͺȣbDjC7j@2h#ݪ"ܶqyZ۠ Q"n4&B>v+҇'Zm,ț 9ua"kGBzу^D6^^g! -i[XX ~54a ,F&k]UBK6إ~pʬ1*^j8e„{[bg͒<#uSWДm60K3FHMP_]M{}%OA|J_FBlc;YB  = ~;:dա`f:"3m89$ i2܇I.ig(l[ٖtAA) &Wi*̘x^$ -&dA -M -!IBCϗz`(uq<L9!%{v>> `Нd|!Y*.bx@&2vip { f8,sųEsw"*ԿEf+:ۦ(Ze.QjPw1H՘-؉K7@f$:)|6i`m:t,GKHCL>0&"oM8u1/JjH\y\hO.0RO%@ vBQEŘU_Mh -2f}xWnсmiB04ia7s]%N8pv2. lEHՋ_xj[qVr_GW>1dE~n;^H)k[TKa 5c6HFcvJ-̪:)-Eq𘌵6ׇ&Ge-?פ)#^(*k%ps4K#HK1v:Cps!bTI6i|#v ,3^o2ܝXWOa2&DU6*fp0]LJgs|^6ZD+=RJ[ܠ_gzW0zXĦ^pjE$~=DDd̐>&Jl˲ -I4#\~e,`?AJOo{c9l&e~`eǙʂ,aayHt8ΔC[Kcd>}(ڜ?a~lkNJõIe$}HSlJ0O9eݵtm+[Dz~7ɠ)ȡop(%^=.Lt>4$`"# a8pk=(ܱSh NlZb0O聂?*sp擐ɸָ Z䝪PF멧0]R\Ӊ GSXuT !? %74hSYQfC)pލY곤Ic;m6sbCʡzQx. v] bBtT ^GQtCZ~4.h)x^jRLD//㼷9.IfL$fwR. 9Xp6_!Ʈ&?7)7>4ЛrU@)qڣ(xɾPҀ*\eKdU8rlD_Bw8]W_ŘTe|hg[*d4k -"c їi|2YpNrw&'xKivx*Xq64N#ϽܗE˛ﵙ0ǒKՌe$ӻG$6ɺq7^x"%̛^aZn#UDQUp0>=jAżXxD%"']{lViYɓTBLR;Ґ&]@ q-Cǰ@ u\&u{!/j\%<ԏجO6 yYG%AwҥnF.ATDw b2%hg?vCT|{hY䞼'~wڽ =f v!Fӝ`uvYAɽ]94{D[^ԥq%'\` ؄{+(Ú!XOTH띡 Uˁa0p0ױܯҪ}b[awV?`G\\DU |_烟!8EZ?Yh<$[XOI1 \`P<6PW(>e"yϿ8; v 주 '.# 69O L0Nw>L02}M\u"Aa\ゥ 4@fZ{_81Lo ;UjrZ2PŅH5 +73Lb0:q1upG|kGF&aa 4KGqq"0~=jlf0A|NqaծN-ð8  0/`I D05jk5k;]Jqֻ₭[*cAwVF5lL5 l0xdžLm/Y\|uԷZ\PiFZD&+x0bMbV0.||=*–f/Q!囧q]3.Jxa8YÒ\bͰg D3`ޠ i\|͸(Ś ;44.01'`tahOa.ۆXjXv7*0QMa2'~x bbPaİ;$[%L^<1Ob8ŀmkz8r/[c׸dظA[lLn Нce&3<]y ۜV֙jL h;k |2#<ƔkdX!r$C%˴f@2xL'd Pqy2EZT,ƅ6 Ps,P -zYYFo.k ntKLp -V,ł> љÌiBznq\fכ38S.9GTN k:#o\T:+wFw3yOϘ{m[`gu?q\!Z q9+Rtl4D`@ @6.J?+ɹq9}5%B\ڡ3;-xq[/g,}6潱荋1@zZHq*h$tʸp\4f'49h B" =" мtBh+4Dhv?a0hK*}EɠKB$#z ; -ZFCd{YZ: SΊ WZ/4e/Юq|B{7}5 My*<2اhAj\ȏ P>$eh1uO2U4ʍhsh oF{z"B}2f` I-v58' mD.3n\2 -5!іŽVLDN3e ) B\ ;4qN݌ldh)۸(nƅ)Cͼظ:FZ"P!qchOOz] ^ +9{*ha@  -ZeN񳡑-cĸHq!Y3 -yxx>I-.F[ukBCъZhŅ.  - ,EA}\\ũ l?4\\6 -4~h`Q)Z4KFPmh=4HH4sVF~iy L+MM9͍v044bEQQC_\5jTUVZM۹/W+AX=coRYS85k@!1.d5޶{9[ 3Hؾb\ۡ,RkZ&DqъGܿCḿOظov`\987oo؋ mBdBЀu ?p8 -(e N}0~(.C8'E5nT. 5á};W Bip ~msMHT;Rܬݯ7{+#蝢OܶX\;q8xŅoqaΚ)x8wǭꋋ..W\)|^qSYp]\ oNqo)nŋ $ħ8c\Դ8dnq>)8/ӆZTř?yfиǍǸ@p_ Cxb$A3 DH'C݈'Z }Iα\1[\㩋TX\ttJಠF3e!VSP瑷 X\"cu\\ )=Yjť/~NƅQ'A_Z[gqn8Ŋ -zi) -*rrʹcrcrɉ^` Yuśn0[3[\$fqq+."{89"s֝[< v :amW#Apny<XˡK.p{Nչ.eWrYtڢsR^tb KtHDŸ MՈnFDwc֥0%T谊 +ކb`LRZ%At&(s ]nRW-ʃF%"̈Jq1Sdv@ 9"*."9sp@+.s:!tia2t} (+4NJW@g&ӯ#R\tB/Թ1Gݸ/uT?uh=V7VWyX7\, s 0XBSLbG- ZM"!cPw!②U:ueqq-.[̳O8E6ߺ:S2)nPuͳ/%vA Kx"QDq(j"I\0A,!V5e"'%:!.&#=ąŜ^G:C{p3fEzϹ`A\(pgҺ+`RຎҘEGiB`pvpٺ"^7u uRu=.Lp:\b\wpRԁֿ=\uLcB:,y((X^W;ŜO#vd;Ϲs>\ T<uڍnrpǝ,w Ϊ8\OwҘ.o!@l땸3KL\Ȗ{{GZn3ס@^b4x <6i~ o<<0xdA{s6X dL]lp҉`o rݏPxKZ (^Gwx#nt5#ӗnOXn<;\䥍cGXk塠PRg/OG¨n}k DrBz;oTEVSS`(z7VEMƧw6#x-sW E 5pMM\ޕ{(Mtp[O5ComfrC=4 OZꥃˣF:|d} _Bk''G>-e>8N>b$}8 o79qG}3'|@Y6.8m?h߽-4T#ۧ][H[<#*V"6{#l'Go16? 4O#}:DiW@}!zF ޫoqap3FUO{>}d!}= ܇c2[[|oo!VhzK*-,}.l-$/Τ`_XcpnDo68 u - 8v.{?|S hzP/tj)?u"6o9pt;ś}s>,Aȴ}\ն$@&2ʷmm,l8CU ݔdh>gho\l#x>ܐWzb mZ"^y" WOg4cpMFlɱĵOp}&18C\epkUe\;k7C8\y iJ8p!^w.\0E8܃NjTg?> v/T bӎEڵOKb#C^<V}?VQ}DkipN2?}O"xCdP2CK^Xd.\\G -_}Ņi_Ht:t\(VFxO .h(>TC5Wr\ a?J|bA &{+%>ﭼ!U5M .d%}q L .\/Ĉ kB1H^ rS+|%oSop> \Th-'y_ }E.󼯘}~4)sh \xxCettO5wᄋtﻆ}Š}չaJ[+$}{_G|>}I)QG'=.|}X.YB2n.X(||8" \݁uˇdW\TXp E\4ǮϬb^|_r"Fgjڮn.&Kp4=Bt&Vpa\$~?k_0?'ĂKUc'%%5Ebc\d |Er3 Y'Hnbџ ~-\\ScG -.v,{cB'XҮB .Dw8!pȃO=t߱.b*HV\dOx~` ~8D;?Yq >6pV~;\\x" -%r!o G#TaK=E. -~ZJg?mnh"./p2|C6ttgX\ts~.7̇) N/]4>& or)~J\ DERp8 `s{Qjŀ.&pac?.d@&/1p᛫PH.S~-/eD/~Џ-1p6쿉{. \ .,d_ɏic_’ \dڬ8p!.-xy8$bN cVsBخ܅i<Zp`v3Ǘ*I5Y \P*?or;/-؉JyDZLC͟ ]WIP;Cbp)iI p7CXV~\B (nyJ̪9OpoS~vuq[7N*n -\H -R'@:/'Go[-"P *j{k\䀘 R(\HPQnƐ.͓}x@9Nۦ3;V̯($꿅-<*bZd/37N躜OE ~F0 2d~$YٷˮoC";5D0?o} !Ȁ>dDbsͷ%S #[d%?و4 -kU.o-:u-׷PLD9o!`e%|\o>[Ǿ9ˏ $N)(>oCZjf(g[`~`Mݾ淨!-yg!b |EjYW[q *'[\=p.w vFT[- -> ^~OֶE#_g[ sE`6F7R.?[ ISgvb "%4^~ Gu%^~jEMݗAtD!W<-0\\  [oų{[hrF|!K6x<փW -b߂qq#sim-B2`u2&m --OR]A-x>we߂mX^B -oE8*isM+YX({-Ty (CV Scd.exm"BP[*)"BdP御(X"M{;-֤A2p"+$ -oi0'MBWSeB;#Jҿ)t -zZb-xOim ւ :烗Ex /]R -|vT- 2~cnL`YXrr1^<)XػS_2[-ecsPf-BXi( [L„vd`% ёTvz􁦖oQeWx؉3-5ɅJ2̿v\#f"C˙(oQ+)l$Z˼"'aj7[RIRڷ迅 >ѦmL jV \ -o6\G߅Of{"^Na8ñ0BnpD(i3 E>hSZR,E2v}z>}(WEjV0CZ |' -׋ P"_;ŠmX^85f*GQ"b]wr` J3.X]C*`pHE 7 ]a1 m3z nҐ%0 *O -p!2{Urܒbe -+iP p"qyb)nMW1bp_*ZCT,D׃. -BT~!ro/MjV"&#"?GT #/_`j9"n[R #K\r$s\{ձU<6rF sZr\_t6fW,-^a&$a%g 9za&.x;hCdu׹_Ҕ sO/A_(iWBH0p1r.揦|2oEjj\]6-ܘ$/e(\zڸȞWp |aF\Ei+ZZ`ed#ll bJ'ds1 !srG`~d WBGCMX\I"*lD5| .Br$P\KCN\ h]\ye ~"5+Wh;҅Dv<~H.S&Su~Wtaf|uI*|BZw#^taZ [c]*%XɉsI4Z#.h|xW`@tCC28>A dzӘ,ի$1F'H.K -.8BBV=B4\;Wpa --Ȗ -.]%Q̥ (ǽi\={&@. )>3B@ ӧWKp\BUD."/쾩t'Yګ؂9xYt$LL .pЦb vgqȶD~JZʛ .a#8}\eE:5OL+߳/]Z[\˺YVV&atGV"Kt m!Otar:~Ay .7bg 3”˄}B[I;/#:">lwA:H&\@SIL@9q"0P\ .م5m7)OjTHcNvli\I 2v4oZ7S\p7nNhL76K<đ`Q pO>.T -F7E%X^ҦpO)T >2\&hLX;Ļ.ceD"?[`W#@Q7tYƴWS3M, QSKVͤNW>"nϢYpA;~ݸa,oD0z#-5wzA\,_7cx 93 bpW0,+1=!ǎzcpK*y -Oc²_qyjl,ߵ'-\vjlyejڼ_)JƢΨjrzE^5rPN+90jךx x7y^l )`p?ʃ3/7U>bp!dnfYM4x0`@Ί?P,M;[ Ze [cp +5 Ȏ`g`#[bp\dpR+ \p8BGZFQʻB*W*83W -P_!?G%mZB> -ԫ n=k)!I+KLH Ń^$GɊV k}N*fMn:`VA3 VXKbC )T).1XʞT[$4rE6LZ#:1X.f$}& sS]%9ޖrUF -F"x|jxԪyU(Fr3'"G !+$JoVT{D#lujqY /xF~~D]H8LZ.!szyu>':JZ1IN3'=i1fP?.XzȜ@^=SN2< t*D<{=~"]ƕ",RʿE-c*"Q n_y c̺!\2"E0QnnVH'Y%"B שEx ^ܵ'ŏ%)\iX"1 Kp -RK̒Ŀ]H'ӠB-?=KR"x^,O*BͿokph5U2eP mN]!\rSӫ^5MϾ[Dy -ǏͮHq -_^: -ӿVvnWϼ?nN`f@y kNu%!:2h)RM{E$x ixM O@+QB"nc.ӸJ2(I1vY Z-{s\,jnI;EgCRz^Stē<%^zW\8W] -fc6CWN1F*u.# VO.BE  Kl79^.0=tŊBe$w2У!N`v_0ܦdJCIIPj' 'ILF|Zx?_)Rmd^-Uuы5Cxţ}0 -fQ0{W E^5'}bz8{ݫeœnqIޠhESz.zZf yT@} -h%W.G?y\n.'r)M#B0 .x^UEInښ\M-Jf_w,(E$W"eel8 -&UѮjfK~|%#զWt䲭oI=G.˫MZ8Z #mn.}u*-U+jRi)ϮuM/G4tBE<'ŝ ioA4?&BYt!4 eϳ ?(iE]4[sӲGɐj3v-%H-}s46xE!v)/KĢ4kcw=RQܞt'C} ?j -zz̒#ÿ.RO6Rav>)̒V%~)n{Q w3TH5MbQZſSv?OGU YVQ'?>(=-K*JZSѳ$K(E)kջ$Ozny䦪M폖!KԦ"]co)Wmqʿh*X ӻu飂T~87wyezge# -r99G'=9ԪxŜfXeGꩇ`uׅ붥VcDoq2:5r:%wek?<Yv8s]vD?ɋg$_MC9I;^-픦 i=w Oh։;>e9\NsղdN˿']no $GbYmIpGM×NJJM_qH=Q0:Ԭsr@- ŷα6v rl#u!C=>'9bS} -iRdk+fQꓡioc nV abUmITƄ@.P(Pc5=苖O1Y^Ԫ"&e?bqݤ.z~)rxd菠 a>J -fWjbQza\۫8ލ37ӱGc(b?ZVx8 `iƙ9 8r/`;9sr[ټoy8l)9{< T|ߧbl: @e`y0C;y tQ6Lc;Y 2Q Q`9yn ۻs7dnC7'Tr4ss9$ppA:rSm*UϛݶC y1olMݶdd.va"0~st9-:.b("L2tY'܀9Zc))Ez"r@X@BKњ\cxZݠh7=2Uku^>"5 MXr[z3d(50 Ai5Q1\lAn: 0?:8yLc7_oe*e.U4*MA樏4HEo;VL -D9x<؇ut Y5mW렛lgӏiMSʇ騚jd:X54W[99942Npt>M|7.p;9HdͪepשNn]}gjHUek;Y fٹ 熃n6t_gi;ny͉*fI{ۛe*v:2ǩqn'yz?MߗmGsyn d` =AȒ_R';c7.tp3i E-K;A3~aNO2\19(:II#XǑ:xZsen*zlƁ=탖$}J] qÏ{/~"l.zO8wq.I0]MS9Ӊ7.8䎳?>Kq;z8p/GB*fefr^}je:@n6[ -nY1,BQI_'o"퀤Vͳ}'@4Nvr8)<t8!n@>f+9SWnֹfڦÉpYm2\k5vNOUw/v硜ÉOifY]7se,gCoeudQpwin͸ٌ (T_ZehMIkr[=M;V뤝MheyGc7#{ z(shFz'EZ- 9CyG"nNPsZuL&qjM;37(ƣ}_]܎ͱ5l#vP\}H/|,cc;-.YG2KPIzH2Ū#R3Ni#{nujնyޠnYi1Hb,JLZM=eoSNuޯ0ֲ_ZʂҪ(ZP'`uN/b$juᇇ_qk] Wcv@R_,Agrm=m:WᬝM~!ni)gfYqv:בm$ -sa5 [;E6E/=X8v6:Yg8S7oO@9j"y;pN,[:@*tQNoz?MsM2Bv689Rt#12Ϭ5728Zj'PĚujb.c7 ܀]wZƇa/Rc(sq%7=+qcgd(]lC;KH=SOjPANӽ-vD;\ Kk1<-ŏIv7KԪ XSnF厃7MŢ"[{_+  -a;WNs$?efDrS(nYi"V>[W֊j EvG5cy^sٸ)KYNr80G,K;Wb<r"tFʜBRֶ6Pݶjqմкj[޸8,9f6NΦ܀ (N't@ ;qb4yLC Gb?Yvv8t ؇ <_S B MNn}=$yާ=n8ZM?:I~6똛w W\t f^S+*K`A/wާ_ZQ;ܯKÒy'?ȣc~Kݶ5֬w?'DfjCn6nq1ɮ:OYoGt?kp/EZP8)nX55ANy8Y::w`4yRl!Gd =~lOR䲶(7RUb(su^L9>Qif᨝Κu Ȫqh;p AAJ]fJ玓-lLC1Crҋ $;7s17sRYNG,;;Y,<MCҺh{q2׵6a}4q<߭{;0d$fմg+~R8hnk7-ݶҌ --L3Q?q1 6#(~Gr\^kցN̨G֔ZUNCGHRіajل_W-yzמ9=(r6DlN洛Ms,:\oC3H=s[,*2PZ~в:,׉<>8r2"Fy1O֡GKY2 JO&ri6{qbZUM{ҳ?IzGK~N#6( -nC*zNşG .9dDEz=jNuV&޴< uQݴ!7(`EpZM74Z+9wpehۍ@6t 9T {L4܀[ouץBr6Z&z}945ZMK5-2vzqH{ q -f{\3uS}햕nEW|Zͦt m<ᗓ!(=yLlNG2> m6wy^o.Xr=uֹ0AZ ᎻpUϽ9ZGlMK҅۴8 I"Pn=:()_ zjؕl`{UIAvdSytmܚȯ4[#{?yM T"AHٓNS$u?5]3zQo+(g1je޴BIQ'E${rh]| )oKqZl~9BhIjKCYV܀ؕ7M;_nC9V^-GR7$تAeym9ɫj_;InuxQIMc>H=i[u OPzI(!h{_i*v8E12ő]YD }$ϛ; osԸn P>d.sNeY2ENMܠcx,[;q Q(75dK:Y֞v8ogݲTݦ vܦ"~`j|imٝBQ~뎋-rNiۦfوEW r Dud:pǽۖv6ov8Țf{ux"hrzڟnHflqT98&-sOI"8{i| QiEba"8e.Id(?zL7semC{\mC]g)w[q-m5)~ROϝۡA՛ f_)B}I9N, -BIkxpj9|;崸`.=9`V=2jQׅVԮ5[&{]yqƣ,+& w]urǹ&edQDpMa6n84Ð:"Vq:Q 7 i!Vfe&Hٰڦ#q즉 i)Sn@ni[Fr@ _҉jYqfn/:7(\q8ujXt,/g'{nAUV-sղYx_u<9ߧjYiqsDZٴZ6]yxtÐA֬{ z/N.Hޗv:gだ 9 "i^OiK1@jpk,meOKs#6*qr\.?#8\jb\ߴaBI]f nX'EqԊ"h]INܴ^+xM媽fHnz\{ZUKrE'uvS r,=˂ZvGϺNUR١wz[Sױz-lF>D^fʼnX A_>O;QR6͟oګikfY76봝}xbAAr6}Lݶé?^ oc7lcmnIt8jt(NGRAp>o;; Ec$G涚<8Zyfb[u̽Dl ٸZd<_:ⲡ|mlm?Ͷ7fM,7:^u=JU܌fSsc Tѱ7GPj$Ib#uw%6G0)R!zB+wC/G}kSŮ)=_*2%v܊[QJ'?B CՒbIMzUYE5 p;:V7nEn.zWTVsd⦃!C`oiӤٌq)]p;jre(gr8Yv:)Sr6fv:ڶf~y^S(BQۊPI=QC1޶m5mCx莻.=Ҍru݆RU\G,A)'8Y縼K66|Nd+ۖfܛgJmj1v];+(EsL|rl/CP|:u_בX5tN.%HEKdSˎ4лNAbrW?qO{ș4 iԦzKPh>Y֡J) z4aUgz6J.kzWfwy)nE+*ROcNW[dF÷X5=)bde*dOjp6L6}A1ɿeE"ǹMS;Q;tQl܀YfekZe&s<}Ac?9S!ŗf;)Mw[9tj74֓}mY4xMk;c;N:QV'IXnC䀨G8ГtE=>u0T3N][岤/4UT- 6I~H7KQmZZS [-E0=x1E0*W v9 KԘ!-)yjj~P3'AB$rWTĮ!?.6TU$rYb%5N5%%lvQjSW̺d) a!@ )SS egMi>}ۦӄI֠bUQS~Z9Ij8ltM˞9]?dȓ>IꢈnيQ)tld@֭$y! -iX5ŦR/Gx?PpP ;IfAP փbq,r8'gSr6׍t'IN)Rz\c\66_$mϛ2P0;Ug^mZr6my7mUNG8t0g<=$v[efjirԊ.I솰iqnv@F.r򎋵?nZE=} 2Dij[J1D]]5L#UĖ?g)\iYnzz8ocɯUQlk˚48w܈E]> -t]Ky`~>RD"H]%iUG虇ߪmvS,(JOTwѠ` ((U"2bI֢~߯I32,jME驗$~(#w W/ ].[N~OxS LvS*Z͕u2EP)򓒢6EEǨI洗2TEr.^.S c^I{ipcȋ߇[n;C WBY$=8J]]+9\ qET!ZF2YZْi➗{h E$Ym! - -kL]C4?J8mGH*>1c\W*Rї8{ r:)v8#U=/y1,tL;A/<<nS7(\Cw,nKjrٟ(5l*WijY9.ßa-s:VE9Rrt5k XɿHX< H%Ol٪YVWM UF:BT;X{?_=sr|=N'EQYH2KOʑ'ZNC3 z#1GNir$hN.{jsUM9Z͟5Y7&(;aSZoE6${lm^qoS <G,u14˶$#RLgw{7܀Ni熃r8%{(^o}3{]-zYʟjmq& qt/~JIPj&ughK;f?Dej5i> S(&'8#q2JQjZŷ]<*he:jZ_wzە we6ȅL[SYGKz~P2.,yԳOQe1d7 6\=hRZDk [O~*#G;|~T$ݥIt_M8zMq7:F-ʚ[F.qכ"zQ1I+JRgCtGĞ(2ˬIqz?n7CRk^6/-+nzw-%ESnʢ_MWZ }Q/E:PĦv]Ű:KTAOI(QQOzcH^oX ['}2&k&oIE -I622X -IJqCi@*ɖ 9pȌu ]:;^cDֶm{ oyy=o[>yuq=is~uy}|v4Tt2i^crwyi>ƭM뵎7w73MdӵL,4 s(s۾eڶo[ɚym\ɜ[&˦yܾyY=I &Yd=Q -Yu-Ӻ6^t~~L:==pHv{Md4N5C&qWt&X1oI㘗L'&S+Hy^濦7TJxpA#OB~HY4x a1-fB>L)azgU09QDl+Qq$$dFg67˿UG0k I~4( -i\%ǫ0&"$4OY9ᎃ=۾7i#r^i\$ǥn ,1D0v(a~fIPbbWfQ8T$ *Q `jP06w%|F:婺k.ߪZ6ѱ.,鯭]2(iUᮣҢĤǭ9VrH>-o8< qӜA6-? v?T81UխC-p ն4;ٸ٠y(vqmr\']#C$ECĥa1R#j|31+S,]$cmݴ9 ۮs=/<Po a$n+(C-fYIJ+hx`6 ;!Cf&y($ޣHƞv[m$gC" H~Y7]H@$#,&阒/C$qs>+q)DZgn~'{ukNL0帻4]'{ޛe^j}4E7 '{m"x@hb>= vCxЃX%* >Ш@ǰLZ -4]47{$c$$iΘDKxdȌIZז\{qByx5ǯKR>ůG4+ C .\&*]Vߟ]sγɒDC(ڗ&>ㆃg>"=vʞr 0bZ7u+0ӢDpa<Ġ!2SqV}rAi*`idz}ꦱZ,Ej -j[S} CM_gGS$=9 M.AFf Ep}!@;$-"$k񜬧DGj!igH7MݶZ=P=w ׮(Y.V$TDZD.X$O/TfYG}I1u&OPVr:lJIKSMA@b̄wȽNiP"vy-NS4hcZbE4PFZw̪a?5?^ ny$ny8^FIȩkr!rdDJ⧈}45Gv6dgkYfuZN~uwIRATD2^UMp( N=}AU ƇKSH *EBf:4hUG.o>Z QyֽAMOM3NAQJ!RH!Qa -7|j H?ht @ t,EĘqQSٖHȋMvۈz!Ce#UZm?Ea0Յ9IhiO<ˇ->bVHqw#w8lSfqꦑM-"Z I!=lau2v|x5hpQeW4,A,[bi0Z.NqYݲI!hSB &1%08VȤn`iQ(~O5={.JvGnj[~igY2WQO,4ɱȞ6?HFH-Hy9nt"f@իsD lTR+>HiBO۲ؖTGgߍ=ښ_;6R5ת:KѤ]>ԔAo^bH ovYv:j'A8}y8OTeq@\=omץ -*=އ℉Urҳ$d3 0(僯jvQ]Y6ä$edMS=F[Ū%ƣz+)R<ܘyRw|Rkϑ#IHUJ-!_G-%-?p1DuК"؛c_726P`K<`0Z UN# -0ABfC@8TDuItZu21]]D>T$14; eg]Sf(!^%<1JU.K 8Nb.\)4}{a01q+TzAiJ`$|yzSLף=q!h!~&Q8캄|'"3_TcdcY mja-~mz7Yʞ'uC+fiƉ 4E+*JMRZ ~xYbOUZoQLQ -B\ [nKl<qbbb p0 ,#*Ϯ$muAQ/v[uDiӹpĥ8 /AZ⊔'$>ȄȈLtzGʼn#fX1bz^q'CգdUnY4F1ê;1}bfb%Njȧ1urc-z*;7Li7 ׽ʹVF˧2bq-(4) .˨F/(QE. DؘPw$Gpу ߯(i¬H&!1V$|ӓ4tS>?-{$!#E -E˟Um;Om5]F̪"R.E$ )+,OuH%ԏi߮dv,j}T mSMIυC$ Ɉ^˔>1`( 0(ĪbfyHZ\vgv3PtUnA}P>gEQE/Ph a&tBDfeB0F~_N:LJD"<$ɑմ:?~u#:>-?yGG @*^*u%o$g:J\. EG͚Ѯ8Ӯx~?E]ͺ,vqtСŕ}]mIJb[ޗ=m!ZJSt4E$}wţD~\z(O藴]0KSm;{^eYgl<)" -dĢ&mG6*6QH7GQÚݮS/K|U.+HWԺƕvuYh6OĮiާmoQ3WOo>׹r\>z&͢5KU_wݪ^;z}i\7Բ獜MٜYכT+/"e*HFmU[:ݐ3z*}I{eXa]L(=?8],v{& ,FRRt_J-R~ɭ rk0f'r@ X[oZ,{ier: -f ~u&9CGϖjt G:,Օ5,nhmO;z[^=gF^:^Z<BMQ=2cfZ{ue>~$]|ziv(6(FU` ;)x ~v9LיZg'ωֵCJmq٥ق!dn@nD{] 164ڎmŧ^$vUɲEɱ>XAjE%%i$OM3;Xnf?O~pZMGQմ51̚7UǡmAhR>~lY[bQ-罹o,7w8ĶX4<٭k55,N.럚!vm77Zb.NڶMLj[(@xqbq3l#HMeH#+{Iu -A<1\ŮuɎ -k7U v0+=ϫ;HM˱8qQ94TT=Hۦv8fؤZףmmeR -x?ENk5MR7ͷzlOQIE5F'j07Ov_q}(@:(Qt4Rea9r8ZخԕC{TGQXc95Ӫz ϻKS"yjZKq:Avh)Ckm麂 i$~ʧi^7IN"4ЪfɦѴ^[,Y<ݷ*OrWߑѵ.љ[14mGQ $1-ӯc?嶏ۊ^9Eӯ\]Yl.IDӍ__MUbh"vXIL bx4W#x:p' -aHe9y=c;S <56EO" @L|IʦTA=}E~QD?e%2/Bb%>{&ϸ4U1dκuyOeeE$5Jl^Ջp>3iThdJTޤz_qpҭ9ٶ\$1"%0*TS^2l( &P!/ZNpו&fq֭m{8XFRR C"}'B,)T^ٹܖ|zij'Lv̛NX|އaQqT2۽GuXUՇaϋh0G=ϋU5 -`A#ǍjLnKg9>p{6w4SE=:j*ڧ h}iV$͔D$@D0.$p \ PhAcԇs5IïsY嘻tQc$0@ 6`1~41K0D:|I%ťR63Nl\W6?QMU#pF%8 f(#D! -&A&$30.FX!"30ζx)ʷ.ߺƪZDBLdb6t d̠7 \P" -+l|B+pd=/ݶn5Ŗg1# @Z 5B-D -T FXd`Z+"1$|:|Q>ϞmQyB Y)H 1hb9( jd$:وÇ<췆VFWx4a\5?5㿸XB D  P<̰1E $%)$V?ɪ_v}.KCPb# K0BK4',+*ƂDB55Z"F4 -S@&$ `؂ؠ!$ + Z@@-X@=izlq8fꞇ" ~\ 0% F( 2 T+ b"A MH n`,/Rhy@)G}(~9D"@GP@ B+XOh/A Q$ bİ'$1HA VP -`5f(I`Z<9}D@ n0-t! ]p@!4A -M6 LP d`#@ ( #&&EC>>+S5jׁ.` \%D [P(A gĐ&(2`A xVSJ߻1mYDګ+ȋ   T(` -W@( w}mQ䇤L,X"$H O2! ^ pLE ?A:zAeD%_V} -*@g86L -OpЅ.` -Qh -X<;lĘ\óUm[;; EvbR20 -S`Bؐ(\ -Wְ3! [AtP$ PP n  -P 8xJK˪4KEq)!` P-drC&D X*4v0*8 QH V L81`P,^ar z-^),c6 c@*4 -V(00 -4Б# HOB~JK}%/(7h3+LA h(@&8! M`xd@ P -@,qF  s -{L뫊DAx@ Y-| P$`,8 -:p@0`A>%@-XhI F?ʒZX!@$ ]B@9Ad!6XB-TBA V X|!LLtuWʅJ*uR*! ip -Sh|0 -~Ѓ5@*Fу>h8<#'M$_zc!r`.t! iH@*δZ'!H֟8H%J YdnDVE\EIyC@A `48A -@`0!\@`0_7Zfy~ȀCFԠ6 pHJ0A ( " ( zA l ~96-HX0/hA h0P)p :Ё HM ;bA3#J캥wF"b:c; &;SʹvP;s2hXtM{ x C^" VV@?McBP?CJ!Z -Y7SNP%~Hң$ժIT ǸLҨjɆ'^S^1TFʦQ< S߯9,K@>~W{ -:X䐑"F%bZ9pQ ȂI~MB*drܯUqJ~Iz_[~:zh:5U NnHMt i2 -GK]5YNCͯ "2Dz۹$]1.e{2T,M#ed*!(G~=ԔC3ϋ74_UxTx\V-#Ј~`帕@. #,cʈaZR#YZ8=zIG͕-v5lX&.E>'Co7`҉>ܰ.爟e$e -W>MM]OS#~}>!?#1:\JZFv͊" WH!IFq\flqJ9m1&%Z|u"#&UB'WmyZN6^Je\SnS< ,ČE0˞E]j,㈯{,q$ɭ*a?xS%ԃ -֮ny$|Z&i"U-xm[lD1ɧ601D Fro#=]W6;-aZ,OKjj99m7)FbP#NzY,1G ]PBXISzzU=\v'W͒&E&G X9c̒ZFy@0K#vQc`F~jX)WĦ,$Ћ؊t ;ST4&y9f$)$PW)vyT Gzl $|" }MnGɼ s,ɭʎuHpbc$,/DT"vA0G"XR ȃzY9dKt%U 0cEjbbĊjsATaX>y KJoUq"g^HOx-,k!hEK1dOyZvDM7={ִSqE SLu$GP43_"0+vKq?G$2L0#Scyꢸ$Y渲aVL1cDfys˞M0#l3> ʇWy>-~aT%ddGr%R IQ)'( *nWD3' )ZdT4OH$ࡺmQd߇QEdSc@I]F(#1+IT -/^1~IvE, -WV bUMG'0#/OvDSm]RܾQǘxR^5DV5Lb$>zmtG,p@@&ٝAxwOROMB<ɧh!hrY$}S3Do#Fzn\1^?HrnaNVXHB|W9&/w=i&E^$>jڡ2BP*T}F/n9~]u -j_4bZ`D"VA|`R)rZD{ XemXN=@qqkBиr-}sL*M:HJ )Iϊ(2̤F$:K\?M=9]#.V-c}"i)Sg'ks8Ħ,(4f|bWӈ^@6Ģ"IIH;pl{%JтF +~9"B*9 qW:RЀRb!3JեHc~P)5jD;ЮY$ ]wO!}HUA2 1HT4N^0]ϓ%>MBbAjrjI`>gӗǞ2ĆJ TK[%}$c…*K:\Y30UI~SF<;\@2EJa -x|oUEݏ,b#jRbˆލ#~\^ONٟEM>bez*xvWs/L+EAX-ZWbVDQbjQCE P+$4*%6`G:i1 o#ARDLI֎UV nST)@ 8t+ьhQŮM$ahb}D 0&>R yXG./QDO|=O -_*bfshǁfeUZw8BjeZVʤ>;bNf$2/CP~}l5m_`bvu~.s -hw鵧Me`.IFU*֛F!8-bQUdL ˇ"6TaC5*$x !ҋWD#W@B(ѣFK|8B 1ZЃ VPݵ  9b`f\&+!-ăXb%|#FKVPzqCxⵂBEJpRiА^iŤF~Oq6JLDAhyS|nfgMss<Ŭ)PdH,X jE -@@zx3MQkD#v2)hEs IdaF< aygģh)3h2Sr4Ϧ.Ч>vhQ;~HyXF8"4+(prЬI4%1(/`d920Z GEJk~Ei4)!gO -ɜB"{M=TDn@$!"z٘!)bƌ-^^POMQ˲vqBJViGʇ Vot &dHo$Mח?o/[E5BP=z`˓,r7*T"-"?%ZTJ(y1C(aV7Իu8U|uI7M}A)Z녫Ɖ(PfKKF9u'ѪD!r'o*Npqm"ϐϽ9g_yؙԣvutIb5I1-iZu#TkI=?Ϥ[]X/ZM*r[7!zZOfmS3ܟdH5a])$=ɲ}8mQZe۶i^Pa0rӐ0)q)%,U{ai!W" -(#(?Wԛē7YnzT={Lw -xHv:5/=Oմ -VX+bO$1D CpO򚴢zXU"%eUtF ]">nJZ,*I/ɯm6*X!!{~p ,\h$0 9~Aj1Gd.$.$+[Bq'@M'7ߍ]l UvML/}jӈj+ -(x~ؗG+b+c''g}s3 ǴЭ[G+Gr9Q 0q妃f-wmM/IϭʤKďR:ሽtL|=}cEٕz͸! H$3:*7HB!Nnr[٤ncg^Z!Xaz@IB?Nu^gYu뮺~o(5]:v,Q=yHe"CJ-dA5/Ʀp -)EIJQ΃EMW4Q[{nIr$]HutM.[k4mS?^q{AGE{T|B4_xN9|*|A-CE:{0Lb(q"0|f -xr֪en;2r2DUo'YF78ŽrARqvH h>DEDfELú]S]pUdT.\&AԲT=|ܹ(@z$s5Mո ӕ[ݦIu}TKH\vG0H7;̽W'+6L$;|fڻߺ#Oq\ Zx @KЅbeĆA/* yZ.ŸguoZ$r0>ĀKP0 |x`;`2 -@ @!8#edJy]$;ɯvľ2ȖsNC'RKHbb!E -սZOQۃ` RIM3=jY4YX''_ -F)?0@+I()v w/E*\hɑ> -K @4P|! LGxpKvȬ#Xmɲ^m ߓ;5aqkV &L2P Xp$A,@Xa~ -ߵ"Ww\z7պCqsȳMt%d}}_K@U(0H(P/@[A!!TY@D  0xz؛'ݒ=Q˶|:B@ D A @vP6|` -ep؀ @#,NH@6D`†XXQ,?S !bt8X`!La !` pC9P ( @ 1RzKA騖f r A >` D PB8Є1 V! -vxD4xAF"Z'jFENgkӽ2T%p!6R30BX Az| Mx(`e VVŮ]{͇@G^jp(R@@ - -Hh?P&~$ATPztL`8:0$VTLVͶ>ݒ G%_ϟ+A$P TL: 4 Bk):T78CIYt=G" -10(-1* `  D^0Q_2b -(t).2Mey u K)/n@ |`*8\(h-@(.@(,|db #I"?SdP%$& -t02ABAJ0 K 9(LBP%a&"ze[e}ޘ $rtH'(IH@X"vc>P3cv0Y4!##.A (d X(N0a,8Aɏ%^7x0@C<38G&KI}D2@% *Lźgסx(8֑Nu/Hmӗ=Seb>,MKEG(NT𭖸g!ZW}ο "َ([^&*.r(@J0%QȈ ^HBW)1ȥfG]#V#v\yhꄊ} E -J;p牛Θm(i2{ i MiS|F0 "?(ޭ(uc~* #@~l-X#0bQPNdRB(+9Pogݻe:fmKbX #)^{yxV,dMGSLAPpT#U"=kd LnSV.3;gb:-}݆z ?r_+wK>鍮'Gn8" -% -6LNvf:Dns|Ṓ=wUvd-B ęq|c*ͺ;?rQ< $7Hb= h~ eL;$*$-L-1M3# -A9mtm{j]܆o+`YOLyW^];md?04ϧjon牝y(xvy"I枞2,)]U7D9穗e~? 6OdSj-HԸiYDG%XEAmW_ܪˊJn\XIs_YOd%ByB;}뱬`Xj|=dAG]K?lm8`" Hp l}Uuw5ű}gѤŒ_W8tBۍG4M ڇ#nTN$H$u+ׅjKX5EDk3Ŷ7ǯ-8ph99pT)E),a~,;zCԶ5I(ji{P4x,aOqXqu&uhE_WO~%?f:\-Ao0/M&~?,9͒94Fz1bO_ uƑrtk}A(TLzV/QD3= Tx_n|ʒ`n\oX-?Oퟞ;IzG\Mr"繓dHMU[ZW ̵O(8Zg"DcʢDJ T0z~(Y>ya\X*|e׍,$9=Yc~ ޤ\zZ%vdx^9f#׶.Q𼦭-߮dZ}:⸷Au㐏'K6ݻ6J)" --^x>mMgK\oUUԮ* &i%㻮 EKv` WYeɎ~a&\u{4nu]u&n+M}hee0|OGQ]pgW\]YtSTu >f߽ΦL(XuE" Y<W[[n1GӾ}uU6g u4oM({L<}mSu,O7`hyo8:3?9 iqqhDHt]n{L)" -yj%u蓫'Eq jDۍS-6RPO|=^M5QG׈iSt.Z]zKQ[?]|14xb SH4Zoߓf4FV!9Vɳ$:$7BbUbO~3/P P}mԺ: Qv :XV,ϋCBb -}ص - -J:c9#x|Ҫޢjڇ]Sv&*^GϯB-HeYRn1zmAF/+$>?"Bxx4U5é&ql{@:R~D0J^=^RdT&Ɉ>#~`=jeQدGM~Yr$MAoߝqt AkID~NJ!ls`%$R({eS5u&MS4ΟMIcmyDEɯt[$宣?OS4[N(~-RdJ1D8XBXPϤ8jR&YzP '9qϢw\ ~8)'"]P\USH3TP)Q*zeqԴs(Z~F Z-{e/RLpOT?h@ @ -,0D@jr(UqlMݲLH! - ,ADq6ďBԳxr]TM(XB"N탊 -!tJFrA|z dXB؁dMI5< -<W:h Fˎ WiEE$AL 4+0d!C ,hbD {uGyhH~Ȅ11ejDžUb%Je%"G7IZNBhXNZb!H MZז_S7euzԔ(OI0ܛi(z_J+P -ˊGiD<{*K@:U/-FBJnLZ[!n,{CW9,Ssl5#A*}$]=4"ݶk[H.X&T{ѽb(#[H_1lV-󠨹٘Nq.ǭfV\n=ﳪ(.A@M𳦬V1H@QH0v]E}5shU=/_b>eЊvE G - -RPY)Xt676^ aD:Tb!,'!ّۚ. LDAi#ZDLh!Cdb=j3hD>VFhJ"]TL  - 2Xⅈ- 0.XB -$ ,` -@bIPE1T4q@$'$9PX*ɇ -X3M+ 81FĶiJy%9!;vYg*cy)"烂a'wۦ|s>-F/҉GO?G\b">V!^Ut'×T-k`(_qnhzbup,J~YVKAmPLbx$kT*4I'q|յNiub^, f0s˺Xfy2(~VI֍K5muۯMOㅢIRx=2ʶQ@  k%ue&5z9[v4ϭžv[ ,_HQd#ؘ \,]c Ԯ597 i=JT._]]F Xĸi'I}a({=zx JyH0^aE oo]u&ǵ Un M?QƞfYUM3Z(uSߖY\Bb!Qsr.IzCړiɢ_va~4iU=g z:ukWuR997@\` "ZdX& $c0:dRb\0%;XC28l$JoRgzZ֠ Zd-a|fcSDh0LBx!#"x@"jjtBI@: x247^Pp -mboߺ4WKo_Ԯ.=%mFUzR E`"wIH )"3( $MeweO!?EA8 PQ~! қ翶~U,- $߮h -ȃ2 -ͰN=RDai#P@ b뤦z^Y㲥Y[_UuT A|M}Xb9`L *rB$j鶊ɫ%h(!cFĿ G.GbU˭ .bM=$QJoܓ$=[S_7/E"# C --`jZN,SE<8AyD8&(W4z%9jV#|n D`GH0F -"$ =v`RbeDa! -Q jr<fujݷ2*դ0ղzY\7l'FÐ6kX` !BE+z?͒g 8@(D*E4>z$r[ -I]hWw-~<Ȑ@W$Y@(GC,\\N{I^?$$@/Lc%"E2RjY A~k_V=PDxxXvh ȡBgEiZ%\̄Vmnuِ8"%dwڡfVbԲ]ަ'Ae]a.! C00eUT%+&'^/X+$)?m(w#Xz[Xs , zIuc@ -o|v>Gͮ uUE 5 -XViI LH -%z( SYsV}APE^U=Zr:fniE[< -EjLK-\D,h0HB0.8$hp!,3) bG>`8qZWW JOV#)w`q&頃y)d熃v4T^1(NjWVP$`vx|jiU -@rm֊zzjx]s V+_K/ǥi-WADjvHBeǢRF IHMqfR"=8D?扟% ".'+T^MG|1S.C0⇋Ɋeԗ`Wݶ,* -0/GiLDtџZcmk"c?O1RP,#Ю:^#Gzyier)^@< )jAb<_]6?\y$w:>y1~( q^o癚eu/DT?ĘA>È0`BZ+*KjEwAOݴ3;<$B/{݂UzKfEA>vPP~ȩ+HȈ!"FTeH(ǐ壛v>vYBdEgY{ t@n8$SQ},_.G2v+;Shx`WkElE Ex`FHAb-G 8TY -PC U=ɲy nY$tbIQ,bxó͘/8@H;;м11+0O3%eY6{G/KPգv - YX䲟6Mn ԫ)*Vypr:Ğ`ǯDGBZ36v"{ݩCB"rD* )jM`#GBqHč -A 2*\(<=YR8 kOzcz]uHb}Zt~IzPe!YWd##$&0eA욒<)cj[h\~X -yY-]|jvِMytH_n[m~xp)LĪ0FV-kQ"`(azz)!*Onf7bH'?/Oűd(\RRev1ŝQSuPYc87EO2D,bB0^ zl֑NyՕԶ!Ӕ'IOI 10"5V`Hr":-(d8K$#edChZn6_H`iaBҲ$TͱGW*k1l#@PF?=edR*R AQ%jٛuxQEOzfS$*/EClf*f]P2+~)p&kϓ<(Ւˎ-\X,$WmO xIz X&ŵ<NH4 -itLПz]EsA $|Pk )h@#&ytNp ax ~U݅ٱB2$e*&%f̴L4,RKkz A -`;yҞhyfp"6ɷm2B5̎z_rQH]zn罝RJ2aŊj`6fG#zxbqeCD#VY;oպZ$TѵɔTσqVReKpq-'kHA*~[ ZX oGrlb̰`]ozaՂalB&D?haPj8ijOϼQ.+2MKΆcwh^zHJj !(g;MHʡjhiӍnkS.eIo˟H UchU_uEC | o2|e⻧XE5,Cƴ21!c!3"ӢF -22V$nF*hh̸a2-z -mmijs|f&e[n0UdrȘhfT$151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515155555555555555555555555555555555555555555555555555155555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555YkŽ<ǁT4ԓڔN(#MO>HTk:*6۸\֢c ~=9ܴn̰uJ^Nj odWʴ“-*-C8F0UP\]9b9^e3%<9_`qsױYr8x#Knڣ ~K,mᷗ$}w| ORt> eأ$hEOۓ v|,>JOO)`wbM*we)f8Ƴzgu2@ KQFִЉr%7C$EHςTA\F8V΀xpΌCޏ0ѠR_1u7 "ˡ1n+[󑌹/G2(P멓ai"6}n$Cdȏ-E9E,&0=mE0Vmr]{FŢ,yGO;V̺7v!a9*EnklwR諞wX A%2Z w]Glg?LV"~Άl| y`EmQY@*Լ7Nu>`]S~5!5bջ =X+O.v%7Р'Rgr65%8T#݄vyïĪq'N[b+}$$_*-IyAiZt4Uܞ^6#X˱4Ǯ^uk:܍SJKnZO<|8͜ LHkq)VſGn#9ŝmU%,HMLT'^vXF)ڗ$q᠘Kjs#) ~?&v6E'7rW}#)v{-J| -gVbWFbص,5_L(UMMS%wC5",e+N.e1arQX̞ԓEbKvA3'dx/O۾tIG eg=U4K9}XIː n$wI"x -nSv;VG0ԻxpfOaįϞ&}ϓquou#v=:ϺYR.=BK{leER:ՠeU~~'{ݏ&]ɮ=6$wM7Ix;8N{CV؟WZQ)O*/QojO=HZOZ[BBOy]#uO=vK [; i^~Mu *pHMESYWI6W^1,"%o,~s0&9.w b]WnpzAnXtL,R(ţjCp{hx{.c5ݏ#uLK\4 ŞKkbSp?3/fs|ͱ nZU'k>ou^lݣ'Zˑn=GE[\Z=F#{9!&E&" -bז.J5C(g\?R-2& B˜ G/g:YflU%=' {`8ÉxC%dR.=~?^ |/+v=fb.Dm'go'kNǹ[3'tIE=dh^.bԛtWPJajo=2XƐB)rq})rzFP˒8JEyWDG2϶wX͛eבT4T2܀^7R19v0M̱iMW-3;DY2GM[ղ} k#*=Kl8ē0zSzrEPvkur\;.EOjԮRd -SHC:FV6FV*PƠD/^782d~_F3V~ʐ?Xt4˖S< -vcn;NC,[̂fժ)9zcZSM[5?D'O) -FI|\3)jĦ{l/ϻ$MC+Z v.w5eY_jx>g[V%2C:nƱmF*JL(9v^.N,yX-N%IS0A֒%1؞7@skZ4[ Cy|< T9V--=\s8Y750DAPZvu(nqћAX;o Yfdj tЬo[u}Q 5ㅊ29xmr=1H3(PWll9ơuE' fG}9%v\"XR*@>(Z2B˖ne%&5ӼAP>(ZMʀrPjv=,aU4sRIq=LRL`y2}N} 蟞8cxIz3Ū~9G{>})d %Y -ےm+}yq'4c+9A2jo3)=tG<䷊~T4IK~U ZOXZe}45.=7n$f"(jU-=y..7^w u'3sܚejVOQ Aoղw_mS1|wd@OfXP ˎOt;9N>~jseQul.dHNnQ'GRj^vŪ*5z2؅RҤP0<7K Al:ZU$Ï'$y2;}C+Zbӟqo8d5ǯG/S}Iޢ78e=$Xw@)Es$ &R^Cd%>6ǡ8 *4_k gflޮ/KuyiEEP/E-[3(PbJOjH߻mf-!RS"ܗ㊞mX% Nj YZ\6GK @"x3P -~aC-8J0LrX+FJcjUtţÌ<+Gː&Nj(-GjmoR=GKZ(}XWYx+)Vse-p-;9oo]XOEQqra5IvoӬqG>MqS.u!6ɐ/̎Zփ1ZF,N7[{ -бjE+* -vGz"ȇ\c?j_.}uԊ#>$H@=^VDx;՝!e``w4SV56d[9iDQ8Ď 1"? L3;Pdt' ~miq Ԧ'bRZf>ie01IEX ZW7[vz;jʼnZѐ" _wۇMrTͱߤA!1VHE,c9 ۞z : jzJQD~Y/ ~ApAVʟό<:I?G^޶/۞^VDEk*rZq C8Rjcضݸ$5Uim!7ӵ._]WZjƌ|-Hi]Z$ۦQ&>stream -Wwm*L_>U=ijz_v:3ǭv[e1{Nz˦uRz>no.,_DB+v:2%Q] ~fuÐd] J˔`>ZhQiT~c][@ XjdnѠח ~-\vUGh8 f>%كy{IBQӚ#n|AYrSoA 'MKkj#.LhlԶU?кޢrn!~{N^y2VrӖ?+:UKv{K.+b՗= -~Kn ~5Iwu3eIlz_=ӴrCz~P35DkjjYT%PU>sU'>Z6:yLQ Q*se A()˒ˎ6v7]w7 δ[ q,QO0ZהJ{u,c9YҴZf -vM[RQRZšvӉ=TZNkȝܺIUy\5M'˓ 6\,Umzݞ07{_(7fM{qI"UY@Ŧ`BҊ'9MX-k1RXHRQ^WS1մDI,S|^5刚hM/PPt0eUx=Ţ%Sk$=&pESx/m񑚮$uHN-~Zߟ'N VĦ+oE*}R?=?+Jrט=`uC0::>ʎ]NUIGMuRO_S]? fhUE) -BOPd[@~= -nݟ7rӠo4TT,PD2(j}(v_'hg-CZĪ!|986m%7rzzq_==**_bx)zWWzJ40l5[a"Vͱ6V9zg,[B-)0 -ҏYw?=An"% qL$.uhvP'BCaQz_w,W-[^)Q7gn?'EYb岻1K_πvW̎RԢ{ 6 :%z nG)E,yiI~R CĜ2]3BiK2eUtܚ˾'$[F2,Q>>ɞjz?Q$0ϓWۚx-y~EI><7/i -Ciҟ*}.s[ rb Xfo8VPݗV5@z4.sy8}-d :ŏ:D3@5u&-ڥi""(I9p1|!jL&xmZQT,Inp('cOgm+} c.2ztH~bsz4ģcH.j[q ЊhirYf9Qo1څ,M[&o6MkW̦Z$GzމEc,2&"^mױ]ho3'RSR^a3<{EOʗv!\noP-U%я_|x,[CrWK=fz[|>>w2M[v|zYzכ(nI@} ?GQWQ-z,kzI%V} < сq=[ryŞZgamak|P01‘v( -5,B^Dղ4K;Ejʛm}⧺r٘3V)LQd1}4nHfiL"ϧgcgY@XbS4{\0_iìǰGM,a1<+fzY%nT/5ms)~Ӭc_U_<-H~K||D_T'iױf%ZybM"qYޭӂ"\yxtf=Բ>~9\ԪOd?@Y刋I-My59r VJն"o'AI@?˵f+nwdH)e*a9 _cj " ,=YrU_E6U2 K]泏4 ״7˗_;#DRy%wU2J^.FZ-BZ0(~C.d>| /ICJBUȇm( L=Iz?岣Ԭ bƪBE:,,MĪI "w>3lԏPd&} ?~$=~ET|>.~Ւ -s|$Yo{jiЂ&IJ1Բ+&`rUzlIêב^jwyfzxY$n.꛴ݠWbQo!}fP#R!qB"Br5($ Cd!UJPqnQxUݱ"D }XU3UBzAɕgElPo#dǸ͜JM8D[8'=a>> ֩Gl9I:"=oeyA$F|!rp~zvh5cŵ1r^9Tn|tVZ-"CX1b!}R6}i -j(疑DŽK:[$v8xn)$b-Q,I?$6,6\׳m}fӰzC1IC* sw℈Eq7WMk({\ܦuG1r'MO/-uᷛ$߯D;ɿѢG؁s)@-{v:'yVlnsI~W{hz8:[;Z;?*Z]$Q"+8&-& $QT=˝盨 ~[ _+NtpmKri$u}O̻Deò('e/R˧vE1GOW*n],Z#D'GhErsi]KaSZ3=)9;,rMRfQb -^[2*xAD< -룪lQ*ـ^J%uZ<^-+߿6ܩM[-e5uooo$6-￴X!86*-!4^PZ渓!esz*%Fx6 z\ -Y>)NC%np岇5'WT+;N"7wn`yϮy0;)T@+N"RGdw(l- EJ_ Y"ŨBz,CI^)@) -oN%^%cw8dsr^fZT9\JRR&#8)3c#%VMmfNHnhZ{؉oNڔ 2f#6iRjzdaF<7'EP`gć'3^`uip蝀,O>ԒKBgO)PM kEpe*yeiv²„gcŒzeDZ׆_}Oz\WMӫHNSm7G )d"8 ÅQ3q?^LN\%"%.j$W2 ZKHQO:6'Mr.EP9Ԣ&? -R qr$.^94E)jS*!;i.xt_=K1$N)F,v&e"orSd5bj}<9HL{:ێF/^oᷓ}tl.}IX5dPP>EwI?M[F%1'6+>>)S{ާ _F@ȤȀ`D"Fk -5Cgj~mïu"rm;:χ6xl&`3Ev-%;_$aV#2(;bV`Zۯ+7.~ց7MUT!諧+RiAFz=0쟖EQL1&Rt-J3v[˰AҊ$ٳe+E)+vEkf~)#ʖC-#01AZ -EW̢e*0MA+zva[N>z3*4ѫ~Onzz՗v:EWϘg 50 NIX!}ΣG=O7.$HrWYlȁ?'=PzhY6A0/0<xaFey)=lJ2~VŞ'b -T%C8Tn>p#FlO~~Ŋt#DJk=+z@FJKhMeL$R紖9TPF@ -^V!.-'xbKYJ'EY2S~= -CIE#JzBfwli_y_O2Ta XE":Z_'z[iz|/)FPRv-I(9aAz-Dͬ $Y0&Cа8B'0$Mt7ɔܶj%ˀP<;lAjŰ=~)#O b"pעVh)JtUeT&.".>EYu  eǯ;>n*O?NZ=F\0! D"/^\(=\%{9#]RSO ^bh{[?w("uYb6ւ2T~IGĈ2{9 -EvܐqVD.*&+dv)ɰ' %AR".MêU/k[ hVL>{=Ah$[)X|p!C悥Jo atzqGtɫD#Qr8Q}Zz -%px xlHq02"~bQ(drɮ H"hJegz80i!F4 q vĨN*{+_1Jȁ%edqӕDT~S>HƫG|}J$v!Bed 5=-Z`*')F8PbJ` 0Z*k:pIag⅂y\5\jUhA+Kid0<ȏ nUW-{R܀aX#B$ti薹w$fudH.X//#^qyLom$vDI)1"R e -l4 -#?ZHXFe& †Q|&.!X4  TĘ`7EG؀Bdwc:Y>#/ UBg@A0_\_Q UqvTJɖa~.J*گh)DSS~e^7e[N#X^L&]ňJģ'0I -!`İPZ@*~^m?j 0(=ݲL^UE-]@ȼ0!Qa,dbbJ=XDTJ#N#DIJeCP=`UbdI@ErU1#ApN"LzWʈ\B|>p+^aeӻ(i͸Vqr@ y1b!i(#?Ȱ`Q58yRBMPjno{) 1b+P#?jUU۶!Ih$oYU_2(|f:xIi!d? Es|=eq1iEWp_3eD?MY<%BF <\vdGcH${JbVlT"{,?^}9…JkH^xI.bj@$ r/+T R q%!^JrJ1s|zP`#.RMč<`0` !V/*Chw7 PJb\eG؀Q 3ʎ^& %%")}2<ϔ>(=S0iMaw$}AbF bPD' fMq ߪ-BT@Ġ"r#_:PBȐx$\HInCnZٓGaFuY)!=VHXf$'rQV1wvdBˆ_2o^{?I`\TL'uFXARo[N]Ik2hMrAA)gg E9M9渣'i% !(^ǹ\8\t>ш<6\ԒԢlֱNSJ;\BcN7sLKe=PE -Uҝj؁Dc _@}f@M?XRMT@.]gޮA3H>t>wA;b'>Ȯ3p 9&OtNN@ |K-tA!Ӎ4Di[΅u ӆ&)^߾7R2JUKٶ"zJAd&oEvߧ 3O>C'tv.U&,hrWh&MsM:g!MvB'w>!O> g!vNjo'd,8/_Ofp&oгpN>!o{B?uf°m& -?y };N|rr<og& >Lбsr`'Wy?!}t>aȶυ;y' ~r՛ y 䗳m;D{NyrX0N~;;as3N ö|&ɻC&09TUN['0dgL;dBa\턌'v7_OOXU aX2iӡ+s_YE [ i gj+gS06îf[, -:c_ " U>8  ~ͦ?gM"2{~g.hZ -ӡri?5ȥըxە+o Nj.Ҡ.zOLBqM!E·|3@ PF>}*F^iu>! DA^to9Q{G᧋ iWʕS*AP4 1 p!ȕߑߐb_c+(Ig\XL.}|f:K0YigYk5aP # B uCa ;#1jQA)a51CxE]QbГZʊ~!r2 p\rer^>L,%3\۔2r!^߃e銾?hXò]ՁuoF0_1q?џ3/WERJ.S_3e.-LΓنkn `4@@i諀f:9>}u?"x@@($x:oP>IT-шF ioRj@|j#TMcE@C.ŽAi}EYߔFD$!ު D3=BN0Q&:W2pD; X%$P?[#YܒDr蜚k-@(=)g`-C@ђJ# -줁qrY;ѣM$߈؇KVxr!xRjˀ 9.6DM c]!ghHYMω!Ņd"F>clJQ"x;+SčˈE&ۡ"ׅ­ĀYFze׾"@F*iYG,r|$>[p,3-vMsHT¿j7?;PxbTI|8Dj9s샤8HfP̄zBꃇox$pcG`-yկkꁚ;)I7-Vz©jY:2M%OKx=;jaQiF-V`RG7-uF𠩃7tO;8|6$%۰ -/&㡩l)t(%nBHKt]?w -M۳ *iI^TrJTDDY52(cJN' ;II6}K/״DɐB,sboyU{PKUJ;՗! ߨHZpoBi jmn*r:GȔ^4RD ?|eX`-nDh$ϴIʞ>հtNIVOx$:Jwˎ*``qV?<L;+TA/NBfv¦#Y׀ɀ#1g8)-JxL=g w+Q|_&ґ3;Nq؊w Sưe6_aYS7n5%%FH>bV+"-KBUvTgeT9[F(V0v|) 8"px <]?$T ]H ͽVY1%0= ]K"YM.,I[IQMcQ)D_Zx>pX6n*3ֶxE- ;LNH`Y -[>`/ /7rYjSS#!nN#'躗l ) K\ixX|l59$8$jZQ[ʉm})' iO7@ "|Yhflׂy.zw29k~*@>d~C| UZ4#kGo[d)$Ypfܾ(Ff}Uq aŔ+P>m -tk$%jeͩ}#&)񓏘OHFeT[EF}opMկyn `)/M;}7Ő HNxrfsȴWyAAcU~1޳;PtƖQT -Y ӢYHwn[\g=T,Of]c@j7'GʳN)k\k ԜtJP.;C|𻛊a"RdBBz?F#ߣpD?IB~~6"BxV`jYEVLC5NRth_" $*֖U5T9 ɳ{^8h2 -C%L&~ ߫x8;Od7>bQBqs/T'DWZQ\qGXALŞjƪckNS1O4@p_ -y!꧀rc]KKCpE~gOMM_CZoD5a_BgiSf UJb ="ibIԹ +1ݴ K7OHaCSZN%Jg UDuX>I_) 7Ī3I7x:wTьp*Wѡ-Q阴[ȟxhJo2&i'PRhIm$I4cIfnZ>PZXRVE#+TB ?6IXl0qC’2X!IW})"?23;y$kB8U흧M!DC_'f|:qozCeMP]1gi1<=?C B9+HPp08|,&d+p'\2pO7Vs{>1B覦M0NZbY'pI++ifmt|Gj!XܠWq4#d"k*:~3bc]WCO!]`Sv% .GrJ;4uRx-}N` &m@8PKjc:d+.~($&xDz-QFKULCBQq𒗇\DqmJ/;s|cYLSQr}^+4yJ|V+"PKg*$,XKxѬ lT 쑿|]6>2ufeҕZ"HyH(\a]Aj_8!CCzz i4N@yI" |~YP/q ݋QGC^Ŏ4/ف[4+TyzQQh}~H~H&+͗Y6pȆT&=09_;FإLz2o -Mv,) UkWh7rY^67"B:YtPH:*MQX_d{RΥPA{Pg%ەG9jܽΈb= -ajg4LF1SS=hƏ}O+Ց9bIz<+09e{ (#`9FC \p#´#e {+he -7]gzF*IOH:|ݶ*ùoQB =5_lVwmYpGg8/(YpJ }Sk/T.e3.&nml8oi -hS"rwefGca]pܳqr. h5C5-S|ҋى  &zx`-ܢm0{[lcF܈drqr-e(_V<\A^1GT"l:chi4_SvLكQ H@\p5C R5ґ5+09nt>b~*AN(T(Yf[R$GGhJJ%pK< #6"ǜ}/d\"ё؃4ˣbe @ kcȴ%2 /}[ p0}UD4Y`b%s#Tl.@J `R !0k9ęn)De &?^4ULVgY m-*JE-׼Dӆ<.2@@ocx4O{|N#3C47v -XE]q.ë\vVq]xx&ep IJ _uOAا'@>%Z>%3'd@@H -SEK dD <@vT(  \;B 4xuRSVG9]3_x}z֮] -J%8_{x~tN8tbG)tԭq+7\`sGwDX/%I)FS@l H9HJg3:@G-S,ꊋ"3dE:A!6 _^!V:#/zi L3w\J^e\= -`ݛ7rȊqjg\5R֤g׌xTk"b1_o R$_a x4)/ePSOvB -XZHF HoDSvmxmi“^/C>2.̶X`,CY*o5yXh8( ՜ XGo1nBŠw. x04>I^wZ뼮2S M:]SIDB̰@S00ϣN sӕxǭ sHS4[4. v۰a@Ar3|3:fI`"S8'Wu#+}W1t)HTz1ſ,6\4e2q:!P:eFI3&!%Ai,1=~3{f5t!\֌EMR?v8T#dp "~&1!3}* x}`[~ ,9YaroGjc<x(Ivpxƃ#-SX>ZDDwx8)-NJc&)&a(k*Å*YKr3KpV9#[D_)ɭi)AՐE"Mb"(BH9]+#R#DžQi5qҍަ^ߍhQ#V)hDm!CN2qUe\W\BQ~ mK< jKdSQQL;CE -FX 7Em0F"q#+ޙ5>RI70jqD87Q(t2LlK$ɯɬ]/ڎX@n-!EB\%[t -V)Q&@6>L @D4!jFi G5:^U`&HjDa$F ؁[5YH TvH4~G^UcXgKbL%@ADf~^o~$@#43 [S3`iv<1حQPdvGSIZ Qu7t6αA :.^X?*\(7CѬ p<4"{͊H5FňnU 7_D?-8ٳ* j -ŝg/@t$Ww>k$ΑNO^G0ɺ4G^.cM@{?R\d(=K7+x -,sG</JI&Vc )/0|;VUB6$؝C -:}v,JL#W^#P'"hrYϹhj+% Z@ClJtQxP(@9EXb%0 Ў -ٓ$J4jjnm K K\P䟸ɝ'8߮ȏG"_g@ƭ -)./>gG*_Y=05La#hŮ! Tx(bt1 &h'UE>oC3WV C6N)EB8jl "( -Pw1(C/ ,'{o*Lqi (6Gh)qf ˡ{,XCފ|7t\0FZAW& %c/\rE+G-+[p4e;Hy02MSQM32:i -]bDTwvMfc-[C{UNt -B # -ЇwښJAMtɻQRk(Nm&FXsޙt'V*%J3hjAƶۼ*[U˵ --5w6X"IJ/}QTǸ7U=#؊ajk{!ԇچEK:e lLl|Y6M 0)d} -#z"1> qDޙ%[;v76>h܁*!;+ЬYXˆu_4l)Kl`0sW Qb\Pl~wHy\@F+FCw7q ÔZ Gh3 -VYɟ΍Q`Pꑾ:g\8{n -+.$^Dž_@FN:mf a\ir8'G\3^KY*y8 `58H -zq (?jƒaю¬7q1CM`9H0Hb -(F1[]RHXW1Qj[=. e![f%E; -?"C*$-㠧 8CQI$ -8 ʛfIJi Bvk8 z=jd&}&W#7 \LGlt9*SYݑ1`O/JY gH]E9}]F9 -,XF- -|ٖ(jK+_*kyD9wFf#o;}b$ˊmDkTǨ6UhGz?E3~3H=[ m>x8(,uIUvʘrF1##%q.puF="  f#=bO9DӮd jDGK#kҧ2-nϏ%g/@ȥ M Cx8\xFGB^:Z9-IT>m @dS$Hȫhǃ Vpߙ}T)W#Ȳ%K%8ȩuTs#܃#tHq?1 mɾNvulm#q&h*@ -&@XA -(@ T@"x 8` ń `a g@ \pH@N*%(L0^j$X@$X0cA$0 w` aTi{Eڠ_c{%T} zmG)ba.iaә庩HmZ }x^vߏ , *P`,@ 0  -`@>&H 4``H@O[TbTV@ q8=8KQ m/d||bac:EbQ񓷷(4h X7c[Kby,ۑhxy@ f񈍼򖒏  YI%@`D HKCl?TePEhBeDP'%3G䑽UawKIDHj@8fnZYj&?/ᬬ5mYwYmT0:_9ݐ 'Q_7%.28Դ DX1!>;*!KŹ檊X%=z*ތX^LLIQդ-^8/nS26k,ŝJH7YNEoNƷʥOx)-ə6-8UvڻNmڈGJ0mHzI%Sfe)鍞nCx[;~.'[7UZi[ XGD4B[.萏t-Ln}ɹ8odFFFbDBFedd4DlF%Fl$A,ll$i%skkl˺<.3mNHte,VbjVmm!! l[]{z|kkF؊˃fh'vrjo"aXus7y*`3Rwe·¬[+wM\s#&~O]=CöU:ΣCCUZTk|׶lsqv/ovw.wN6,2-gZ~ToTۺό -DpjTm*޶qi@ #U X`A` -  %X 0 -ۖluUq^uF*lve6cWwtuN`g6qڬIS -ߙĎ\:f]ͤc />we7rcܰjdNHl[GYՎH:͹udXJQHg_H|˔w˱#ىMy /%v>u4+5=;gͳbתh"^M³ٞ:Nujm WedE;=S춂ZK[4Vm #\jӷt6vwZ H۵JY+F&ٞy~ɵ1 MȄT$,Fф7NW+(vH}|z5_mv3\ -8Tfbk}vʳt20p*˩ɼ婇9Zg:[I[zjkGKlqh[;}gZ;^U }ZWbpE%*&|#o Z6_,nEgL TPr?q" pʓ"A_ӫ"MIBHgSQewvb>LK_ GpEL4,9 z! /r*ʨ$>} up{>} ҎQ'.wI]atU1NX7$]i"6*>y[pzt;: O^1ɉ]b?_0ULt(ke`z+9;IYi nK%T:Z—͵.f|i4Y9+`Z#* -%2Aµ8|/A>]É@bFdB(@ed!uxg;Kg62=3K3da~(\P+wlލ;MEއܝcBkL5FA" g D`0&O|1g<nWS ZH朗GX#7Ŋ{uCG!-eRL% ^ Lj7ťM+ρcw"G$&V]nWEbPas X0c[Le#(*?7|?ȃm˛N4s}==H9g*v}砯+Yu],8Μ4>: yoUy.St5S'}(ƪLyH坰RH R4B1PD&H-NMf;̜ (EQڬ#k(-{4w%>\wR P洄3,K\|&&,'< ζHl$sP6D-1c_`0I71_IG_<־{vxar -h@ՑMAyUX9ʵSH#3|>dtsq S݈)W:s}}ҡR^}bGRgZJ4UބB{ ʙzb ,^? q)dD9L7Z)2亍805XF/GCz,jH -=5a9l0=:# -}y]nhSoίǶj,Y*Ee_ )]u62ς:Gc~OC=rI_LTpU]Mr6n['OW: \JƳ8C414%?YV7"\ǹYg-ȕU,MZF}d]ȏF+JI`k]%|pw~xKO$}ݕ8|e1qNlPiıGL)?e&~?x -XnWp ϼD7yP-۟䔴e(5)NbQt&nГ\{۸sT2t# {> CדjCoj8;0ȱJ4ޤ4AwƐϊ%&o%  ˓%R/;onpTK^槒&k)l98.UD쟛1@օW-<6c)C+^ݷFs\ guy%t8ڑe4AG>H, ?[RҕM9L(kذkЊT.)J%뺟#wޕ)ֆ~O 64*3@X"y̐4R) qja!qҦBu:(0}PɒO*BP>2bޭ׬Y0>. JE={*u=*+$AqFiM+N hJ3$Xr+A[xՁOLdNXʔ^d阺KspP/'3N<ҏ/4ɳ_hhő"pC(S< n=Vk0(<$jpb0FIuI˫d`n`6s>nVnW?% 8TPsOFB k(f\naC=~L0!~iuc7z_i":lR:JTGb1Α ߎ{lo(Ht9MR])HgJJt^. Al9x}i) Kl˽#N-^mWH5wk>c1tl_'Tw]dj U=~f$*KXGҭ7ᦫgh7a,1 `bM6f2&(]`rԪClfѦ-,8%1!W;DMg##/*$ h,44YVD&TAB_ uēdm{#)-*j^6uS2{抹fPY0E 3$X{.VՉJC9&/]_\i3/ hLW[g{Pθ:Hc1(MG`[n^l*"OJ0g`&WJ)gםTX ,DgE^a4" -J5q&wCkA|$-G \<..z5vQbڀA߉T1+:JIHO-uSW2e=!Bi*lzU'qj~(~hQƶB>+~v}M0&0xjAEZ/87>+Mm.m̥M}L#߼bӮyJGVW1h9,dh`LQ_u)@KVٕ; *X\=-WZ ")]^%j+ Ĩ?]S&? H y 1^w9X&Wr9DžQ -f7V9+X9+y抵? mׂK$aqt jEwSG\z=HnVbMT#]t]-+YӦ!|ּS9hB[bjW-v9[NZ9D<ŵāߖW Ҫ;^m2~m(!_nً;s3cPCo=n݈{,[~tCe8=Ĺ$W\ s+X̒=|H&,tz3{=Bh^a'M|&bfL~}::sc?IL,r RqH!6uբi7Tώscn_r4!Ac#N.$[r -lpL2VdFz$jEU@,*d޽:W'zr+_ !a`<q; Y$ij}1Lm`Vw[</1CI9z-O8a3/ $G7Cxs-5%~D`14B (R)”B jTg*%T2qkI K7MHASM8紆$ahh AVk GhK3N^'4"f(HK%+UYF`BDw4>utfȕSI6 .g<@Od&~Cthrtse_74W8Av Y3f.2#:-<)㈡K>  ZB@vɄA\Xh&f7ZQ,e7Tʥ+8Fxߊezmvsu{TY#/$RIF(6ym9vJfn`)h͛8h&JZzt ` QbW<-vsLHRrm -aRiJ!PS|2 ȚjKkG'ˬXs @h1%E?6^ҜwX!D`-@ &zF8WB:VZ-3rafC 0! -2־XY{m!3*g=Y1p8gIk4gXtVߟgwdn_=M@S!xKv&1PKÒ9OU»׼9Bnk:?Rs-h`+(\9}hPV] ={mX,݇EOYIrgoܷqv,aTY?cclFPu@K|ڋJ-_ [Ā61!s)TKDdwHpγ|6N|7O0bH sCOF|z/L'ލ3M%WMAGAwUe1+d f2=歞Yp3mp*ei,{ZTD5H/Qzz1dWBLIVJ* &ֿ7 +B0NBaw~) 4%/g?_eTjk0s]t< ?J*&kOwVoK/˦kw|x TW.|׭>I)oDw@Tl=YP;(K\`VJ>^IEY`}&8 `ނdWܾ5SjLó(pVY÷÷g&C8vwk;= jzt?CLV]=z4BFlY drh99{\xWɳI)>W%3v<~Qb{eLLb1$9?=ndWG&k+.o}%;JY - -%.hR -PQ1<~tJ(WM>8DNBm#'xr fƍJ2ZOkZ gQk -Y NhT -M -;kf'vɅ[g W |(U"iNĐ)eF֡K%E7Ġ+[ŋ4ZD<{7/ESmǬȆWNVCRxVTlM}l(:# 1 B,B'H,ЛflX(F:[(TywWI(E^O#kCXErE2|95կ^!Z$i 3Xh&mQ"rEQ#y 1dª"9b/@Afd4-Va`WXӢ[-Z@e -IWI_#Ɂ ~XxԶ;-{V&1Wx|f2*(e'kgэG,uB128?NT7-( ç>J߆j%.g䝒M3odn G\s'U=VE\ƐB$w{!9& l|l2HFV1 8u$bV=VQqpա%}wB$1mXgl\bGIo -tF 6ILL'6xٓ&9laCp~ 4es9ӊ ',$50䣝 9% m87{2Vgz7=,bcxяs~#)_ ټ3TlPjqNHң!@o F?A߂Sp'u$Ә9BܤEQ>1Beӳ7G q>Xsbpu#P+#|˾yȼ۳ HSbgAbC%c4$S}Am:%+^:[o"Θ .;(Մ<_ ]uOP5t?۬ '}d67vhWҀO5`pQڞ|@w jXkX4Ax:dF4n|)ԟy/QCGM6 JF>pGՐZH W;Z$2nªjJ3GU@xATVAO+Dᖾ\+$!krWMn?_48l>T"S ֢o.ݦ̧(9ḲMy8)v|6M`6yYU (`8ذg0OEP P?1(:%QwX] Z#1T61g've C6 T<_Tzc@be8֣z*m/Q֯nr𮗸vЂ .b=6=T/c}xvnY#0땊R_\ -f̆_V:'!̤k((gL8|vH3(p1TҒtQ,K'밪 yQ8NjX=F$$&L;͔'^no2#n[F4)W/ҷ7raEZ8kذ-9Sa{ ~@? P -:>"g(a;Ou$q~ PS8x$L9 e0 aMٻhb .A=d qTic|kyɧul'#aO *]D%nvE䄸hvs} DpGGYZeᵗ]'(HX,qa# pT[deܠ"* ZbQ_vHeQ]6ZjG{|!]v\u+3tK6YJU3`ʖQQƟ[FPg2} -ZMQG _hoYpNI$}.Aj%2m3JԳ,QwL0Wp/b,!rgKGb&DƮ?f4o263nSg@쩱\Zs0$}H55<0sڐ3yNw:^X.5m. -6Vt‰2b-XVj^ ճ3/VH"莻֤[e74o$yl@7qj 9*+Gg'3m(Z"WM #&QmSMaQ Yrށfhg(X{nZ&iqLB 6nmN/ . NW-& 6@}s0N%ґpxȡ9^ڋ-A7:g}nc=؀N>-9aLCr }&~ -WK" Xu:s bGԧKL!sBү4kqCKl0XI 'i$SNϮ,J5(h4 >Dm)s~ 325X5:Nr\HĠfuu^H{~;(d= B}0IbMV)*wl8>? ś}Q&e,e4sՒC;;f"1Ȏ -ެ1Yؐ! Q%x}!6%lÄxՄvǽ1 Tn2G#0JZ]V" #ޱ{[bْؤH#WBoӮ.q>Cϳ󷴐MQ%wAmWz[d c=*ZA e|Ɗe8:UØϞ3 ;s4>[hw@rf!cQuZs4=@ޱѪnj{ -}%yj jv 8(BƘ}#Fj3*ëa.6jDhȋofYB1<̺tShp7JW_>fOSnF!Z!UQMT]' B3\\1%Χ+Yot| Kd80Z2^azSr2(! 6Ԣ%Hijݔvke!RKjgTMzd8{]ElY3-ݨTrEpM -"~{nKYeqO)20eٌW&*'ɱ^jpn&(S㕒1 - -Ԉ?toFv1*pgU\p=wG^t @^.V[ FZvKpL:<)QStꮇMYTӑ$ЖNSL3|[ L?^::h ?^9 )ܔ`Ouq{=!905Nj$+1K}o]7F0M4^+}gFmGںpyx88M102XgR[k$IJ+HjUWU12_BadP).aU -ʑwDbdW\ >)UXD8:tA01VJIoBr45 ŬcDFNlj/-ᛢOvU#tXLg^V -^py?PR8k 6sҝ3(FN{[:db)9gںܯwZ euB,IV6.EpTO1MAMmR~8HsԱO3䈟%}{]%i)=EMF -əӧ!5Tr\[gCp:;/9@k֎߹FduI sHN[r+gF~d-h~k$@4;WB%ZHYzmAPFC5AVJrL%)*D.9CJIIGV |U+ c)Cw)2O:!JdRPœO yOg6!D1Ig \jnCƖ#B TNZ?gQci 8<ϤoުN4w쀞T -`ըvf - -)^iɬt$H_mlցwgx,,.P6UJtMAFWIH\Cز5d@ϥ1tpz˗WL<(+#"fGKE1&;Q.n&CIS'D~4Pz7AIk9{HU0aW | )z {X(@u*/:EVB=+D'`U=U["xJlqQj_;:z_~ PC儠w*:`b'),dsKѨjKeITW>DGvʐD(`:z 2G"n3Xk=V.i=m[ -o"F=ۍYC6ťmG|[RK -^';g#gpɐ%oHMhM cI*r0FP&8 ZѢ%w^cM!d٘d؊ j-8ĭ ^ -ٶWZaD%A"O>D;M-S)S0ȸJCEs8ead?&(Bwiܕ ڛ*M[>`$JlYQ㢔I'崄 7MJs]eiFv*Aڢp2ߴ8-- _VZ+*<ŎH*용GlOȪ{Lx̊éK%/r%rnNSj rhv[qd]XէH7k8Lx:݈ˏŹn%G8,1E  -[n3PCc 6MXwD5TJ`<( -ʢg#gZs._~#G mEp3tMf慆ցO+-M#Bt{ckS飀RhgRYo]}ggQW``;^j"a77N0\, y$:$ rF;Pӧ.4~})ĤS?mU}7jԆg80;B ,'R@"0'Aq[Z6b!q:D2Oޣ0ui?E*WTo]NI3a?V*EVw;si{ [Z*!/ -$PYO.c䡖hL+r犪*ɦ$,W^C䋹M4'טd`M(ig` ߉}\b8E]!9i^,ZeXfg.녁/ڼBxNZ\uZŸ( b$sg{Vf5'&X"āf ~C$#Cܗ],̕*|y&( K/X5؛5Ǫ,f@^\Oi_|Ie;T&QͥCu0AxR,)0z[Lx]kjGA%i< b( E9;;Bw t<Ę)C6-E2e ,QU-F *{:i/>|~~醲hGpݸTIz-Y>.-}g]&<,Yz ,W>hcBICHPь'>tnqgNVH_E9ߥ@FC'ٜ50OewO!b{=V -s=HV]3(ьK캘or1ojf&)3–0h˄mn#F+Ca")'6C_Vbs[!cNݗW$Z~ICczS~l`~;{֐_'UiQpLHs9^-LXg"K1r*y[j@]8`6\'C--4y!Xaء]~3 [ƈ|j"Ht!M%2KtF+2) ,+3UM ; S23ɚ /B`Рyg`NX\kzf]a3*DܹAeX5*͋ Bޛ]Üy#j:^PbϚ(Se\PY49Ja! 0,G2]잣b[.8fsmRq>-·l(ݗ3b@ 3+YҔ4'qYJz_6N}]:2Ƥߒx }4 pKlgѲn"A q^&*spځue?T -kEnjo/?|0\J7ѱ + 1fgf|c!~ XX$0Ò"zv-Z=ыެȭzql.u: -,YK]p3laH{kOH`aymj ;rAk q ª(Jl dIV }d_ w|}]Pex<Q<+/ 󗿄Li;{r6:MҸ(sBY]dt1 BAy8I$KCpiPAxMjg揾NM#Z=+nhK9-*F:*Aڐ׍MD%ӛҴ>POOIZ5|l)Ovj>;թϡ`V@) ZP:M3`,l7hU{@%Bŕd)O6X/P%h+s5^2Ag9ШZǜwd!C"|6Crm/6 Z1u3mh<1[+Jޛc(,Rwvi -⒀fKr:{&JE[tZ1Ŏu~Hȉ]c*J4 \9fiXiwiZ-2Umh@ǻO#$†NlDc,6>tRL>4B>6HTr)/{8DiaKġ9ʾS Yb7mO B|)$8Wڏܨlka3[rgO7[ѡa#1zxSP4UX)j:Q*iĒQ_x/'X5wшs:D4]FLnHV6#" /NMFpK@>:(u;=D  -T;1+BT{m@D =dDLGTYg1_>R$2A҃~+b!!_ޞq'tWKOR+ُ۱$܏IgHҩ&%Ѝce@e XU sYo*ĚB;n˴V<gl4?U7O:-sJ68[Ȓó+:Pn|kZ<‡> =.2ڎIGUftjG$/楢H_@i`P n6gfGN5+]kCo*>wo9MJ>PDH_?yD|P?5A2Zg:fpnnh+*^ΕѳU4h'a_ <*,kWam`}3 n=3(0F[=c_4FCT_b.s^&a Zᠸ7$| +E|mF!V"- ޜK-Ї3B!w#Ǖ]_>fțv<{ /UB-EuVs83"a/)xǚLvwǑkٰjUHKu'ƤxᵞabIeNޜM.lZxlXVp"d3TYŠ?{<џL" å]]4U!m0q|W"ncB0fzID~\U -JNT .">&etK0}F4zNETjMkz-,Fu2XXf]+aFfu~z 쭖(%iDeT*ClAɃq.\I/6z55D;h!=ۘe@>1~J ׊5 I%zP ҷ!2HaqMEvEզL 7JÝEoHO'/   -nE%*$zdsJ?\*bQ!q sx8> SI[RF$ ^|Ƥ$`39#򬌬D4MVӪO[Qlc^7PS? 5ݽ08:r_8cJ62sŨO)'HC"FD(H/M&)O,R˨y5SF h.wMx-ط^`5hQH5ץF{ N|rK?`"rݹWT -hs U -/$ $wb)B/qefQxFj1\P^%CΧśL7^J(q?H]ƆWWSi+U<2P3Pt=d[aHҿ.}䵖ɝN@V:}ű?/:wl[Q|6U9njDRÞĥbW"о\$+Tn]$_"Bncv&ޗ$S r -JrΊ&;EP yR3?Mi5m{]#5Gv 3Ơ1)XL-g`$#^B׶I3M" #L# vD]Vch,!8r^t¦2 mP@|I$~2Y%u4za+ Sx/>Ѓ0ks&,=_\$WTB z\#("60J4u۴MQ@RDĮi)8b"EN.xϪsWuk{v<Td]z6KuX lI 4ެ$7Chd, ^qY9n a7&p6Ϟ8CU t:Ԅp!! c4S/FO\W׶=f*崝=)aB-? :HK- nPf1.:wж~_TbH?5 ؾ4VH*MSE3X\̾$PCg0h%NܞAe7ϢACl'Iذ`㴍YfRO#"!}bUAQjWѵjĪTKԘ --qceCrIpc!hOE佖%dFS"h"^"fnJ]f7S)Úf>51XTY@򦪃mTa@c6MMB01Ͼ/[) ]Ie@Lp0˃ڀmP4^N/XY\kYᐟN"ZmH‹0°"{6QY{RT[;uRݟ((crj/:Nҗ K;E̜%gŁNx WA2b:X.O3_dK'$ fr:uSPJ;:BU+G -?re%`.r*X-_`ˣqB5mb.Yz% -C]ON|ówtZOzEF󉽐R 2A+`),Ƽ↛`4"?򱷢j4;!|Xy(„۝vOM92Cp`"sO6Ӆ-%Xsxŷ֓O!:Y/wVIg 2HМrB#ቾ T-f`萆a^E3nc&D{i4D*n,]Diwך)!lt -8ӰHTpcr`HE+m b9Z4/Dr>gǞ8H'tU[EzQ=\e,1%orS.at/'* S.bbl 6B: =qZ*Gحj>%P׽ʌ%YVȕJix da#q{'&7r)V/cYBhc-r1ʞ=\amձSw s;q@/1ua'o>Ql_Q:k{ $P.dNGPz'vu~V{\YX٨Xv -gjz͏%oP|o nG/k> <$9vS7 C?IF2;9 W aEġ:eVݰj&ubzhz}q)Ga "<` -IߍBŢoƛBv83A^~@VXڛ9#F//O({st+aJo8AfxU:Ln܊wwewAZy+d?Ȩ^FwͱYnJ , *~Pᆫ/ƟAY!_KG%F̭ @6Rϴ "N& E.9J| 3xcsCZ[\?IӫIkv҅u?9c(W|W zaϔ\( welREGpq370m%[cH-ҷ4%w/ܤk -983t1K {I-Lc%6|>s% Z'Y˭:Q;T`=Ǭz>7*nTo2뷁.zRE,w|`;; y|M5Q웒q2? S_`|f&,G(d`p~f~Jll>R#8Rž7Zp/"LEğg,f/@<%"u_zlz~v' л‚ -N^}H#oLTG@DR -Q A KeQiuznKk&pLvߘ_clMdr Mq~_/;iѕaŴW j\[;}]][oLݦ;;:/YC/.;z7ob;-Mkj7N=GZNYqZԺXI)Ǣ&u5 k8-[r-V+J}X<{`FY*=u[cgsWg@ /fyܚ}[W`wF0K87M9j񏚒:jP Y,Ǟ7j.veо:%BIur^kenk'5ky1d %$ώ u˙E[cl(u՜slIHXo}[sճ>.+b6 j:O']Ku_sk-ںkaoq7n u tuk-ΞK$D`V:j`mJv FױVS:v @˿7;)fo_jC3 zfXНQkbpZlNW"uj_l,Xl>XK_@O~+}o Gc}ܹEo b}]Yfэ%%CheմxJrDQ$۟~oI~gF{w,I^fI|9MT}4Ϗzg2w(9I:Tݡý<ߦ?{GmnMDMss$i(Kϒh;'Ms;Os{h7hKr49iv/OKM:2/wqswo-K?$?Ϳ'ei4OS4MqoztuwID.}sNzO7Qݩ_W(6ۇjeƕMO'En';nh7.'MqwnYNHmvZ f] b5[dz~oaWS{X6@\sXm[! rmI}u0t%wYzn<k~_44!OKxtr$$ɩgS{)Rz~}'OvTѓ$;ɩ܋go$v;;jޛL~/ڝ#w'͎$xsγbW93Onӗ_dIzN&}WMwdi{izN-NR-MNYi>AMfmAJQ0F50M1~;`/2p8D.iF^D͒Rf& mL,jݖSruu*8,;ʈr*ldT聒r!\JK()ia6-yTQ`&4cN`7aBZ]1S!5Q5˒*YI-g$ Ɍ5 Db%Y)";(M"2xkg]}Zp }fmɗ8/ pL7k-ntFe61j` Ҙ" Dp  AOT'gRB &UH !HT Dz$?/H@n`Aǒދ" 3 i!C8m0>Z!5L3PPH -DnXzl[NNgWӤGM0/"YyȔ>n` xDl772Gn.!ύ>ޥ,xCxx" KɟŃ<0(kR b!BC<:4R}\z17Zxz~9Mo5HQ^9yPך4>l - PR -"%<z"#{a>wϛ -;Lo*yާ3`{AM*Sa -+L?nr0R$  $+9)>B <<4V 8Vy^G0!6A-. -, !T>&x#/FnFEE.L.UL~)|tvͺ䣞籠-mQ#ܪ -WxG+@ϣvUy'yо$, sEq(laVS"Q\ٽ:[ijF(m?H:\3XtݸoP~$aMb!fy1<ωO03JT%JʮGؠLDd>DP'UVZ` %묓γ`5UDkD:mƏ3 JA iM$A, nM -xx:,՘& xڵҮvq7IGQ)D5Fr.b 7LZElfiYTWxL!1lT2 UBmB'L)Eu'E^>iM itHCt42L!>hD;n`[U : -l>?J4ݗ3\@~ţᅎ%Vu%mhrN48 rI,I"x$:i=-yfV8a@̣NÕ%ś --ޕkr:} - QnZӵ> -2VP| >J$`~"a<?Nb-b \N&&ֲ f혴! zͅB̺N)┠$0AՊФpSV * qA\ lU HnPr6ZѺͧqlv6,$4!D^, /8q'ʣz# -u)\wl1 *H$O+DHS/0YTIJ7UFl$0=Qϝ$Pf!% 6%i6 ehvhM=F3zxF$(2QRV)[nlj?E.a3|[PhHA}( J/B>LmP"P 淏- -j;gHT#bu|h-F8CȂCFVHa 6(7 -DY9E `T )J &5H"?n6rZ[oZ5qEI!W79Ō!#PkEٜmG>$iYhv*P(%8yj?N6 "o8vm; 8Wg!?VОFQ'ŏPzn\0 4(h|\|BŤū"/ pBI_a54c?t_ibۡq(LW'AqE o0xJv e]D - ݊DBoPNJ8dJXEA6 fAaP"58>i@z-#lXy@1qd[vjAyV^m@[ϴy`w|S3f3ɩpe1"r#h|FpW)V|\ICǒ/> <9-e0? 1I< 39- j>&["_(Cfey"^mFRAp6l(RCA"=&tQ-2zZIXE-QM~>0-ˮe'fMWh۫h*~P -0rAfCF*j+J;=؄uڊ&Z_|d߄pܣOCqf'v50BέHwtu*<x|u~qiwWI*2f{)~:mXnBy]nY\L\f"vPc*}UZZ3 j-Ci<@ȄDZ - \^r 8HwiT=33/i2V!ԑ]|2b7S{,>bo+pxڿ1d{@jy>YLBq:8R9_ bvyH01\Ɔ<D<ؔB`_5jբqXm.L/ 2tW1,2_Q҄>#ka> ͣ$$0ZdPрB\Z& 0%D -@1qjx@gA2}>GW->fyn3`gcQlMtؙ5gKpf23x #FfE -aв|ܭ|R=F iN 1*aZ}Ŭ@i<ȎxCX3C"3$醄#?n?ICY66OCWZ"255(0`4"ZULnW`2iP"Y~]$$r7).0PpGNTJYIÉHiI\wt?4)CuNS% )oFp -34#Vu4*#ѪRkLO{ "q0:K'!x!'4 o۹Kt# .h}}\ba?@1*U>&S 1 sir3HB$%} xj$C&29 e.ķrHI ӹ5!X?5v(>L[<‘lyC䓖 -|d}%e%,ONy8{&A7uZ{~Z SNojF2!qd#;RF;lKjQRxM'E#v` =4X{U_Q'lY6bв>,{wq︁s~l4> G+?MMM U"T LÝiUW`+hUtEБ6#;iCzx A"ኵ/'TS6Cl,? v5XjOC vϧ -+>"'LjK}`= ϲ0*.iT,.ԐwL4'Ā<]!i NA˲AOC?>? kOܡxq&.L‹'>? P|9秡(,|C.HYG+aU9Y[T0$5q-XAVJD`idԁUi5him9 =\qǐ?n@^,[1U0igƎ;f7j(p7YWm,V~XKLBpвl$F@p|4JK# DX:E2H4 BIJDž||( jb,<6c%~ ayŴ{A5h;f$yXq8#RF/8ӁtnDž -<Vֶ6iϺ5n\ٓOʖ,^FH$ -O30Kx4 V .lbdL)oi iA.8 ~zd- ojȈS<P([~ȃr}Ut3T(׍y*[T6!&d)$6v\P\AO0<8%8% ?ɲ࣍MwAˀD y$>J&{h I\5ߛŌhl)~u>,606啒mq̲%6PSUi3=)^[8h;(x--’ rƏU -3n4 -ޢ(8²{~zkKPM7T%hC3.g:rj(媀Ǽl5UmXfyD:T -DZn y֚YӐv,[E˲Ue*mw}N>Yd>G>#g>,o063151ROCX6ZuIY&EƲXyiq^+H48NF !0xApSLPh9:vЁ8\0,KEr=/ʺH#*{*t"eD }e Ty O~o]eTbU$ Dp9AAI3>+ぱ^!<B+R+& 32>5^ -hUa9#g,"+"UOƶzQǙL hRRKr媀vt=IQINRb[>y$H6Cl#l@p4:&ŤudPSdo9~1zxgȅA8z̮EaHJa83SB?0S5 /imGxԢDrEfYdk%\8ep/'N)+JqpƓI Y Zoq^Q(ᜠೖUjM87(E"P߿^C&.`rE@N<2 /Zt8Ej9AIaвlX%ecR! -I&%(Q9m"r#$DL>Όb廟&rl<湑x~ͨ%G4Z &IW4v)2Idt73kMg3\ɖVD2hj f'YMQ)#TEF{1i]D\=O$2Lв<,[y4d|#7 `j xacj?j]&'#\ - $ @-U}e -3XBЌc IŒ\KhH$H<@40$Ic0,1((R -vܥ=^ -=w gUiLJsjnz = Նxwu 4ؙ(qqJp^k ;6Fd`CȈ18ut1#}5?c R2>XFM3#ò91LDׄP`q4jV볷fYK,mAA8T`VzuZ4f"oo=3}!wH#$"$U,K.}2WUu$UG`_&͓n+>gCja$-3<12Ղ,dᕥ4ͤlWw 2WwsWޕr&WGEp WseWӱӰ:^ɧW+~)adwgtTb^qV_)+k8B{ZW-~BdZ1|Y> .#֠dkXD*Ѩ:%;rJ\,Æ&-:Tcr^;ʏ-h3U'P a,؏- *䌉aŃ2@@ˆyF?A|{0$-С)Ks|קiujUh#pkeT9Ы'? &MPx<;9/':XUXZ鳙OF|uoDf {M}ƻaPU߄}ϔ3plܶ؂*:jPI"UkNY\Xp=~산ʾ>T^c^z&uoZ)^n: ~K[~I%SEa tsŲKA 0Xb:EBU@7/ znH -se% -oط|z.#ʜ 2_ڍ fԬaa:Yֆ"$J5uzI9.xe5-mA|ݴ[`Ḑ.&vUP/N Nӕ4&=@z f歂AiC_"%~VdяfbTTFaaڇrc+Ŭˇ.hZD,<)8)6$KsJe yl,Qɾa_>) -3:v\+&~ l k%2xUiOJ<5OyTiEPf0eh?̓=$nWnV'{)hQEx.U<]qp{x","֛ e9`%iPEq= ͏ΒO݂d'D'PφݼISRsۼxJ̧5@xtmZ$ .p6xUfkŃnI_!l]11oA{Et0d-,dK̴}j -۬ժ - PdK{ -6qz>/#c'1X`EGgM;aFRKdK'@ 6Okqت!mG !AyL&W~+X^8٘Le@+BJյK/%" $)pn]±5:MbU3(p-C+ ҹP01f+f>H|>-r_UG)p̳qDG(ІH\$tjf'YPlbNfCVŽxD>8Ȕ Yv(I\=g>f*X*sh-/It kx?U x2.( 90b2L+٧a9 X(ﯩ3; )nR'1iHQ GDO~L}bӵ1FG- 5ڲ pqR.$~9#bJYoȩ˛Nk1f ٨5dWd i^Y-{ܔcѕ -CP -z浭Y.7xj.=O"7DJYD1W-E Jcزul -kFBBMDƤUa /ޔL^!ÒԚ ->Vzt=5M¨D4$4kn3t -+"_L3>-L.xYӞ$ $ŒWUaMϺp feߎ(\#ӏx4AL_W]Jv3"I ,kkOD-O -F?Do9҄%571Yf$D|ɇf.Q1Uyl 4cCLf{9,inSTx>:MK73N -g5Md 8 HIMS|\@d[,VҦ' TzKy aIbe$V5:kh[_- U/a+ʨpZ2Ȋ3S/XZ{PAN -̖ J2Mԝ7 eN+ e_Uovz`N`L9B=W$Cuš?.B*J2`G첲:LZ\M4ĀTaQrǕV6 6 }`.QqA4K̳QS hKN f|k*αgWQ/O>hp|8VR\2U:pIZW[NCm]m)Pg פs^!UF˺9}kEܾ'wnm띩!< -1&z"SC٥v1]a?!A6T+*L]n<{MZnRqpJ2 NȘeD3o0&]P/ۥ(;}+5m`E|(6ETeUa +$ [2*rVR@̧ARrň݇#aCyvJ#|^ PiGE&nF2{6M|zT s lHSmhƍ4pG%KPu8ؠ4bo0"ZNC3Cx4fW&1" 2Ͻ`Ⱥ+s-ONb{.%2`Č/XA1Ȇ6@^fQ"T0JE1y Fr%-c-MRvCXx;&)t OLeA?\JȩF oj`c5TJQ,)0<:xbhVZSYB~ nD 6:򳽜ab2kzg# thn $dݨ5 i @ %褍!.ǻ<21е&t^^<\ X]Yzaz-w ^@5ԇ1,zz{;٣ taPlg,*/r #MXH솰TC~lú'Jf&eBg!6Hw1Vᑟ76 ז""} x~\ )}*;q)btKHA 1X()@)#n Ѩg)w{0ǻ1twW (iM#S ,xO`ti$6/~'ݴkMyw-xWr$޵pW)3:{wMĺtt= -G, t{HC*eu[b2k΄|[3i|hn -WҷV#lmykEkrzN1@`%ħ3MRYpb<Z gaW(Y /:%r$=D1+^( 3=p:XSnjGdZTpC 0 Urk RAş -fթדg*$q*/|ݙ9Eˣ੒Y9B:MfYF7 -u1lBk^F8I"̗Gn/.4A4.`ɘՏǿ~|T_>8%7g]~`v-֓ϠJiRaEFr9uD9; V5z* -,w?F^sC%$.Bqm9Fx(_ .w]s ҿj{<"\C~Er312y }\8':H>;FvR-vt:|2> dr`LhZ0SZ@/feO12^yRV&Z 5 -Lw-?gXeeMx~;CHlW|a:޻V'wQbǩ.M53n]ɞ{ tj}\;5޸6ft\Kv 7 FSCLA'Jyd-b¯SdÁhc `w'=D;V- )Lu ]$宺nv0ov>n #k7. YO.R7r"-NR?P ȺO'sgc E뇺@ cLb.@:,{^E$TQG25$LRT>IYS22iFKJ@Zz9k3@--',L%j+jʔXK՝I,%?P:M@VTp7h͔$5kTay%|D_ -WZ YK=%=Q -ۈCObu8bX~xxd#Ѥ1x9yѹe%ܺf5 d 9>-RL@V?,EOn>7=^p*Os4žGBbw aגPl @o*z/ wP֤cJ% -ݪutY[m?D>K;a}WV"H7*`CX9rsP5Q5[Df܎ènRKS;?X ùMF[BwZHD}V3ET<j[YƐFclOe_N9ŲE,S;p JjkBDP>stream --kʠ=¡5F^?wnkbcw;l'&%E{8 AægV$J5GI.W6nutPd[B 2[V ߧkXXI7suVH,Xd S\JX`kNE8?kgnzd1o~-bM_}Т¥<#B<*j -97{V8]T@Oi.xpYqFqj Vjy:΂;HJ6^g) f|K"ȶ>[엧gY r[o%`F)[yvaԉk8:FcPXLN" \`IMh6ube hA: -|;8ˈ:•3`< -ju)]_4ؽV9;~ݴ$je]N0o_B}F΄cRD9o(NI ĞL,-6 -/?lv,Z#Рe>Ozzgz&~#=[ۙ?'tfs6 47C3 v\L|JוٚmԆ-+I+?jݬ5*Ue_Pg}U32r$QrGZ.x%&4 g!o ` - H;?#Y wGC/M.6]%S{É8g ~D܌s_7A$es(;C}9o/Fc' -Kx9TK37%Cvm{ьAIH-$V.p hE+ VNQdVCM/ɢ{"޴4 nlY<6d֐Hsy=l\_&xWseTy蝝z9m]zzi`iFf)QZvw#—d}@ΐd3ۛ t6a5QWD"#)~NU0`C*UxZ-Q,śAԂF]@B/,\cuٴM1"bO-[?rxїfΧ!.@X dy3G;i^zzWoGqΙ.a7NH/X-[l]oQc}4ro C)J~?Ռ4a4;厄BHn"DooS.b{*c?&8Z5ʍBtF3uiqFb3)/i?}\wM1m>0)3sv)  d TB&P/N/A&jK!Ls0+|#/p,"\M^}&6?)tdw- w^Q$4{n,)<>ħ'uzɾ(~eRbJ'yRCQ -(QݘxSʊ`/Sѹ q~3aat}bOz榢TYB'0vbIejXZX 2:@eGL5j\1gzy[Ď(uZa*W(li ^{Evb &3ꚬA3mIa&"6˻}i|Tu%S}Rr1|{T "%'p,׈(9ޭ F-Λ8O^D7F08ƒUQF8O鿙gǪQlqYDt`NRA"A"ܽ%7 0dtLȈWiY&NpFODfH;I3 u&5Ε6'Lw*=L"׌BzS -{t6%-^8P%]t~ 8+ȡa_%iIZAU[FRyVT@&E:ca+ (z!ɫyM Lmf8j6Ys\n߃'&.:~͐ ke?-kNm/l}^>q3 $H#y|L0`O NL' 2sB¯-NP&r":TC*vM,69gpVDa3Mޟ%r.ioפL ծKφӅHTJ #^Ruch pܘ0Cc}?:h,5.М,ͳs] -8BTא@ m~X?3ݫ ѣjDP/LzI۸n`Ă+\W (j7J:V"ލֳkEHk3\bŰ_[rSTGcpWM&7ÔDRV#?; ?`YC W7Rh!ٛuU_LޝID49:ȎNj񺽐e.i.f`Qvn66uv•#%mDUhw;p|F ZZ5 PXô5 QC@՘ -Rp. 9 )=.)ڑKՠ;E>b;5|iھR}}P$Zv_츺GHȍ[#(7e<_&.DȖ#J+Xߐ YlAz0ߤ -{_Ke[Ҫv -+ϝsޔ5(TowXA[kũBeҲ(]n[#v2xF<%j˽eruy_ej#r98RL(fN9V4۔/` &w޸eX;U)! ؙfF-R }$| 6 XҴ\Sym_!%~Sx<`FQ[e'RQd()UҾ+юWtޑ4v3ߗDx*XO@fh]d4y}Z, XT{ӱelg@KɑsRXh~!{$DwI­5F;Lq=ɯ$=rn8%L -6[kdK\Lc6 n7+ -3Uྫྷ/ -NgJe@U -شrM|6D"O AgCLhNUk̖ѭ>;삢5CZQCQ}(7o2ܨgY}|%=g%}6ƁhS_E4ⵐd*4#pW@Y#p1 Sr'%i&Ȱ;GvyCrޡBc3RW{q /D {]9WCnT[x2QL YltkMíڥ$l魃 9#͹l>ډ <h˽?|Q3_[^u’@5ڇj@h8\6"Ύ_6BMrܡJ%"JG9 ؗݕA;U|vsE)H7d,,&X*e- Pj#&\4N:ذh -bYm-fP=jbE(%1XQ/8Z2*:ƾ=oE$欏m_)]:퀓E-wBWh`VwE\y)DOlG:RR%=QhP8}VL'YύH Π 0]8"Z`9ڦ -Y+ IU`ڔjHU1~\ -we -9Q_H̃D>rn}$F['yU@jtch ܣyu`˅~ Tؾ 5|?tgӪ]=BLӭ{fXT_ "*743Z"~ ƕ[VH&ouf B;rnz`a@v0Ivr,r*YG~i>tK [t?KgϿ|NǙB% -2fn}]QHٯkkjBfSnK{%2Q,@Io psF1yطUBte1SgDऺTKX0 !LuH"wWY_^kʮT Q/K-HCca7GHL#}hSw#)ᄻp;ă?ʛqK<+w|ܚ2I}88,ۧ(O9mȚdB\N7/)l6 erC0$Ps,1PEcZf*PRu@P}gw/4$nBӪm܀x9`]lT0`\U0 "&0Fn - J4EZZi+Xŀl`|EIL2"Fdl22 E80"`4*, -8 :P,Lؠ!'|,RC>fBH>HJ4ĂI 8h G XReVV ăUfO=wd!UfMdX HB0a2):QG͙CZ`V& ‰62@gX1*CJI2R2ጳNgmT0:kqNQ8X&!R!q HRL.E:g\l}Jl]kokW̼tg&DnKk=S)x')(M gdi}PXPR4/¡a}4ʆ -u> -*6D&)&٠|6BAsV-HD/^mCVE(as=6mZ/ey=Ie`QxlœgL ɤ΄ B*L6NMߓMgrqH&);ZxH+4Oy7-]WϻA wv-[jR)w--U|}t7=jt]͜Ю71{wSⷮDjbF̻Få.ULgHMy*3\yjOᲦz-:']o.WtcjinRfȩ]yu{/%PRnn/{jZ:lD rB' *LQd -|TB,)r"B"Ϩ8 g͕xomTqaSﺱp*q՚q9w7零]۫q/>?d&u뭚OMkLM~|λ wwߤzz穛;۹yQ&]_)'~FW< -u6*#+Q⋘t -I"0d -@s dAFD `ه%y2!.)NeR un H'!OP4]dw2$RB~KE׮JJ`_(%0`h!Xe`] :4M#o+fwCh͈AHCi<Ƶ; tx4i0Wp(ݷ~ζiWP]N L؂q?JJ0S/a.sl9 M&P׿8qghUW_TǾբd䤭Rz$:*b.xF5DzDBt B,"8ɉox[M'>yd\?ҙQɡAQ'$静5ۮB$-nhۺ^~q̓_\,ӈmw$>dbj!B";8B~<` qe)UE% ->f%:Tځ2 -t -7:'}2Pò6.C|TZqXI*CP,1_H32|ju5 $*p´Ga_؈OCdQ#lqH 8B5@L*, E7QXt ePʡ'R\H #=釓@dHk R1sqs>ꑟR{"]d3cxZs]QZsDKX -3!%n"bJ.~U9e`Cb{_̳3A#nu.*}#^ȝ舢BAjӒwȲ,%鼹9]4Uҭ,l]*m'ёN8rq"*Z*9Cd)@+=0JD#Bze7Ja?h "c -`8Ȏ )"x5pHbL2cZ._n5B wT)eڍ0-yrw٨+ʉ@euf"RB 2܀yșU7d{o:R~SRTlJSk>HǾR-0摍gveM7$b1|H> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000044902 00000 n -0000000000 00000 f -0000044953 00000 n -0000000000 00000 f -0000050807 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000050880 00000 n -0000051120 00000 n -0000052281 00000 n -0000117869 00000 n -0000183457 00000 n -0000249045 00000 n -0000314633 00000 n -0000000000 00000 f -0000050507 00000 n -0000327703 00000 n -0000045366 00000 n -0000047466 00000 n -0000050694 00000 n -0000047323 00000 n -0000046249 00000 n -0000046762 00000 n -0000046810 00000 n -0000047501 00000 n -0000047859 00000 n -0000047614 00000 n -0000047739 00000 n -0000050578 00000 n -0000050609 00000 n -0000327728 00000 n -trailer <]>> startxref 327929 %%EOF \ No newline at end of file diff --git a/misc/branding/rounded_square.png b/misc/branding/rounded_square.png deleted file mode 100644 index 4f8c439c..00000000 Binary files a/misc/branding/rounded_square.png and /dev/null differ diff --git a/misc/branding/rounded_square_outline.ai b/misc/branding/rounded_square_outline.ai deleted file mode 100644 index a082ead4..00000000 --- a/misc/branding/rounded_square_outline.ai +++ /dev/null @@ -1,1781 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[24 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - application/pdf - - - conreq_rounded_square_outline - - - 2021-03-19T18:10:40-07:00 - 2021-03-19T18:10:40-07:00 - 2021-03-19T18:10:40-07:00 - Adobe Illustrator 24.3 (Macintosh) - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4qxXzX5/0/RGa1gUXe oDrEDRI6/wA7Dv8A5I/DCA6rXdqwwekeqf3e95tqnnPzHqTkzXjxxnpDATGgHhRdz/siclTzOftH NlO8iPIbJOWZiWYkk9ScXCJt2KG8VbxVcDirYOKt4q3ireKuBwq3ireKt4q3irgcVbxVvFXYq3ir eKHA4pbxQ7FXYq3irYJU1BoR0IxSCm2nea9e09wYrt5Ix1imJkQjwo24+imCnNwdo58R2kSO47s/ 8t+dbLV2W3mX6tfHpGTVH/1D4+368iQ9NoO1YZ/SfTP7/cyPA7Zinn/zY2iaesFq1NRuwREevpoN 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 - - - - uuid:45104e0a-8590-8447-a1a9-51f3a96fd016 - xmp.did:fd9e56be-3dd9-4d76-9fe3-1ad6fd5dc13e - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - uuid:7714bbb3-cb4b-9e4b-a7cc-ba1f08c54dbc - xmp.did:09a6dae5-d973-4c6c-9883-0fe9bfce3a2a - uuid:5D20892493BFDB11914A8590D31508C8 - proof:pdf - - - - - saved - xmp.iid:fd9e56be-3dd9-4d76-9fe3-1ad6fd5dc13e - 2021-03-18T19:51:46-07:00 - Adobe Illustrator 24.3 (Macintosh) - / - - - - Document - Print - AIRobin - False - False - 1 - - 300.000000 - 300.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 35 - 31 - 32 - - - CMYK Red - RGB - PROCESS - 237 - 28 - 36 - - - CMYK Yellow - RGB - PROCESS - 255 - 242 - 0 - - - CMYK Green - RGB - PROCESS - 0 - 166 - 81 - - - CMYK Cyan - RGB - PROCESS - 0 - 174 - 239 - - - CMYK Blue - RGB - PROCESS - 46 - 49 - 146 - - - CMYK Magenta - RGB - PROCESS - 236 - 0 - 140 - - - C=15 M=100 Y=90 K=10 - RGB - PROCESS - 190 - 30 - 45 - - - C=0 M=90 Y=85 K=0 - RGB - PROCESS - 239 - 65 - 54 - - - C=0 M=80 Y=95 K=0 - RGB - PROCESS - 241 - 90 - 41 - - - C=0 M=50 Y=100 K=0 - RGB - PROCESS - 247 - 148 - 29 - - - C=0 M=35 Y=85 K=0 - RGB - PROCESS - 251 - 176 - 64 - - - C=5 M=0 Y=90 K=0 - RGB - PROCESS - 249 - 237 - 50 - - - C=20 M=0 Y=100 K=0 - RGB - PROCESS - 215 - 223 - 35 - - - C=50 M=0 Y=100 K=0 - RGB - PROCESS - 141 - 198 - 63 - - - C=75 M=0 Y=100 K=0 - RGB - PROCESS - 57 - 181 - 74 - - - C=85 M=10 Y=100 K=10 - RGB - PROCESS - 0 - 148 - 68 - - - C=90 M=30 Y=95 K=30 - RGB - PROCESS - 0 - 104 - 56 - - - C=75 M=0 Y=75 K=0 - RGB - PROCESS - 43 - 182 - 115 - - - C=80 M=10 Y=45 K=0 - RGB - PROCESS - 0 - 167 - 157 - - - C=70 M=15 Y=0 K=0 - RGB - PROCESS - 39 - 170 - 225 - - - C=85 M=50 Y=0 K=0 - RGB - PROCESS - 28 - 117 - 188 - - - C=100 M=95 Y=5 K=0 - RGB - PROCESS - 43 - 57 - 144 - - - C=100 M=100 Y=25 K=25 - RGB - PROCESS - 38 - 34 - 98 - - - C=75 M=100 Y=0 K=0 - RGB - PROCESS - 102 - 45 - 145 - - - C=50 M=100 Y=0 K=0 - RGB - PROCESS - 146 - 39 - 143 - - - C=35 M=100 Y=35 K=10 - RGB - PROCESS - 158 - 31 - 99 - - - C=10 M=100 Y=50 K=0 - RGB - PROCESS - 218 - 28 - 92 - - - C=0 M=95 Y=20 K=0 - RGB - PROCESS - 238 - 42 - 123 - - - C=25 M=25 Y=40 K=0 - RGB - PROCESS - 194 - 181 - 155 - - - C=40 M=45 Y=50 K=5 - RGB - PROCESS - 155 - 133 - 121 - - - C=50 M=50 Y=60 K=25 - RGB - PROCESS - 114 - 102 - 88 - - - C=55 M=60 Y=65 K=40 - RGB - PROCESS - 89 - 74 - 66 - - - C=25 M=40 Y=65 K=0 - RGB - PROCESS - 196 - 154 - 108 - - - C=30 M=50 Y=75 K=10 - RGB - PROCESS - 169 - 124 - 80 - - - C=35 M=60 Y=80 K=25 - RGB - PROCESS - 139 - 94 - 60 - - - C=40 M=65 Y=90 K=35 - RGB - PROCESS - 117 - 76 - 41 - - - C=40 M=70 Y=100 K=50 - RGB - PROCESS - 96 - 57 - 19 - - - C=50 M=70 Y=80 K=70 - RGB - PROCESS - 60 - 36 - 21 - - - - - - Grays - 1 - - - - C=0 M=0 Y=0 K=100 - RGB - PROCESS - 35 - 31 - 32 - - - C=0 M=0 Y=0 K=90 - RGB - PROCESS - 65 - 64 - 66 - - - C=0 M=0 Y=0 K=80 - RGB - PROCESS - 88 - 89 - 91 - - - C=0 M=0 Y=0 K=70 - RGB - PROCESS - 109 - 110 - 113 - - - C=0 M=0 Y=0 K=60 - RGB - PROCESS - 128 - 130 - 133 - - - C=0 M=0 Y=0 K=50 - RGB - PROCESS - 147 - 149 - 152 - - - C=0 M=0 Y=0 K=40 - RGB - PROCESS - 167 - 169 - 172 - - - C=0 M=0 Y=0 K=30 - RGB - PROCESS - 188 - 190 - 192 - - - C=0 M=0 Y=0 K=20 - RGB - PROCESS - 209 - 211 - 212 - - - C=0 M=0 Y=0 K=10 - RGB - PROCESS - 230 - 231 - 232 - - - C=0 M=0 Y=0 K=5 - RGB - PROCESS - 241 - 242 - 242 - - - - - - Brights - 1 - - - - C=0 M=100 Y=100 K=0 - RGB - PROCESS - 237 - 28 - 36 - - - C=0 M=75 Y=100 K=0 - RGB - PROCESS - 242 - 101 - 34 - - - C=0 M=10 Y=95 K=0 - RGB - PROCESS - 255 - 222 - 23 - - - C=85 M=10 Y=100 K=0 - RGB - PROCESS - 0 - 161 - 75 - - - C=100 M=90 Y=0 K=0 - RGB - PROCESS - 33 - 64 - 154 - - - C=60 M=90 Y=0 K=0 - RGB - PROCESS - 127 - 63 - 152 - - - - - - - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>/Shading<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 300.0 300.0]/Type/Page>> endobj 26 0 obj <>stream -HVn7 +E=Hi',ȡ^h3sΌH>>?y5߃^a1O߽>wX,zddž_nz!RtVۛ7o!$PQ?2(Qp: eG^f3bv.$$61wS\Lijp mM_w TxB8iVg ;TsA&R[>av M3-܈}G[v7sgvjJ r 7o B+g1̜0# 'FME{K;/h !92)W]#%c[ՖʼnUK(+mO?Wo?^xh.AK|;FO(8PUFS]njqAd!B\sHl 0ɻ>_;̍QRG(;qўgW⁵˯ 6L@3m\xEqg@fN0<HZB@%$YdκJ`%ԊjԜG~!NtQR:( ȈjIae.4!JS4j8ޱQ#RyT]dL ޘQ&Enk$v r:6sgԆ&55" -PTh;H=K9VžL<'ؙQAаz\4F "J*S#m;8ԬL_gb~ -0_Pv endstream endobj 30 0 obj <>stream -8;V_Y6*^S9#Xhrm0#0&Z!EaUaB/LM!3WU.0S>;lJeK<34foSG]lt7CP26RbDL32\9 -6haTN*e%;e<+c'Xe1$r8q_pj8^"W?Z>c&d%ma!kFB%39!GMO9\;&E<9l8Np4gtmJ3 -CNJ0oE-lkoC2;Xj5VkZX&/0(6kiU,/dFajHD[m6RYUUnKFRA4m>,SuN>2bYph>OT< -lm1>"plnBBP8mW()_F'K&D]rJ9o@NqVaooV2:*tP,MmRHimH*pmLpDcX)1f("4JBd -o&A%glrH\-?(nXuOt+/_EM;kgj%e)hMju;k>%;&/`cJtLWc(;H+NN>7?UVufhl3EC -T[Qu_$^m.h]2/9''_mrf\lsC8j\1;o(56B^GnrFDT-S<_'/q4ldQ8F]8oJl!%U(8P -0pRdd>cT+*^p%Y%E3B!sq5Tf^^Xh endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream -8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 -b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` -E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn -6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( -l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 29 0 obj <> endobj 27 0 obj [/ICCBased 34 0 R] endobj 33 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 34 0 obj <>stream -HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  - 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 -V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= -x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- -ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 -N')].uJr - wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 -n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 24 0 obj <> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 28 0 obj <> endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream -%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.3.0 %%For: (Kellyanne Cook) () %%Title: (conreq_rounded_square_outline.ai) %%CreationDate: 3/19/21 6:10 PM %%Canvassize: 16383 %%BoundingBox: 6 -294 294 -6 %%HiResBoundingBox: 6.21052631578914 -293.818181818182 293.291866028707 -6.73684210525698 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 569 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 0 -300 300 0 %AI3_TemplateBox: 150.5 -150.5 150.5 -150.5 %AI3_TileBox: -138 -506 438 228 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 2 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -70.7799043062205 10.8373205741618 2.09 1268 752 18 0 0 6 42 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-156 -546 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream -%AI24_ZStandard_Data(/X,D --m* mm[QΜ&" -NRj0A -Iuy,>~aE%EZL.9QF&Fl=I БH1 (TaI0c#G 'č⅂BI٥q" [Z+/8xWRh%U((vK,J4jh)!lM0)Z3$MY2RHI\bLءQ@$ $I"1Ie{{b "%a+Uؖ"aG31J%@^g9-("zWų1M˫r`9@C3R,e#:dPk_ڼmɜVim롒^]:s]E7J2ۤ=U.VRv5MYjb]d*g$t&, QH F I)\(Z2 "x<򬤰r ǫx(eؠhYq)FՂg墴dg⒨D0:_Q DYʃJbQCN$%0qtH6#8CL\&H#D2I񩩑L}[$LݗD{2}D'nd^m%NWZ]7O)s̥1s^4I ((lT= ("@ūBAaHX!;<_q\r#4"&*. 4@L 3Ssɓ8Cʕ&HIK % $A@ "$!qlRRIL4dhр1^zPB^oJ~2d C TE (WxC臥fUCuJE릤.X:Z񪸹dko2$C!cԺ=^UXcA\`,("IcS&_hu Z"ڇLnF{!cUeTI[1BnuaÇ'L媺ĩ(.\vŁI8#F!sH$Ld"I7PDM(oqǑ'O -UXqYhŋRFqH(ȰQgk( 8 HA:E*SC6HUIvRxxC d6b f(PB xBAà  @0(`᪂B`BD@4HDwD@  0x!BʬIBf$Dx  4Ƞ fCf `@ ,!T 2pB!3"".hA ZAP &@`*( `` !B&!DP(x 0x !¡3 DŽ  ,ph`B'ަIFI(s:2=r`_E[Lhp@((t`e8l`(([K Ba80 - -ei\`f!NC <,4@0l 4` D`&h - -Exx8L$HhH@f+3C  X - -BH " "&l ABLq((C4\@!&'ҍ+ -8 -eH`FL0^hWP,@ 0 -#P>"a0 0xx 001_L1Du`W鬯ȵKkLJ`ML]s`,(]22Ҫsg!cف)\3ڈK,( &`ԅ[?H{Yws;)5ϙIGTO_B`ûu&PڧJ[kӆL#rhiLxLhҕzwl -Hu׮'k{R(UfsKxzƞw6jJy1ji='VDulZ'}W]cz>6eҼ:o9޳̪(;6֛VO}(viK5Ն[s{4V̳jcu?Yj{ʮZ>#s?cX7:6EeSͼMxtL?,fjOxgtxMZttOګNnϤ*̦~uhm.Y?FgGM=6Xz"/utQ;uuO!Gis.']&ţ0i.?3w6K\276RL'D_:9QSvlUs g&& MwI-W\|7eHCWH0WZp1n:*!Zۺj2bn:딡A,3~РuOViS񠞶~g;weLYhʮd=􏧦=T_YZ-]Y/yDQHe-!ըcMֶLұ>NKOm{{S^@t(GRVqO \S[ Hd-/$I$ơ{ȡ%%1hIŎQ͂V%)2Xh $AWuX^MT//V?Ě_q#5SE9DQ -@qgPb6'i,I-r|1Q.%ϾCFwɶPuvetsqU7;SyQ\eXÕ/ I䖲Ǒ$Q0u_R< ()E (wW*FI)ʨB5)#a/Zy/8XIѧ'm?$]w5ܫ]R*.&nB۲hVIUubJ%]*;ݝuhu.t-U$%PaQ;\j)Rje:!#bFG&,r(RSKq+QEbHR -%5EZ"ѫc3-u,d"IV(iLP$6&l%+ -eRX$.zhrWQ<$*-j6E\L!svȠ.lHWzwFܲ]%'C=.*SeYq I!]a$QɐZKώ4){(Kv DK -Hi$^ 1\ӯqWy/Y-&UaNj+VԡEGrGZ&^ȋ&-?8 #8ʜ8~lFG*(FȮ2H#VUL&]BJخ0@(),ZHٰ N-%X D)=2/EFAȦ7WyqV͵Qj%,YH$NXree.#,tVˑ R\31H;dV͆,D%.jV. rY8+ M#UUR8sma&auG&:!Ig:\[ן>rC"mҙ -옙4.IRWX$*Z6[#3橨\d/)6lVmKin\o:$esG)Y7oezR"fQ{'-&-4ڝ-usBT:w}];wVNYw:˗Ql.BnwQ O?dYR{+>VQ}mmvf{oW+ݱNGu~u -(o3#̎ަNzKVģ:j!>GzWofz6U(w{{jD'oJt&?671tSv!4uћg;[R+5tv'2oWNg>cBgoݴwN{''=6dȎӦs곒1SPt esC;]蹜;.&=n'&m=7oF,mj.OHz|]l;u6SgcoՏ5hy4fuy#“eʹ)w?oi-SuA뮻B=1ugL_;]=eZOzul"YkuGLl{S.NMޥk<:yW]{zmr3lt6+-%tSFĴ6|"YOpk׌kiֵ)%,[iߢosR#<--B˥;=i/:%!r}h;h?Y?>nJ\|4b-:wUĽRL.tPqkXtjr(kSJ[.OQN\LDDEMܻdb}׹K֓vwv(*q-шySgsG}TV!C[L\_ҁy)7IGGE̤S\BsfjvD_>+xLi uhT<ZtNU"];cƼ"4ɺhC;ڃHG,|aR&!gT+`!,Vs׸w4.Kpq. 7HZFX':ֺ)KpoU]$#\S=<-JT$;b4cz[Cgvs[gc,w ɣnKL=TI}<3,<ƷCNFvH=/Vwk55ϚAk-nZlKӼ\g͔YfI3VKdkz mK{2 GVH|yev|?4YyʷwXv~z71+նH`Ϣ;SixT;uiw -5vq񬥱{BsK:<4-myMvd1:\yZ1+E<4Vxk0q|>:TҴ=J5cVJG=&VwNcU{lM-Y%R Mo4ک<4Z'׬&V*֝۱5y[=9Kctv F&UғMUͳs7Ew{䍹l8O50X4YYvhinn\tWޓ?xhky~h쓚-cZ;ipgܖm> 2.Z7:ijj;:F]iSH&fӻj4l[l+:Z5;y]z-q35kͭ0֡͝D0ӬέymZ9M5v>yFiZ5Ֆxljl1b&WvUgǯSgsE`m'RC=n2ٱ65muN z%ejʖKYr]ITGҫd""" DPuxHUe?;=f[{?9KB4}~z5iTht4zXv4R˔K QKN>MszjD:%kU"X:[:<={}v!EnzE".5W'qLTjݝ:g۹.}ykjvN<_ʟpW՛D<uuWdvwkAPu{0>\_g]խX)JO:p -(noAt>>y)]:;vUV>RֹSZ$RW{nw0q *S>Om{.~ãv|'ѴwhC?ڵؕhWd:T3$1eܼr^o-iOZ%4YjWa&֓e*==OJWeڬcҴ/(\#F"U_{tLM:ǴSyJyYM2wzmz;x5SQ:Mݽ4C:_!4_^P(kuEK:4YxiyO]z+h=y0ɌRgW1ӘҷW=?]sfZi:$'Sه5 q}O_$snǬlΫVYM'lWwoGVuGK;UwD4օTS:=]'*ݫEx#::;$|gvyH[GvuM=Oj,":|k3U]x):43to -PՆ;ս{=FeSpкw=1cu2+Wѝ2f驫eV]V[UuUuzB: ]JwJ<*KBmuUE[P(nx[ytkvjRo>[E=ު;TROjW^_WuJmmsFK;Rzn5;3-:IWOHEv{~Nj:Ro otRm׳B{yPw~ xMtPxfpjDeSgYozW*ʙEi.t[I]ե"хtWUޝUJe{y$>-nTeC3//=ޓg*pcT]}TUxvUvmVZҌ1ʟ}QځYn -Md|Ui-]J+U;ݽե4,,;eٞFX -x-XUF찶 %g;+2˨+ĺ٫«G|;ܕڢnV^ѕhUjtG+vYiKg68DACC XP~q^d{='7-ly{Ky9יjZh~]{s4ܫ]ڸvbs5Ϩk\œK;JvE$\'坐WdϼwGDY#=zxʌ(Xyo/KvohЈ~r&etJ_tny;vppy\Uyvi=gD٧HWSeD koA[5hK߳#:0mϖS~nс:}ZfKD?UFUN4֫g-UN^ɷLq/ME--+lx4 Q^iu75,4O]KՌh0z>HwF#ߩ|Ǭa..~yj\ɽ>_wBu3M-1fkO/a.zlheiAriY KdjF2 #0 }n>lH2Cx$CaC+PQOP1Ӓ'<@aCPxt 8nTH(s -~ޤI1:9L.b]b.HNgW,MAppo^C9$K8ZI0镘Myؠ;B/d9]O񍹱p 7g:'FgOt3%taXmbIT`Lѽ/Kzu_unMوg -pM$hϔz|S3\K3%sM_F:{kg`f1֛lb -֮PJ{ILwdbZ$ }V So$E0 "&bF,xb -Fۃ \3Q^2):C0s<.#=<̱̝VFi -a{ƻ-~>/X@~"1 6:@=I -W 7~ -'@hAG-Gl"9\B;O -M \5*Z  ,FAv'n"T1D}@mkx'^(FN7a H)bk ドFU<AUȠkwKP6\^.Y[:,ƨ9lj"Xev4#Ʌj# -1*[ )|jBؘ]"M8E~elGz?nTXf{|FQyڊw[CtHtnprq??4*nT~?XO>[uۃFUf.ZM=MEc~]2wIeg߯l˚7*܈'wNL4 5Wȳ摑R.>.bJ ã`r@b^Ӓ;p1L/܂F[i~U Pb:+I^In,%uLC<+Ji%%ppܾP0 ( ^| - - 1 "μ!s~; "uAh\@ {V#L. ЛonyR- Be H7W!ZjnU?Ԏ~΃_2SU/L)w\5p4~1ƛyׁ"9!\ԑg9m;rBerBʱUljC -;>-P('q vݯ>2IO6kf1#h!?݇@'\J@碬_})uzZck#F%ƥҹF2Ir1v+`Yˋ,|] -1- Qse91Ǚ" -r M׊|q/9tf…8,T0-k@wK1d#uI)42k5g;"2;H8(S[\޶UΤ/&E^3XL (30DYC0u;?8F;KU82|&MppΔEL KFF)0!d!_D{ߝf0&f -'W-~PnxI&;6Ӏnə%1i$^=ljE@gyzh!6V{"dh9u^qcnR9I\9ْsm'wjX \3[9rb+4q^EAVr =Nq*]ka:iq;ǩ3:W | 'I8M9.^MRN I)g/_iLJ9,-/l!x,IvypӍqDh -=#E{IxҘbP,TPXw,U'~Ϡr^nM g>-,|YeJoN LUI)tǤ)g?+- :W:핃Ҍϫ8L%v)jx Y>`^ ByYsƭ)hOi욼PG߯)Ŭb!YfUU^/ PCo z48R+לx-ZyMEpμ&-n~!!_3ĦFa[ ͝%En fv=ٕ鉲oE,>6!-i&P|YtM֞H!U{6dWyۖW W{-gJE=G;YjʗZZ@>oމs/ RH菢, -}ianc1@B[z}"Y {/L>Qх }{󹞽!BϧA_6 M!3|15%3DX烔"v>k(OUVmZaX<;b}~^ rܬ0jmZŗeq;,Hj3pR8bKdM|0nZդj3n[ ^5n}} j9$npMp[m kb9ѷ-49.-6]@-OU*q$Y:o`wNYێ4n$_n^ˍ;rC7֏r3w5Mͱk3h)E[n%ȝ"n 2LRjhl0I>LTw/a[=w}Im7h[@+5|n(. -7@[#M(D) -)ކ C7I`>*Ȟ0Kړ{K !#_ mD 0D- -4q!;NIHeGN)$&)[AL4PD#i I-{QUg#;,ZBÅapK9Å>iKL`"8*| -Y :A :JwJʩ̖9]d#&Lװu OZ9e-[@íQn"K)g*dP-鍘RC/Q1޼>e (Fz}M/y:'l3+RmP`+M9VnpbLUy"쇱:#B)Q?Kgpho!C%a:g_JyVĝM'[KO%ZvC7-h4Z9ਟ!P+4I`66n`oq`qq?.'-l87 =?eV  9uM:>0ѐmn~|8"iB;1RN%2ya׎ޫl WفBBix<)%&G)>=DZ?fF/kK'|:= \yE qrc€3aFYa9 3.jV^B0~47N\v ǂ,lTƷxޜШ3g r/~ !)XV e)kOr -=`cZ)iց='^"Ӭ9=P^뢫\r!WCwKVVrQ -gEa3p AlzF4zOf_Xj āPS_sD+;q;=Ͻ4JDtO6[Kً -cd^3yM0?!V}C˾M#2#ɏꛦ -uK=60ҷD"qlX@' ^AmhI1c餿(DJrZ#&tfwc\,Zg\8߹V  &&UՂ(*D &iz{I:W{?a6Nق\49D1ϰ3!ձ؈Dt):#&n@ ލ@M@#n:HF啥)/}|.vp`@x#vqbc,.u -V [PD08W{I! 'm ԦߦŀAũ ho@ØyBZs|~gYuA/3iNg!uB3/ ۧC=Õ g9F'l*5J}b~ -#j76Q9Zњ -#R9M䙠eiqNlb1*'ȱ&%QK/V"]F$f@ߺm$MP^&oHDu>FظY=$w*~ ]1 B\mW+[*ܯE7α&6aoSiLfBeE2,vAY0xl(ߛd)Fg꧎ -2òN3/ Ϊ`m"Ei>CroB15>ÿEڊ4I56Sqy6@8ٵ(1~&П{(^Y ;JY뉝6AW- -d4#)箮\͚ٙ[t-РhLĨ x"QɖG xPs ӹ\ĆqH#YZry3l?TJsfϿ,2ȐmMʴ07=c gn-@H;'QTkKr_Tt| g&iZ - f:8Jf!_"+*ߚ%m[e!)S`({bByr=qP؞ B{\Z HJ}GKZ~S92[W%fTq4#u+hBX u(N;DrܺIa?]VTHV#=@ځtQH -u|_v[b\H7JqFx} -@Xzs0tJXCL [@*"'nK3 `م!@C%|-I됻ehǫd8QA{}h\/: (;A_IJqyOsfߺY.\&V4n@/эĀRvs l¼3ADnϭW5s |AE~<c;VV{=l'rc1č)2K14/-@D%iZ5VS~ d]f.F%B4.8f4tO2iVݔv Gt8je: -Q`l>{oYA0 4:m˽A@"y,Μ @Vܥyq I u)a@#*!kVI_ӓ@ߜ ֦N,RLgFgOv߶ cjnAV_ V=d]")au Y7D!?ѿй\IixDP Z{꽀7?NۺJ%ʚ_ܠ7g6%pIk$GӨ޾Ww }n"#ȫ妛x -.it +1ǰY."IARi|İ4r}7ÿj/ (pEҺz muO t -|ٌTn)瞢Ӊ WBy@N&y:dWa{XxU;EsoxUI??*Uz6[ %Ѓʺp -4}y[Xv:͚%'GF7Ds60G:=^+SA\jRlC Em@J@#éy$O%g HjdbKsAy݆N/:‰Vא)sajIF W{\._2#.sq,?g~N i;u_q kDOSH -\;Bd61`C^~ȉ`p#+_ֿ`}E.Vz~NK|7{]!\N$p~g@Mz*<1:bMmZqT~l2AI7]z_Vy%'Hcm Yz~vY͍wVw 0>2JcgGQsd -)J Xa-qGo KZSPBDY!^%{7!,݁QwI{GX}-Rߡ%O5TWu g[*ȶ^GVM%v)=χ7~ދVWRX~Q(~ctAn&1+ڻF/%Vwx^5I ^k^PP 77N*r( yϠZӅD-jp ^O)˞|m1*QKS13M(>~Eĸ'[fF|]Fu~.T ;\2XH~wt/HF6o3p---~1[HY*a{MBh_, PrGnO9O@_9٘wOH1 P T_AuO =| O!_LIJ/I{Pˏib}!{ >JJ=;rQ\tKK)[New "ݠg|f=~$$5$t;;-Lb oj.;C9~k/V^Ц# Юؼ8:'?3GU>f0ߤz/ҫo3\0,u|ަ$$)'G,c{khkOCXN"Eb~ g:EnF;Lz0t'NQ`z$A|ťU ;[ֳ(s -0<݉2逊]a&")Xn{v#N;P#+Or~Ⱦx-Zsn~RG.'sn'̭$v|o1Q($:gx$ ޔˍXPkZhk-h/)3+i7C2Au ipRL>'F- o+0c>R;wxvYxuGQ+(JA>jڎRMEX.?d/v$D[ k۵f3ۭnt̪پ bʶ@K7j{ۡ%5cE>QLy庀]%AsCWZ!>rX*KK:7Z%=A+盕cRی읳L׽Sw ?_LѠ&t%ge.o9y/ڒY`a֑c֗.ZHGz䀨#N[AcK 9HWZ-5N [LUM¾n sWxM{vـQQ$OU4llΐB/z%]47!yԫF:A 5V^ot& -^ZѶ,NB:=ܽ%BZPی(d`>׶UNXoc\EAC"C09mr3GupQy "pKۊcp78% -pi/$fė̫ T`7{˃kjh!6epc -tKa]t0af -=hM [{q鮊{RFQHN B; w\~ZP0J]B/wEtOsOo$GT;Q e3 -c3Y:#U- Er 3И|ޠ፱ʖY7e@;فyƟ|q8$~= ,L)sxh*Gc6xꌴcx -*) $A@k]3ϳPY:b¥v``HʁrP2:izFM9:8'qlc/\M6n)z5O b?Il1pi?w -$0S(srk4O^i(@Vӥk#n-t Rt4p,8;$!rPwzjGhC5]!+BWL_vi*y6sgs;=GaȐ _@gK@`ҁUWeվeQG}+_(T9&t0N~w1-6kB@5j|bkDOHUW!J@xS1JE9Ю¾:uj(CJd^eeǝ4CP2~+?GWdOo.597(@/#BhR5C.'aj1O'*`6Ͳ;csݳM+qixtmPjYXAHewAeQ̙F!|>5Ai{/=K Ac?ay5 1: ^lVM!ˉ$g^ -I5(ѿ9a6THT$9lН --7nT"C'54aP'p`3-}M%6P}J*Gڊbs$gy+q$ĴBV-$FFHۈK4rN@V,SI;]JMqiٞS0µ9s空@O3ieSL+XJ}Ȉ"<6}D]s%\-|)ͯHLpI `%Pإf9n>1̀'^NH-1틜܉L DRr3 !$kFZRV4+ -鎀!L-U[)OwXCR{)_z'C%nhU)M (`Pm1u -Z c<cyp3cPáSjD }gM#K+)˩?<"R J.$$K h"qGSx=^tAHByOYyMM'B -)!U(F#Ka*d"xKN#0uNyX` L4a,╵GX뾆ʃx!ho9l!QlBhuM^g-0A8F"F+:'$vTSZl>űL$,8G2vw~Oۉt9/Ȋ;de_*)ҏ!\~좄̜uT2AVPtWr%8RvA;W·-RVarJ죬vcc1p@)F55 9YuMԔx -11QDwaO"-S:2#ָXGSL&3iLS1M, c˴ł--VjxͦbC9)Qe2*1v̎bZUeJETԃYUcI6kost:;F(u؞7[+-U cm TS˪Gʟ?lP:>%S@b!Q5"ƈa2X#zS&6_X|{(xZЌTU~NfulQWQ /U|Նa 'a 2"ƃPOJR$EX*ٳbd5ӜaܸsAzGbx*/֤^%>Wfzc/-&5*ag0+*BNb%H{S!%{<1VbhHz @Jbxj~>է&P kz|Yoݛ%008JC`#*d"EٕP2NLŕR -ɕ#R[R0p_ϗޞ|}5$ucB X2wC'@<M* HJ r}˅WNti۟gMck9c  El Sî Ikچx*kqr QbWTx DQr>xVZyiC|81B<̞bOhp+Gm* A$<ϾZVR ܒ is͔cxb0ǫj` qy4EFf0p|7zF$p VWv`0)8e>1Qvײ1875Zeߺ?  $ynI]En@Y *hӹgwŹaP82Zw -8Zwݎ ]P/$uC/$ôvxa u8Zn3iF8V߽xz@e#R'GR{O]Q?T1AXM -rVk-zADn'%4gmtƏi|0[f@7vAN?003ڋaQ/e~_ -O\ن Y$0PV1/'Q+=GZHUк`Y%gN,C%<MbΕͨD ˮtiHgr`bNwIh d[{9:]08L[ XsTt;WcߗOx#= 1 hHYA$eA65pHgScUVE20HCMx\+?^B>WT9Sv>)ƽNtEE?\Q}?")[ m! >bie띜I@]h9E.5= -ê5hJLeф az&uiKJu,GjQTK);EjCkˇ M<#+ cg;>bl2uʑ}Ij i7r 1χys_fޓb7,ށM -{4@k\ @{h[9Owi0$&/z3lY`Z"L[~$nlZ{#O6qGϖC]r@ˍfG:u&q)R(ozSgo5h -oy(qS:`v?at?Az&e&y$(5R'//YbGRIy".3qV&/ab \}O%T,˜W_/n1xpt #pDR+Kh{@k|+r7b(^a!IQwIUBE.G{':8XWꜭ$'WE otjWщ@ē}xx PZ]8oc| :co İ 0OI7>GHE*hV(-ż}I4eYbx(LmpW'#OB^~jd?_ x28i7E/DOAQY!>!t#&XT"gw)뿋aJI$ܷc`e8󢎙"]M6k LC@KH5//\8#U<]wu[,$ن8dGO -OWVgiU>(}L íHK>4/ I2\nGVLy!/Q|&]׮PPl&d)bMRY@ĿHpp8gqvqC'L JȉQ nN_#)q6q>nhVGm 4zW%m,U'^eģ!(;*U Q|Gw -gZ?jz=;vAۓXF?T(az) S3=cȪ2%8z~"$˳6>5n8 C i#dfGaay0JUfԀ29tq2unZCP|%VlxlN\ύOčCYe㌆"TY ` ) oZ3 SE8RAZn ]z?kVsϠapP ?LF͛ԃsx0RtڬrfY7c;8ՓDWK;c hFآ4qleQk7-3 p,PbD$#r7f[A< On#(8ʗͤdn-]gGw>yմQh h64GI2͔lE1{7}Ëh`;:MZoRp'JKj#>Ey_6ڽ n\?h ; P=Ru>ZᑚMMS;(ޡ3;UM EpN@)m?^ -v*Ve;1=:{~ƶuI7[ĦF&~ & ݔZѮO&jS! \a0P6J*QkvAFC2eJ'װ1֏z|0y>FHMI0yGXY5{9&:]B:MpL%UE'1I;C.%JmP}$d,]0EMFshW#hk\ȤX WEXX8}NS d,Q*ިr[pu^f?-&=N9L$C -wIcJ HӅ褂M/VKeձ6)PBx0Ce,>SdN7J;B@'CDifXmf-.@/c,+9 D ۍ~KQl/C6ЃFZ7n=hJ=lh谦չ;#oRbKf}9.'gZ@B=sql6c\W1Go$369FVJ+|Eeg&V*ɖeHNnR߾6oӛq'hX3`X-S -)H Wr*9FH' 'Z"c#8Flč;(wE^js4/eU#& Tj$aM#hDE$òW(j^e,k9 >y/ObuF;c*7!{G|8da4+8 ;S1P:naBڌ5jp' iQ!H!0ً#7N* -V1|k&$BeLCrHbJjF9LE&!I|F6KG8!zFGM+kUp'h9n BEբxiRոx#FfZwI=JO)xLMdb rHC=7Qb'WW{.K5tN0Lr+^_nӰ|€Fy1`i]a<^n#Tmkab4\M-EAlI#ѦBe%)䨗=% SH53sӐ![X1 +6A@زq kvrD(MqgM|+N {bR<&avI[: .K21򠂤CR#mLTVlNv3-伂Ľi+V-wGA}x׷ܶx/!› éM -n0k0eZ-79P%L(B*Hf#vZ|ai1ѮU -iI -=dW)%H4wwiTB]Mpت1D9XŊP)c@55_QUiq>Csp>/%B}M=?NYe -}Wab4|%21&©, BC 9MԫuC `&`6Bd LlA 4(A"  @#X%0*p$A L`YD`\l`|@(HK 0A * &l@ P 9I$ \4 -6 >  (A3p$@l` !` - \Pd9đD:1ΜyT_8NjtLHlu5j AXPPĂeU0B)1:%<2A Ézk$w4J/\vZ8HD! QcvȳqX%W0jv㡠T]VP[UaB1Ao7bA|DQL¹X̻=СQ筂$H-Ӑ"U#KMp+X -đHѫP,+y$B*8xHQ':A$HK㸩eAGay)?D E1ml j)~[O?j0؋5}"'ȐTCWrř!B?Q2D;BY'Ԣ/ 7=4,WRڏCc 3k*[+΁Hk8n൞LYw33lɽN::bH4Wv# 陗)ƦHaih+;Ba,P^ۥJ73Zk.K Zϔ'/NpiU><5Ѓ= -4j<>ΧOy~![G^[)4=RbvY)ʻU_rZt*^^ -I9#ŋR"?G#29dژ߰p2L.MϥV᠖>nS9EI]"䠦fT/$27(է/svno(((݈tF;,q{=$Ei\*+Ae4JDv!9ToYW%GI3#e ʇ^D=,Dj}+՞2jhQsrCW?"Y_TE{ē)$D)?Cv෻ѻchJoblQZjGL6\9R _~(1Och+KMI1jpq/z"R^jq19Ru3E% Qbt<(qWyy8~,vYP -=PP昏Tq_Q/yCc榡ʑDa+Q&bQH,㼄%Fyd$t1lIC~=-5$ʰTS'X, bٻ\RҺ,\ٿTYyt*Ta*48*8oު u  KK8uD;[IbZ DHpZYqqZ9(c^`ZpvZ) 5v -FsL5Q0Қz*Pv){JUG%Bۢ(UeMQN*h\cO׹l\^.uo֪:%8C#3c4N{|FLUZ*" LQ#"A -qW#OVS4KVI.b ETσ.QRCJFuZ,lCHj/ -yКF<UCj5DidQj3 3%|zB;]U_Vĩ5!p" rQl ;\CRDFQVYD>gdEO>SF$ݮC՝AA~P$]&q)2t~|`GZrrRSI|0tpb qnAu(faR~uKD*(ZN{@.*%(".W*,B逢r?dQH&(ƱdDCc`vPX15%.SЄ1bp$хiQ}Ek0-,UQ*d);pB.T NȁEA7H]W9h f* -dc^E#?4M6Lɱ9^A#;x]\,@_lU6Ew4 Q S ^E43!8 UB #>>dBѦL4PF2$IZ5NY|yxO,%!࢕#O@Oa QJ[r#K!?`D#5T!I:UXE?a*ڈ *F"A ?1< iȣ+ }vP ҆؁m8DFȋKJ%qpLl "\.!-!OmDF `b7s-n(-" sBєŞ.AkPu9bːqBjB^#TTdM vlgE#vF*הNYw H⌖,XUC\e&*X"|g[Euxe\!BhEb,L_6R\qoS ͌N  LCr#/:d|(UK3pU$ '"꣭{ΔW*ZF:%W`qdTA3 򿙚iU/&A -}* zI K=1j2䬽LqЇ"F{)5jOxNdT~v!AAb |GQ5&^L% iHW%E\x2Q1I9}SI/MI] -1P]wkTI&,fPg]u0BJE`bHDSIi1&SA&]TCR8.Wg.d~UTڢUT$T PʌQH -UU ոO4[b82&"ĔOx>%r$dfU$ټ&ebSW71S؇#IpUֳDy)f**]Ws+|$`D("Sֿ~h4ye'׮蟚XeT -=|eT}̈ -MsΈ{8AEb=GɗGO0$-sLJ}׷+nE_!9"C $FJԘ^WYSx>ӯ*tN 'o)>ܘQ}LL)Hd:QWqeWiQQEnA^RT9EBJkgMfe;Q.$8!uf)xUΎMĩ4C[8$D9e2GA1$eGomR iNE" O.B +]"I+89'NUƵHS٩JM1҄":4z'J&L}^]E -umԤjd5jFI5ܒS/J.b!ƽbθJj*@b!DK8hI&lM/P*2BIk=w$NO|U&i1{N7T,Z{/HO 7`ńK< :JfC$*,GgLw_Q/3fiUM=D]Nh2QRQ́v1NfY%kX*lTQubFltjZ.⚺舅 ף TDT H<-xTJ*$ڔX-JSt@2ԙr?Lk3Tn\l -}B j`<A9Х@Ȕ6˼EN/^` ^}՛%'>tM"(Ǭe+ -qtJ"6VDXIERjyBF-a= A8t!2ڣz5NDY4I5$zZ~ǯS -,t58FGd$z*QDT*׼-EU&rȤi -*"Oء[M8hjri!qZq]IEbV\VaWe.YUe8V=x]L#d@fDODQ$OJTuBS!7rsSPRFIج~ܸfs5&U1$c -~E_)d}LUc됋PFXYk^x/ClQD M\DS:2r46q"#c"+,p 1lȁcj.E(bHWM6E>]XTAKmt9! I<;(.Da|8~wʫ70A EU$4* I5;ŤuzՕjqPD(:0݃j:ﰊ'Mn1*:؉VAa'4+#g) De$tHo!kgCnء0b&M:+Pet@ůl˜a>\SKgpa&#;Qu0hHz)5&PI*~.kBҍi*N1NڻuYܳCxqǦF6cAGd$mcT.tg/)G: m-<&&L&k -* f10"BQiU+fg{GlVI=;j,fL,oZE]cRml)UbNZ(uE˪H*TBWrghƴ>e=/t4AJ(JӨ4¦*@HhR<@ `@ 4;V)q<.St,J8 -Q^Rx[:'z=$j) {Yd-a0imHL(j /~QgB < ' },zN@$xF*dIF$G'*:3 - -}"SK_5V.Pœv nl[2{ _G'D-WIXe\møpi֋@,pbAT;)Kf&/$8feהco`HƆd"Ū[89:bh{Ȝ/aQgA078|#%)Y!(=di tJ7n_^@$Q.k!IX*(#ɔ7/2&PU{vp]Z-o,z 2I Ƹ?pd&}eW|rz#q2XK{i,U5GjZfao_(6M?08G߶q_p/;ew59gGiSVȯiȏ*Y߇'q$\--ֶ*/d1-Q)EcKPva1#".E.B 1ҴeZyz{aGkh,(h볕o9N"/L76[,|دڛbCOB`RF~ka!M; b*87Li ݯ46db#AU8 *SS ʞ" %cqj⊅^0WE-# haזn@B0 -].Fg}(\RJ%84ӫdg)urWkzS$o DD}+o8.dSrz'䡻 Zh8괌?+H -yǕ0anCf*mƦ8L{y'鐋d-9GHHi5ngN'{С]h*=pW抣jv$K 2sP3,5HXᭊ^`GfvCPy8A)Lbnԭ}{z( >o^n0#j].\jJŰeT(aW. -pPNV @}h: +kHj A=Y;‰_Y԰]gaMN|:w"Y)N4EX]QEO{Y4wfb]kK3zzr/9?ЙX2nЇ#9B sE#r@o$bj1Ҧ)aWH*6~j/Yɇr5A OI/&*]ۂ\q.<` o:8<` I/0_L9*5t[f]bpDh?KlB]Ŏ< 2OlT:r?n߇X2˴;` д ˟Hw֞>Eva ЂV*B<2V%?K0`@G姓j)TvbfAY=zqyRf?JCõ/ -ܫ/UIL)n,P|;Tr^=H- P.QY-L .k}Aġ~|X[TzNvXb.6s +4H8P59#qH dzE_=0hH soONȦMYK.ipqYW0"݃SWGtgSj4.S:QzE N=]7Ў ZW(:f53t7oǓݢj`'e|m#4O1dʘ_e%j:hJIn</2l, ;?XPn&g"KcGy9N~H\ |O͊,㙏E=s '%ùېdG㜂0+}2%g3 m ѐ _+? 5fo!buw/ZNń 45 R԰V$ LJ).sAvrկ|(J!=k$Oɓ_ooEΗkil4Dޯwfx.P3ػYpMeJZ#qq"djKCV;Bp:psH h7D^"+`QZI{ch@C*#PIQLVȂ@ R 7Fͷ@<4Wz$^W\ۙ愄^DqZCuv_;̯lyZ9A1y@s(W E+j ќ/ҝ1b+~bPS=dMT5n6vk[Y ?oE~Hf UT8[%)e'lA!U=S -V>MUk@B6=0h}pٹ->qԠ;^GQL:V4V㫚8q|^Q:d -ZNhj"́1aMoX< TaxFD /Meæ&Eu!;V.7Y閤5ٮFilz^ɬ \NFLi󄛅x|/t9G} p͓7rrbK~dSJGlj\/NڽQ-b m5yy7z _`ֵaQ*[3sR-4k^z`K&5}RӂUE4]Rݟh oHHn;`2 $N 8ߎ d G2x82;A{ܖAS+ЂNnB90*Om@ۀC"&8,wa1b[0U W@[. ]mI1PNYB3[d5kT\*0Ah! -^!h:pxHlpwn e7>*LaAfTk]An]cΓ,Լ5H +ҖƬ#71JG:uoS} YYF$< ZLha -%ͩf\FMWGqT!~9ʹ IMi >j a5N;ɒ{ꎞg62*Iv!ѣ:iTh±FAL#>+pCpj C4m_JA>4GK4.H5]1ƾ8D@bȻe9EH~(hurTp4tGln'^-\E|H &C3{?̃H?idQ0!͔^7SU }+hcÝ$U`5Q;BHB@ u+**V1 ]mn! ՆglOd,>U.+ -!@~7ȩiǐxrhS  A݃ r7l+~ &QҎW~J#- J0 >Y9 y\ǡmB2(3DJƴ&@.Y$AE;H-.>0 ŅN}4wZ3i2H -' +$FHGl$ IA<فR>țY @l-3+BjXDEo'ɚ`>Y8M-$қr];YF T!YQ ^+DPpdg솸Mj;8 Uń-i"7I=c ɬ6uOseb_fT;}223 zd(?}Z)uWYY #fSXA5b{kZc>BVİtc鍌HG -}|f`r[G4֧YA Tp[ס$^+&˻&!HYd88%$t.gSKp)$.O?)Bn [3Ӑ{/?Ia7FAa;dlM0`un  TVlrɄn&( `~%b$\4ྖ$ BzzНǂ bd'h UlPn>+#.R&e^+r:,>H}pgi@t賰ޯ!qf s,$ Kk:d'oRgS{ҩ,'D"Щͩ͑bAA[/ԡ;f6A-db畡v,8/ j:>?+"8YQw=]lr(YYkWgrk~kn(C5(z=qq hƣ8 ʢ,Q 9z>{H-ˤ>ZM&<}&N*gS#HXONug}M:&ijB nB%Lє VDGp~+ s}o,G“90(rJTHz̯YKƖ"?VxC(=k"08*OB uWHsiT n?!}p׃[Z܀ X"ړ\+w^Y`I)9@[?{rWsǾ*M qHh/u)ſ 2ET~ -F"4ݑLzf)|D wVq9@U]23`y fk1+$͋3e[BXxy1JsZvs'It^.{4|DB#]h0`k B*^VmʝtqcGf﨧u 2Υy 009eqvoNE/>V؇* 8<> [ Aa"6lerSLer!wA +ڨ1m=5AX)$aQʩswP3Mukc^R~Diio%0l(hҜ0RT+"E7 -m£\j8[^5r= -e'N -VSR;<ҍA$BUct $>\UO*&r'QQDq vYjD3C@:ij)1zVБuvs/Ȉ d:_ 2'`F> {xE'nj}W5lx'@ÛtSRUzJFB'uSB|+bW SuQ`]]n#($O}҄qMN7ckPEL"r8}XKİs q=A h<@#Aq eeWU_ܹn%mv@gP=7zkNlx m[WҷB{IEӲ݂g=$+f\N6_*/pyv8HFßM '.5/NhbaoFJCޝQ9>̈́_$_Ă,PkߞZ@FƶPdxUh!˨7M%U. 0#ՄE~VѢL؀,O(6ZU^+9sQ< \寸PÔT$yZQAMw9Z}^aXŲA.CY6>Žz埞 b2w:OUh *6@ny-F NCb &xkҏ'8x܃?XF-WR?L6\}! Xva8GM?.@ p rB/Gzm;I7xjlLhdvGZF^!?\Sj].Z29%30B@t -7+:ꫧ_1$XqF;kY`>tB=m}ЧΪiZ> *~nuXE)\Јm7Lm'b ]+wjX`Fߏ;2fd)Ӓ!Aҧt88ݱueq ˑ[/W0XaOOeӖ*Le"Qr= ~gfβ d(o[+{I - -'oM%OZj.$*hM X@b -pTK5sm^dpaP|Cbš٘0Bo$;Jܒ]l[0\9v{K| sÈl5{>Άd&-1X~|`&:j%!HBb$FkU'CG)>&D}cQ ciʈp> `ɵU Ac׮L=lp$ >n H*И_5θ߅dfH"Y>V([ cp[:0{hg -{$֬+NGU`&txhuܧ\ƒ!WZ8,"!Sq}j`v-W9wt08EjY}51@N6جedh Ɍzݱ&X? g_01a}GXP8qZcq0 LFsF)vF?vz%z% [u;R]gw@X8v_7k;Lbi;N{{} &ժ?T6}p@JQV.aq?EӖ@T҅j\4ݳL.LP27Ml@&a Bw E~]ACLd檒/G?;Uh#Busp8hUd/a1hlVofyު"[LF'RҟMKp%:~uyaዅKPiJw8%g[tdzR71D-pdASQ6++*O==XyvB82UjGQ2BTUTg-.Gx?YXMY %lnE8RK}OЮBU94`o):Vcs< -zq&%7~pAGS@[,%|qPZP_mʪ59ԹfP\:סͮuӹE`Թ;hzyApͩN yt0>YƤs!{@s߹͘=[BpsF,Qd#@zn( N=Xds/h~>(Xntk.CXVLtC>PUƙEt֦T0RD%P$YA8H厊H[͌Hw(PlE*2Fw֊5R'V*0b5WaV -',H.XpM.*P -dA< -߷vXHU*[H2Rפֿ?I:v ^+Ĺeخ;sRg?)EIV4:~_u2@W jO/qmE.ֲGAWfŪE2e{8dIhrJVpk+CG5(G(@gbT~jg&Ǘ$`5X%TKx5ޜ%ٟu_ȱkz -=OB;._ -X-U]g^ -h8.ÒnPGEQIX؈i1_{p\n% 嵅՟3?ո֪ſj-siZ(`.]fM/ 9hbM'̛khvs˜f[n+(o{r5pט}Hag"ā+U)0 x_ֽ㪹_6?]9-Y&Q:%-@sH`^6x,pup8fѵƣf\StFa#pEׅn#w#ƔjוhBZ?w7"𭋿*ؤث_C½z+r hWr+=L38wfV`4ݙV/ }MVᶾ]%p{^zg9׸)-/ܿkS.M|2mez+s䀑˸x&dLJzsw[,!('X(&$pgpdcvZ,U ̪ t|B|$2|-Suqo Ÿܖ/9eL1͑A}IsyvlwMQ 9bs^_$A吼,{r/-(OCHF=>dBLm#GeCIgz;4Yş Vf -V\"*ٗ2')+]5?V!PeS5a -! zqa p4CLab  C85 oKWia8VV8[)0/3u;bWw) uDTj>h} WSjJUp wz"'2k.ة{1&t$DeAӿ8?{@tjF=e/eT_}}/ -,67|՗iO}H}=\9+K R^_]Ku_J?=$ay/GDp$Bw1J|YAG(pҗ™PyQa{Kmhݷee瘊vF!?.o)8_8]&}n)k2ZዐA%|D09!Gv,.Iepv&/ KW ) R8_7{7">)Dt˗h[c&m|HBUƲz1W`[6|duo'p.dQ5v*;a5=M U[ }Ʀq1%/Ҥ%F}|3z5Μ)> -ggy*?_/$zf~nS7k ҭ喯_YԣT 4(L|e k~nQ@H *_ XOj ^@W^<\ '.pyyx5_J/倠 &\HE#T*.G VWpa ֒ غ5a0şB9Z_6KCiIFKB81uR[,K@EMȔ],i omTޅgt w`Τ -hF pQuZA"eL -%!$B^ѱbc8yQa.Zx`هxؓIhQ傗paQg -*p2K@)ڵoW6A+,JzK K2D(C D+lӠ,ycݔs?e S޺5f]%e19+xL$l"ɾ3 maF"dh99ѵ E&HA%BK J?sln1-;@$0bKH@+JkJSG)q6RgJ>$`ސ5R~?7$f!V|>+ͬW8[3'|;GZë=!X(E@+hP9Y`H -(C#`tݺ`+:Hi8X[͈[n5 ^Fض|?e[&#-|_lj7%m1m 7[AOmn=?OlLg;P} lEcnٽZEr/{?бVcmZpC`yN,[ڹHO(j5^m2j~ipsiMÔ֢+i#䏓@p2h 8)(Ҭ6y~Rҽ6F>7B_sGaYP w-gfr kLqm֖@ްfY5@ dlĬH00Od -e:1j!` XNL-҇Y[ /I/B`07ۃwidU]-(>`%m6%&%}Ӓju. d6bd `mƲ|ƺ<?r~Y"$K"t)jWYŚUF2r"2_u =3p@X)%J,98&!'.qcZg`>b*!ǦqZ#E8L$M̊pc1 J4LUi:PQv~nn+^V4 n/ قfN跫Tlk­ǟ=8YFE8<|U2_(v -gQU9LpZFfA:=">,=?8ϭLчP~MbZ$¼n tyϊ4kaɖe[X۝#2ns`i]@|9V_Q|͂*}PaAdccլDClg ZsYS$i_Ukx.+(rԲ,.˪bLVް,Y^)xWXv\YL2 ,W,^x|jr8O@KJWaVЭpּQO}Z⼨/ D5 |J(ju;D=2U`]vw 8 -\)$ -{_&]{xTkM1 Iј Z̔ 7,5]̆ -8/moCeou>wQ7AT[j$^07cm~Rq|+W$yT }&\< -IF;zf>ը#pL1|!_74o [OQ@_%Xo?/|ꎽ5\(E5TEb"ޓCPӧH'RID:"RGyǯrda>!{a?9}c_t'w6QkoEgo% ==I"pbQKb ш_; *~\|RH.Cf5).Wv@b(U?Ey6/ co]Q*XmjK+(Zu8;Q6%WRY2,Д(ۗ"Ye -HSBex!j1x(nPqlpT\ G8#L!-Ο OI$w0|XTX%mD 'f]D ,2_Vn:F(ue_PݜG{eń`࡙;9M2F7c2e8RzFu rG꽌$/R>M2A^q$$ -9$X hbjaY1s^/Q{8r?;8{/{Vh*2[vqձ2's#Av*O=PAyDױL,D[ژ+# M1KÓ_nSf3m#Zԟ߳KXGX 9Z}W8dNmHy:'+qq''g! \(:`DAa͡ȋ%(krvSWGv6Y$dLu ׄ-abK߻RtR۟MFu%ea߷- gfk#} 5g;6tm -ƀPmnī?` wNjBuaWEO; *Jd~pFBN"p7I;b\$\%0³Dxkc eTs5PW{ !BlFM@Xb\F%A<abW="`D|+P$lo-B@/1*'vMfAZ*p6tS~7$Iډo2_7$Ot')iHfk&>ԧbÀET= LE`g;Ȇs71Mcn+}9_SE -V<>#'usD6\M8Iޖ==OVZJ1nQGQYYg뢸6lwU`Vt.9, NJ׼(s𖲣Բnm±, ΃)|bd l7)ځn•oMkk -R .?KR tGNhL"yrq=l;Ob !:~)R8]˓j_9?}d{ȭ\xH&bvhI2I N7[O*2p<&`H’mVU$ ,~`s6$d^>B -6"oZJ`/bTo;=ɬN||#\JøZ-W?*T'}{8 A1~ ! k4 -GG!!l ZuGDq g0ǁcj vhOϧJj^Z4W'r u v&^͑nVr^X գ-A2ѡ#fw EmY -vAnDC!;rAŏv#EUR̖LA-IaC5fk|* tLrA"5a*JhR}[`lygSvuU9yI|p7Uj]٢TVo eUq: /"TWg;9ŋ%I&=$U~lxQ$(SLN'vJ|#aу[ jf3Lpi*/1qfCf7dSmÃ>l \v.MO\ӈ5LiSI8IVI>G -2D~;]R-*ƪ:u]Bi8 1NN[a${w5'Z@&*C0gqT؆/[/l<8 FO.@$ıiaIv5~*NIR 4qP&Nyj7< |L;z)"t}$|&*[ Z1(?XSH[śc~bj zjőŞ-W)khZ4LB &SVF,\ MEHB_.7A#w[v~NYΟq} 7v9;bFK랉iBd=pE6EWg1A]Kqv{ri4yI\ӊ й5m[~R;kDe-yAo}U}N~OʱiĶ4K>`rD|dsg1R!N8n6" -܊,:l"Ar63Bot7꼩݀aH)dJιo'ݎ/@&Y.0.TKe^~іĝ$8Ga8OY01(4Gk -H![Еfx,gϭ.k, K fR5UV]0m7!QmaEK1Vt8\d_(| egE7HPTa$}VW1/Hksu44 ǔ_alh(kMK`rV{eGV>&u"Hꦘc/ }h88Uܩ'uQy_[Vb$&gU`:~ Oְd[vv$],m VfqAG Z5a4Ŋ9 D70D OHE.~J bG{@yҖ٥r`sd˼>өzjLAXc4O"?sq.;ZuOzU w`= .5gnEIALLzթl4xD18C޳|x,6yy -1u@֐jI&vi!ʕd 7uAG -2޷f5pSH'I8(mj vsnc{tNA>6R4"}}&÷pueVXs}v)$x\2FEIGi4CxtwieU}J(^_>47~K"/HwȝEuKjS؁U8($pdXQj(DgC~rbh]xpA3/.ߺ#2#pHM"ۦؖ*UBby[ʋi${5 JhaHng' ?oFk;sCMމQd>)8Ep&-o;l9Jpo:XN`#Mb«пg?^̣AˬAB(~Y_M<0kB ??g&  6!\"u"b]Dw֭&gZUW Bn})PUyG-1G~25CxLRRP_HOĖ_"o7?/~ ү짟} t ]ƺމ♎e'H&Ae}i-¿Vpf=/0z:0yU80mq"m;|y p)$g\ tCqcH$kv\ U|Pfw$WF #Bp{,_>Zw\uG"F ڬauS;.Z6\l*3;=H'NVoH#]i˰cą~kfw]= -Ć[A8qi~ -y wNuQH!ۇ K)xU'RJᖥD -EIAAd -+)\FRpV$> 2vnRH S81~xB -m$>MF)-JT%Ɨ@1 蔾? PA,w"M9B\886I(d1 CAgg% ²4v$vρN-#g -*#s|L$Uxn -@,V_KY-3pNܛ0:ڍ}r]]"cV R5lM"X+*U9gA%%uV&Xq|$EFћN63X8kAz< `ch{8h[,Gүu+G)\ HˎcJKf0"*@lN"F'|Dr/w8(Risk@nD?9U.doS# p+κ4i^d\F^T% - KYMDW;, V%fy|T Ln1xu%r'2/8t7"?76PcjEٯSs+ }3bXACFN4KJǑtpz}J }^ܫ6 -E l0:H vXCς!^ø`*|BF -6$(\D^W"$e@C -|1$:"F)҆1 JaG/Q<)hBզBWsEeNdp 2=U6!q S>N|?yf:T-!"p`AЏ -"Oɑ -: iqdTbh "s} 0=A"{2»E}Ґ8-w]lvRXH>stream - ezq6E2b`ǰJ*v=2G@;TLpCb}JB$r6!z"({lED0ז@Y` /r]32F)7{͆|5 vl(t+CiCN n>u ͙'ј"qoXMjؕ\)bpאE%^1d&< -2,!?`kmN  Qgo% -n~&??& -;݉ LC-Y og#ĕ|FNlUaȽDw&e7D| xFԻPoOb"!>Ha Y#,v!BD@WЀ>[aXe%uQ|CµS(``)LjbKan`^cL |G_5ArAcځe$Q=pLɈ˜JTeG:""@jVH uց986r4SA@ /}:!P>.IGx3(bҁˠ!e{L5Α!8Y񹟕a],˻~5VUטU CinAijˏ@ ;OhCp¯;Ȳe_ݰMj(t/p:|zX8PNY:rBe u3uZΰYS"N3v LiW٨&vϋK|gMC?b(Jre4ô}Bŏkί0"doŐ=џayJTp[~Đ æ&kNt'-v7rrVhgR7DHwM1TP&E4%d[uC([{`ߨv -!2MZ -}βX Z8ـz}a]|!@gRt @\1- (U8 5sVt+gKh8T\dBHV7j|[jD`20yBPQ;HAaxI_/0,W#m6F ,F:ۨX t0J@# @’;^li:XȷÚdjL)Oo* ِǦW߇@q>h Cyspք*WLsG04\Ž*j6`i9V?p`u>pGXO׼?dJ۱ ISF}|G Aҵ˾ -S%d%ªK( NQv tRzw!x! l -pMnPf]2x2uؿ5.B -f!%?]rDq)J8 Y*&EP*w[ؗBR.V3+ ;8VD߅踢=83S`cK!O,r6N."H -ߴbcv*i聱 3 W4b kË)5-d- o'ԙQ*ę)TbǰV9{W^-BV1ؾ:x^7PZ͒BKv0 PD'jat !Tf!"C'=jBuTAQF,}㊜#2"]$Z۫R͗60K[8#*BZ(ʋgP"_Ypsp!2/ndYןN> .g!54n8 A,LQI + M,ƈv~_@h!!Qxy&5sV݌Sg&JEpM!OC?D\5aћ^ayẂ{0k9I:nIU AwH%0,uP%Y 84I^`sɳBS;[NnuۢP+KBKR]25{]GԞi@FX5&(^ᆗȉ_r^) A$O -3w_ڏ)W8+7hڗj U]OSZ 0C?"v3Lil.5*…\ =GټuBMz77}XnĘut6eu -%=YDEq| [yMq8\pZ 颥b\> -$ʌc:?{:"leMs$s{Em -aBũ.`C>]^8PK8K[T{yZ;L¢o5(MJPj -.9T^`*≳rԚ+j>޲ -&[T%7z(^:E7=ZZB6#@+]5SbbPUw& ^} j*˄I3kϻa)0<:a#;`;s -<[W~3rח Ru[.&ê-Z_?plPf6p8 -Xts*0p1uԂCyqXNV |-97'8|& ;)0ASh 8@q@$)L)g/Zwy}t%P? IoW2iB&W$<Q$>T!= ID$5Mԏَ%dj]CI?ǿHtz Rxr]Kr|rӈ؜)N=Ʊ98`;vQs,J?B΂qI+M]aEĴp6ieiܗia5щJ<"GGdE/"H!/Jy1V&4PdU(25-3,-9D^breTR.4͝C3pK׌1G|cRRPG:-E9_ Y| Ĭb."<#:"66^BljJ~u - Ec>}M$)>Sӏ%J)YK1r tMEC\IOtDykG($ۦvKV)=ԤB,ROީu8I/ՌOSDGU"UJݝ4*T84]E[Gf|U-ܞz9򦘏hԥ}f^ ?gGG(iOU4P{ӐBi`c8RPr+qRz;{NjwOkei2J 3~KFCP-*6Z\݉%l#h1;>jmc^vaDz'=8qH!pMjO6$WA-K.N,;Ȳ}~,S-4\dIU 2hida2 @Pt1PmZGoX v|lý_^u[dl_D%* -Y{%!% tИ72vdjeGKB#zC4 fZzH5K]W(4J,49hvֆƔg@2l!4+_\$4Z=$aMyt!,g!8II YU͞,E(Dr: -@%D"WFi/To+0=ȋzPTTu&RRr\B%TOZr@D2QQQhUխj̲k*v hj QD j!&B&e13S=&(3ґTRLSs'{ .ݡt cfCrO 2ac̫FZjѯRkC^"xӔi4O0VrR"0)HHD̴1!R'1ZQ("Q87ì;JSTe3q0ٕ>aHδvřG; -FqҐ.  }r4jτ mK(P)"l"NU< 3 !Naۄ]$HFZ<w&2YYիL"6gsi#Uˇ5(%@KbjMo%i7F끛`, kX00 ]0A\jUu5<ta$èQzPuD0H vr$UuqQqZC zJvf,{"SuŠM|Ťb&Ȑb8$#v I<m8ӥuj7H/9޶2MN ZKuݘX\髌Je|+쮰̌X5Ybd h;܊:߃h|`ITQn'WqξVӊdb+*[J)2әR|/g:MڝtKmu"_85O1vS$i8Z\؝e5Jr?-PMrI4g"֌rh~#x,zE{>99=.f GVe^r!Ɍg - gq""}+9/ŭ)o_ͩ 3IT!&dH,Im%=1J46RgxFIV:;Ŗdv~zHԉw:Fe#t&ƥa8I?ikv}zs|]ft 2O'}2}N+ׯfڒ5"ludHײFCEi3(x%1WoUDs FcH~}6'<zyV1O_ -sZv:DD Khik_)E'f;GdU.zE_F0p$gk&F{x6PPc*@' m4u?#-j_Һ?Cɐֺ " 'DOޙ OjL:՜ 61S쩛< -BD>S?Dt6/! -!넘 PW>oTq,h3:QmDlBIVթc!YmjDlLu'e]ٜm\UVjd% S6%3 TbJ."̍[{}1mFkiD[uG0D!~ S`D2 w\V"bhB}vT *D+t15T8 cLs =GO-"%J$ݨQR20&HKKWz\:%'-6yX34MI: -Tb!}lRrD80έTKJш:. Ҍ<%'ʻGcou(m4\sv'nnsRvUZ՝qVHy5JLx)-& NAIV j֌cqXGi$ׅ,e"2ʯ z\$R~Vf4ޔ=[0jEkjINoMjd㠣QM AUu vtwl$ZH7VФNg5dkj+[Gpq"ܸ,^eL2:m:NEMbo*%REDEjOŊsH#qV4f.RJ'ҒR>F꣤؃bSOGAәB$6ܾs:٫+[Z:K8 ij%{{FZ2m_PG[3JM+l9R#֫i [4avR"ʌvghXF%&rvɦL]iNS.=]2*!d˄`+#Vv())l ǙM$œCKLXdQ(gB9¡PNFDΐ-EcQfJ"7$d:3˙ez~ I0_>2qRֲ[[J )U#!="զJ-LIq:iGZp 5fdY8Q%)$ͦɊ%)G !QiQIkeЩ41ÒKk|qy/*gUm9!oE 3"q+,:R5AKhoi"tYU43KZ >7hʗ2ĉ1iGIz,FQyQ6ө5,R"~ ^n1V}׭4߬/gkkaܸݸiUJ /9j8’uI+}'3;iۙVI$r|~e׈$<Ԓċ h}n&pX UI$$9\r#9R8> tth1,ijB=V. A˅njE:OFxHM]SDBQ6/ݓH5|Y:B$r&}TP@'i{p ; E@!C_^679)Ev@Bn~Wo.<8S#NX(~ϯ -Nq]:T" @W+-<j74<F"=GϙEק(n>L7)l#PJ w89_Bp^榀f.&v#"n+k,J1M7z/Pj?``SN,oe M*6HO(,$.e&1Qhayq #`'ktx!oh0I0gܤE3r,;#-`a)|%WC$W^/%BIsqL)>Y`X KFT1pi,Ҷ`Z~S<~@\3N2vmG LG.J0haiV,#/ Wh⦁]h [U2!x 5\I!|j0,FkIJij> @"P9(e%m  ߍXwLl{+ANІXƊR5/Z -jcrG`T0ҰNj34% U?7g\59qPvh$qiG/؉ я$zf.`6[sguCcUV3ͅ)w ]C͇l28@';PGD&IdD0,%JZWI.]<(1f>s} (;?P .H˨_ͦj'!Xc!:BGҁՅe*:h"3 @w )%Ljx(at&4]A[O4ԂѴZ@A-"LAur'~%,"nc BԟLڪvk7ԻVwj&k7ŏ#T͙}lúCJMѪzJJVY:)aӭD˕YmOj I/j / iNpjpn>&G\ka9LLw.e j`4(K҉b} ^#Uڱ!>Gp 2(IdxDf B/֜\ ^ mΰJb'Hf|[kOA`6K;H/d%q6fZ?l)mz3DGXɼn*Y@dd.sݟљ7'+Me 8[J#+Ht+`* *܆[GlF*]L"s"Nw٢e@L1@p., - 0JDЀ|@MZ.mS+\^wK p/Cv_ED zx굃Kh)_KHտ%wK蜥zßϚ]+bвַVߤ+C\2S)vEz_Fi(2.,%rt2?P瞟n?BAP"X9bګ(Hu$Gћ*-?J\)doǶ0{;TE&yP~N%ڨtA\o.a#LoI|_0~`/ Bwl,Kە1^xP2)5Iw?)H5BoDwܟ^jet_.?;tC)C'69unixfϗ,[.Ǻm{v`&ҹ-"阪@fzaHy=d迹@߲Foǡg=^htkct߃ظ/Vf?YxPh>u+3(/_гJǟ=ˎL&.uI2"cmb^j`CX{2EȘnR S%b#OEoZ+M'۾n};uʐBuELj ֣ߩ~ -lPtkbKruj]٤;GT~ZD /cf {1@Z#<&Oy5\߳/9Pcm3 -JcjX'!.,cygO`s+}ڕ#M@WP쀭HX9&S93f% 7l}ZٙoC2@eP߬TKU1PNJzжI٩PYpGGd¢_T+; П fo\KhlULϟ`8A%x~5?6* OnC9ޚ:iTp 7A'~>e`L X5LkB_{:Q,?5?'r -t "Gq3ll@ 2meX+'quijK:Y]o'2| --(!?ڞ]t?a:MկeUCar Ͳ)YgCby֫,Zgrؑpvg`q\ -\ZK\;jP;q3 -ιQk9Ú?3%4@Ygv`0TW2D &5{Ȍx~$ W'D'Τ mWZJT [>%./fGUFlc۹C&[Fq>S' -?ִFc7{bZ* - DOaw` ~˜ iGpe&i9È n -k -A:t 2-fm[hnWp:XGUC/;oڂbǸ}iX7-GL#~hE}֭?˱ LH0X0$ 0+DWFW1 *(5EϤI-!j? ţO/1_4N}Wt9 'l IPR_fbD2f9DoE+#ٗ9%t82?_l}`>5rR)dTBLl IkŒla9jßV92qՙ*8<eaQ{,n3 _y+0xXߨHtɘMjOi|F/9ΐ\(n(Nm InrI/u L}BgmZ>DӘ32}~¥ =~F6Vb{p_I A~O+ң02FHdO>fEAo ; -}\KD/ٟ-u}$Zeʾn4؇sXG'^54+5`I]XWv$@G^Gr~C(N-cbLo[[`}\O aD}TYݴMv+m=vL$\eƐsv0&V- ':رU_*$L!C⻽fԺQZuYFqXdw>J+kLN(#LWBZ\aY\ۇ+}?rX;u55[fTB՗H{Pi!}R41E`3 g`_YRV1S _!}`ŽS|p@-x+{Զ'8|WfM"Y{6813:ž#k9FXhEDH#Lŵ+ﴆTH ʟc5B7.!ӑ7!R_hHͪD|XPb0Iq^" M 9哷uhWe\80Ӗߑ6JM>lj|G*Bs[Q*/r`G(~(|,{#PmDh| zD?xɿ_i[4s%8樰A&|+M3\Na*-ybX"*)=۞Q;<* @(TP>p2i 켢pǏE{j`ɏrQJԺ'#F0\ּ4>ڔI$\5L-a*_j-Qhip \#k'X|cDp8n[Qk≏o]aH'iJOZߐ[`N|I=Q(OJ'>J<aO| {eڟ^Y@?).%pl>3?&,+J_ -6.)?? 絵=y⿌j/LݝJ $?ar?9~hRT?Ip_(e%qĉ:(4[>rE^E˩s8h氞㺼)-֟[9hArɤim}7ll -&#jT}VD(N_Vf.b}5ty -Okeɺj]zr2Ǘy P who/C7ߔSwy.]ė"eG.~xs2R2{6ו}Dљ|"1@(ÈoU@җVJ[@K_uz<⫧l8^X ! 4|bp-\Y_+IG:[z6K$ mNӵ{r?d$ >qb2螂x>`:|rgc7BTQ&Ե+ZP|!}f@o? R?Pʱ~Y_&T߳Y2=f2 ʗþl^\߫ξ4 -W nH)>& 7C>[{Ж9.g0)+wu{Vs8D0T2Ҧ:x<{ x7,%?Aî:&hGGtQodFYoQԤaA͸|_DK][얕?A<('Spɲvh,JGpaa|<__ Tl~X~cd9ZX/`44ZE~*A^Z/C|=Jl;E;w79r8zd~VQnsF[x dI/|\2|o:zYnD=mu4gq\v_ Q*d{?XܗVa9xMLJ*+n :3>zc0: BֳUN`<)O|?ﱘ!{$|W>5<D޷!Hr(8{h - /)|k4W,y5|?a+-LhdLM4"U[e t{Tֿzw,ozϹc^` v_$R,mZR{o.'_u E drx&O^yU47ӧu9l]H֮Ryk"xo\-L~klU^fi!˜:ҋN`#e>:armѾŹn]s{'P&=4eiƅGRs9`T ]m >k>`Qh=@ '(;VӉ>/ħ?d.%Lﵙu8C0m.]h5PdXgC ! %y3or ARCJk<5$k -E.ՈrFV/ >Pc!F?]~{`@]L#(,ᝪE)z諘 eaT1R"C gcpY1)LР8/,@eѽ^:!$oOQp -5fu; rh^@ocZ~馢ػtܱDm bsB`@.Zÿ   =c%Dz?OncƟ%IdhoM sDod9/r.LM;:8ѡhFkV0\f)^y>e1rdÔ[k;? 4Q=ZҪy2,%|ᱴ]F_K)oIQ`?5tF٤TOBO82Hz|Xy)tQ17,(̋o<!҃Yw+x7v IΉbjiixd7zͻ5?NNDUk7$64Z']*IgnyݘyEW&( $# 'Էd?]:tlK`Uz_Y󹓧1qW}J]^܈&` -ۆˇ*ERovF5k,?Lem?(=J-핇)g2}g/H..X]oFyw_쀊#M fUVE)+wG^zAO,`[4wemkH&/Eeog4ߨٹB[)hKHS'6Yf/N$[đ=^/04>/f2 LgyLʦty+0`]7 oD3>9XapzSP:Y3$-x -|),/g!q2+Sm-wǔ/Xe׼jo AyENP}2ac]nRntfό pg/~cGW&?$'ih^XyQ85/ZڌRx[zc=k%<9 \vw0&x5**|$IIJ-V ^7ۂwB8 |`2-xI,Nz05#/nHpx ^, o;f(ڂ U੕ -  >J-I;b -[w*ۂao= )3 6I(tYHLSڔ:J6S|L3F^?K){~ݠNn:6P׷^n0hlV|,Qr9:7Ft:")K# -u棖zPJ}b&dsgìZ'T {& &8IFћrU9[F#&FQ,g k8%*r[*…\E7a0z|EK8];$g]i)Z+CGkSh:dC8 y[pDk n - GCZ1#P$eVp)b -G8[;꾻e" |cY!ɐ=O;RT?8!WӉi^q1T8'$-UstJ1pGBȪp'ӈ/+3ζ -˜*8rlFK0TH3ʛ2r -K4!R@pHcL?/چp -^T]6/0/¶c}#UmfÃp,2\)>lLw*K٤<; -Ru댎V#5*FH((WtW~pwp3P':D)HY|3T*P4fDt{)ނz3;k(1%@H75qNwFO -3zD?Ksu :q:#k#zyE~fJ+TDE k=9{ INIXqP5#ZI< -D^-\:i0Yv֡$.J9\ -uak9ف=ڳӖv>ʘ+ =M~~&/-AŤ;u۝xG}HpWzuL*[&H\HBUO5? "p(o$%Hzg$ +^BqR1Ǚ/G鿗C#Qy ͦ<ͷp+޸4,3}|PEKc%Q+uKGdI:h54$jrW7E,)=U0@IO7> \>62~~;` mT\)t|a?Zt0N|cޞqPv$Fy7(h/M/Q -I|Q D}@O1=ɏKd=(A ܧ CM%$'>[ڱ :}#c'?4){7V>Σ+|$B9Kb|:$)!GZN'ep^{!XJUQ^މJR0˜?Q LZMYP$Vڧb w -@yD0^O# -=-V v"P _~SO ~hj}y, @KG;p~47@<$H– <3F-Gp?.~X @^/Zэ4NY45M'cCľ T~9@&7vz+w9০̙'ꖦ8c 6i#o$% m亭 Фf?ưc6Ц$KIJ`OCl-&mS!د&q>̖"~M?ϛ\0sFMJ:#DEMRs AyEMRN#H S̝(e3~COB-,]?"|Hotk$S?Ͽ(bwADRǍ,%N Q1D~O_8i{Zu#eHR%`p-b -g;/i̗~)[c',K1_}0qGGAP‡I'mD (nl2j%65~z֓dfk5Da_/9T0~>~Î@T[nx^| ji&I ?(׺9lrGތ_˹L6jg2~ƈ<33hW? y3xiUrI~/t1 ?^%hǦ -Ӓ 5ZdG3ɒsT5A뀅6l~m ?@~l;gs<eij|~Zy?8Rb%FJ2HjnhuIsܓw˄,9ObB,5 @br'KPXTMPLCd~tLKD'm~'U*}ĶNJ<$dqae=Ff!djD!/O~worx) ?6, IF@ ۙS¿%C~:!AN23?,*.y?#m CId;-7TkB~H{<$*4q'YKP>"pȏ)6:̜Ґe[ѐej۞ט#-+gxoݡrHl;McxA~*):Ȱh]y2#?e;iz&Hbl V?L] muQO;'6|2[wt炘gO>~4cs&;ih;i?ѵ7&ӝdR%0`D4,6: ?F]EWx@mNa9 7UDM*Ic75w$~l^z@P?L0꠬{QḿiZۑ YvAXw΢Aď:X?"Gr"!~:s*$硛@Ml܄;q_8hrTnb݃cn CZ@Mvgot|?wD?Iϣi7?t%q~益W{EGv~r -'1k'8NL癵V4(fr[ꤱ*sh~T:ɬLa'k+a:i74I!gTLttMӣLID]ma:UT9ה`2ﮀ&ס^DZͤH%?iN-QAzL !{Ryv/wM4o6c)}u N}' ־g.l;\4VǪ坄Pw/>ŏ=F3\w$档vVg:,J*?!yO9=`w=G%v~?G[ zƼh(h${zGr$akSOԌ,ГH7^㚆֒I+zI =)9Sj{ :? /ӏHƮHYsא?2.żp'ܩh&%aqNnK|)IB_O  (&npȎWl>bDKen譆%o*[82jjetFDF^:8&<]I -S0[( m65#r$–m9 3i`8T&gA͉96OC[(O:rV{p$>TEoz(,%N^Qb_o}y.MbY6l$ߢ0jFEESzH6h_ jk3թK&pLlB\fb1Q/n‚xulnrM=ҍn7ɂM4\F_87U3ք22AvDvdrQ ό8I3xcBNXrh~Q9I?(M7=MLěd89|OeĐsYH9Bu>iCf濠Z?1G-;~v> 6cڲt[) -qs~ĜOT4QoY"IJ(u`OAɏ4(~mV0leSUF}#"psjGFY }Y崯Gdv7jtKJ $>:&_Hz? 2H˲5LՉ  Ł 9a}榬! -Hzȫ*=©?t渵DB?uA6p﹤tϛ83)J -H<*ل_ H (%tNMEhL7PtN5:8|:(_C -@mVA.j$ODe -r$e-(H(5H/:AՓdT - /9ďL힓ZB4&1ڃYtc/I]I0K'g5B@:a 6ckdM^:u("𰄊 )$?8/ۢ̄KԱ8U\sؕN31B -cBZr_j6+7!,?19bUUٟ8H]=6Hti|M{#9$$D5]kj͕+ $PT_} -`AMYp%] - 92 -[I7H:҉XC~x, -} b -R&*zk39H Ik@(+H)^) !.:Uj|% {Aо [xrC |=,:A[+u>N- 2U)0,:-)GI?E'2)$Nk(${To,!<c$ePkV|2:}vȧ{JB*8BzD܆:a'W1~4" r~'Kx$:Tz`$1]=< Cz -fj!O9˵$<41 egRbu]= G*6pR:(@LE?Ɍ!KH;>Q$6Ya'H) -)GAth>wJDc_*jGwSb =t]CL7'nv?U<]@輪 X}|LGJJJyֻJ=Ȧe1u{Uj/+RTE}k翰U,[9uAJQB` >dB wȻbo?MgB+9A-|f,%39K֯Zɘ,@=Ho-\,UPV0ϏTXrq$F|/ P'mV0[,]=VKQaFCĖsv%KKOXg PKrA.(Y4aI1B5]K#% K+Pl 692yC JeK \@n@~+*V)n.I=s&Ӳey!qgqRI2U -_)iz0W:I~%y=zfC7P|sVuT(0{WWj#j'-5 9YBU -#ʟ9,ix+u[~w'*&zJAKv: yvk/Xt.16?VO;܄ҪT LC-UqbG#BVzɲO 爖ڦQXZoJt0TX \l d'#픋U)BϪRkJ S%`}`m'rVdYe7[J3)6s%MGTܜP[agWmdcu$TwqImJ -3D(c]jy˿xɝ.%rZRҥ{WSk`Sqek#!;"y@Ed; -F}<3NP0CQ]?PPuDHB/P55=P`ٺh028ũ$ěy.RENU2TXԡzZ D8[421;v2UZ\"Ӈ7T:="Ӧ@s߶[cު=[Hh72qij(. | $d#$a5|^@0C׾ ÃMudۻ92YA[8u=k鰐RͻKk{ aj VUDW!ΝwEOӟ,Cc_ -Fh2m/(]tmeZ^(oӺRaui+9ԍm| )=22A5Dh5tJ{t[ ʣ3}'| -"c1C0F&ʵRPqdz0,k̳jZ8*%76{o R&=m.SK%Ǖ7sµ.V V7k/T2iXN -s)7,4jLQLKldGĂ'Cm:6m 0qDyU}c 5 \[Hd_ .Phy$DՏ|!r`/݃ނL&7ʂ3 2M*HdtOC @>-|yi+C*7#Pգ"¨z -Pu[Cy;z63ׯ7c2o}.cMЌNӐojbpk - (`#OIsSz4E4F颔֩¾ è/)oo-8=9^*,2QuťaFdɰC vl[:T'Npgo5d䁈է z#R N]:71)Y.FO&ey檂=!5| Q+1o\=݅KH^a5RR!(km<+/iEH~j:qH~.v]re죧oߟ'BBWib=5SӬ̩_ E{DqQGA򊬒ZKzb#j]rh0.BR!(W=y`= -'>t^ͅj7^!alXpO&1|*$U -~{J}.lBRHc[H?"T#*lpgS|&\E|xd]" -K7է/,gY. -1_o5fR);g#W!UJuZ< -MTf܋/O}wNZE^=y ->SSR&D?< - hB7q *Y3, jRcI GKaèb?c(aTR`THnQiV5ǨVŨ@'b{Ti}w7zcTͣzk¸ܣڇ"i% mQ2_~:*Wyn,X<Geg^,`f=T`G&a:vjRBTW0hI&R*z=*Bvܔε&,S/ "(crNb}QbGe#E%$X=*us.m+++ -89գUcXoSϏEc5!g:L40+ȌڒTʍ]0/}!$ᥑ ! V_RAU7@ʮܴĦOPw41 *'AA"} L GƂ[!Эsn@JPI]tFM*G -SLN&xDS :M>9)f&HpɜKޢL81*ʑٞcgQW?GwGqE򑬢"\$w8*1-;a.G?ZWވQ=! -4Gő1gG+)@k{ܨ*;lM'ZڡYdcč5E}K;!@}{IQUdZoTGt2Q}b)qS]m( Ga"\ -P,b<Gucj0rRph8*b`+!QmTW&v r NZdzPT[Yӻw\FW%6pә1Qy/TudN}YQ?;DVUvRU3G:ਨbQIj0ܨ("_ܨΕ ͺ\/YhTDt-_ R  -b8[8(YO -ꃜ"e /JgaQ=$v}f269a(M籛˨˲P0h.#U1_C0"Cw(,rJGI;Ȩ~)"5˜dTMh/ǒ*}HHnQq˨vp̨ړf;HQ5tעQ"<_U -,sFe@Q@ W&Ψ}`DAfT4~;r@P!k"=`Fj[2JiT](ጊquF^trj=Aiqvu{FX C4ElLVrS% -{#ՒQIU ->: -r<"@k.AÛ0bZv>D"Q)RA4.%Qۑ3M(;I)R2*o+G $N{YU{8@_y!EŨzRpcTecPb -IEcT 'ǨHD}*ŋQ+]֨|LBݚB\o?F ~؂)_UJ bTWIYVٺX6?F}$¨XJQDX bNK'dѹ-(D_bA5t+`TPmHUe nfkώnTn"bú.aL*Rꋪ?Ee +=è@vgZ!Յ0sEC[uV*KOAR6=UdA]1ESacU L'`]i8 ;d Q%'״ <0.QȫdUSHʡ24PxQe$]Yj's(hcް7EF0@2vw<3f}=q*8 ycrgfѣ? -"S0*'NoT1 RN'szȤݧ\¨z 9w>0Ӽx>=q1*LJE&yzmM(S1O**kebOAX Ũ ,Fv rf?zaҨW{_4^G-Ө/U=FU5dCFVkTXTmFͧQiKت"OȡNa=QHtըhOKըd G!j+GPIҨS4*lo/FPBWB  Qv'՞ge\#bC6I:+L}ڨ*p9v ]y6V&>RF5ͥQէrJpqX0%N=ups?M=FR)עQ1(PTty^xWGF''8*-߳ZN~9G?L9ՌgQ56:A@(9I 'Q)\%^MQٷ~o]eGG7J9'mH%#R (#ĪWssUWTf5-ꩅv""evxƚΰ==_-D*̓'D*:TLJ` -cLIϛC5xlHAi|i/>HȺ8T0Bo%R0aTkV,5W0R jAY;R -TlG%TSL?)h.E3BO[Oc%{;2۶M=)~RUY|>GoO^t>%}zR5p-o"򤺂lIua <)~RIJ:v`4I5xɓj}wZI5$TXuGf6'ջyO*7,wwrs'O8QȞT&!O|;ӿ-'U@HTtT>4~ԄjCw18k8(sZR)Om7ݘgTL AĒ :\ -uZY J$p6($,A;PU\b (UGN2[} -?^f9:"͸ {BY -J5̣@xɉRٱ<+{p5r?J%תc.>/]ZUTg"I6J<  TPfI5tt(RCb8J(jٞސZHR,Õc捔 -PF<$ʘH -[7])t! ,@lCWPJJeyO)))2RS|!4D>DzD0ꕺVTO$W3(JRf4YRI(ݘURj[\JlflȣT@T¥TܺQ*E=k|ݱTo'_͙WC>]w#F³RXpxy<J8[8JS(J儊 ŮTy [WJEA;޷XJc4yR }+U_?7 h+Ҿ3VJD|ǫ#lG;W**P ^lcRJFOxm3hRqH(͌ +룧q*{?],(J/a3K KF$*{5;1X*_~dTT -I!%s+RţЕJ&JRodu#fT?c¨5%9JDʊFvY+Ȅ+՛tW%#f)Tє-+U@q^[R[ya}ȅIL\XA?,եW8]x'0EݖE'^J.;vSnI/0˭$4c0L5ϱb.".:]. AĎ\Lۢ|vbsqKLATL=AjY*UY053h&"Gb+0:SG"/Tth)$2[T(TR --ZSFa[Is0Ua*858L1L2ђ',+0˸ĭ -gWCUc0պՋA˶QLe1u\[`*( 3S~@MZHyZ`GkL)vu/ S_k { UJ) P0Gvkn`y^ߵ}ֿ.tsUѭVǡH٭?]L5NBkdӸa%S%kIrz;TT5;댶Z>Lɻ[yK%2FTOC#T5"CF(d*eLSB@ޔCfd*TԢ\|$S|%]TJTl Z d7D nx7duU o_e2GBd*K Qq -ыK^40ꌞj=;oأTR-*6?BRR2L%}t$g*YIl3k~}L9L5B[ig+3#LH=ə*A E4?S>Mjh"o^1dS؟1S1]XJV;2S3L5eh7M\f> /KT"S*5Zr7bzXc2UX(wd*Dg"(7嚰.4v3\zlL>k߰%X_3G;jL˝TyEse*5%?̗mIuH+=o*SQy|mrFve*U5O|P/<Ɨg:z]瑱)SMO_uc1en1Uv5#!L¡0 : .}4SoiPSu%"uJ&Jr*VS sFMMVDsN FWfRS }/-:MkWZѿvF2lB8Nq76`d1HpJT.AmM5Pc֦A̩DY]TN8{@XT葜-l*K9Mȝ#ULޚ%S-_S1)(>Τ;k*ޛU xwaM۶ -TP8vl, -N9\ưVT<Wc5t*$lp<{:1eD -j^趈aAo} Sj-=P -Hx yεʩQblվ*1s|(ps*|SmNk׀N$kSJ՞U[RdR8T} ,P2Ouɢ1bF}*R OE@{d^x!T:AGiQgwrJ~l>UeZTP-}&r!cF%S աyX.2~܅4~XHr⚟D q&u{b(S:D?k uI*V*{%Qe7#yIUM1Y'$@Tn -BdƇ*:zbCU *xpwI$Rysaqz阴_*CngqRѡ+QR"}L>|@UuTKcD>{:E8TE=ƂU] ,s`VD qLj |aS9fBT%U|tAG+xUO.q^JqUSD~:PNX#.1rQuxҢjE)h:!UxQ5";z Wbt*S7J<,0Ugk|Q -QUx(Q宩EQK0D%;=jı'IpdEoOT&*%YƠxz~RrABTgե3",`rd$=2GF *2ܯs(MDU$xgt};ֻW.?KĩT֤aQ |* \wU9*')wLXee{>YU: ydx u>L~[+fTOj-!SZ&X ؂b+o+U - {GTyAWϨ0U_{'y-Q%Q55*2|U%>p<,hgؘ"43IKHdJ\R)%-NN%T oSuFIWBKLPyT/"hŌΛ$9)*D[6ù#$Gr7REj~DIN6VIh\[DG?ƀb[H{+I^<㣊e ay.Қ ڪ^؋Y)2JG} -nOe8dة*()+6/M.jjQ(`"Bp𨺫3QU EUR D U>b|PH`&pvA5b>VÞJ7;gBLTKA KbѶߛTA+95 -ew_3ݲU`tuV*KAVTH8?>wzaQvUO8 UCXt1.^ *d1YdIg -ШbBxqUda>Gԧ?mTVՎ -Jf VU]Za먲:u:ݒ>hSrQEI" TxLk -wr)Ql!} ȨihRؙDqugTYɴ(ޙOF[у`vD4?ezq+v/5EÉZH -ib#QEvZQ4 ql<z -F?Z ;\ǁQݳ¨o8̪ - -TDGUr::F6pL]FՆb{Q3emneH`o26:RyR *oT8J!Ө4GUNB8 gQe#z.&E&PoTڛ"Qf ZTYcPNZ2W -mxNKs2+cEB͵9U)E& 2䁘&e|3H 'xąQ'`d3hG;%_#<56Q Ds9PzVUn>Ol7$~$]g\ٱQD^QE+yٲ'9[jBΙ4)UVK &䐠4ޯPQ0KsiGitGjTtbrYHf&X\bDVQ,'own}iw-"U+[qUSA 68)UDrc72 +;,+p Z*g}=,n)Dp,y*$DɐO/e -@{5r3ORnP7r4܁_T\zPu6 q#,x -{IԽQk4-mpmT(LEBثPu`=ՑdpD0*ZS>4ldřP%kP W$P%sXky[QBՀyPe^ w) %*BUkUJ@ȟ MBUdDp5Tz}B UTv{Zπ U)p't,ۗC!#ԩDH"-ִZQ__hgK;;EDt(BN+2Z.Q{in}זDEI,T'N4e1@ -G6l멠g|D] ^]FO)8 [ aC -P׻Jf޲`ϰ@Rl!FDq!koGaAU@e{A֝eSut(_Nb@pft6pE"߮xQSA_ Llpj^XR -U_ɂ.3ԿohYEC{Bee' (sU,̑InECLkXqT]jrsՆ4s.T\fޛ&bY\55g[H6:S^~u.*;CdBP6>!K&7Z+Roaco²k& axq/(hp]T+P2JVΒ 8$[ k524pZ-!X^@;EUًicSܚK=10qyAMYMA%.Fdp3{JlwגH;R\}S0*Z mqmԌc-ڽfY ~a!4anChi;?.NBZfI`cU&wEYCxYm#)<ƀe5=*Dg**(gLVB{]ǃlsb4bx9>j !UZ`/(jyMH"BcUh`̟[Laڈp2e͜јZ)T:Rv{H'Ew!Q20rm]T':r+< txx -6,f|mKB᧱sʢG#V[^䵩ϟ1ձU -*V{F:笢zx+IݨrXIm #' htHǢa냓Lk{qo"D;"D*Ǩk $+.8(o@%eCسo;ĸ;H»fhxmY~O?k1n''MXV!@fW6剞[^uq޲3TpP.Oyug,$4 ܉*\ -E. V|a$K k/)pIxq;6.\_4_tEQŜ0ґK)?>B2 T=m8 !D-ܬB?z29)G8"Kt"'$ |ǫIWR9#!a"!'2,qxOٮ!VLLDl!Ab8"kMlD&"B= l -X6d}")&gQys C W(}bsIJ yaĈ!ZV ōfѼd!y##e;AFB4fiHJavʧv_ʦY1Mf|o\&:t&80BC'/ V!DhJ1BM\ - ?gа_- ji -N2ѿkyE ~M9yZa(,4 U;47F>Ss=Q= -&|& b\ oa$ & M -eģayޱˍv֜iiB5#+8AfxhXL -oF0P&a)M "rQM̬`<t<5E'uLIBBq6,Y=C1)´cUK)5dh̍zNőSuS\Oi\9!Q7XCK͈('ĥS}ECə_Jy2̔ I SF T(u<\ X:>\TJ¤usfSOa!%m!Lt>s9Y|dwͲh60)V"!ڹH3uĉU:]Mf=g~qJ/)|JT"WZC`lK4Q_s° *g`/墪7'&,hcc,9:)҉3uTƃtܧg WET_[i?/}qL7\:kDu:3^Ba7Pd9BG翐1 s %#|0 -G/(Q@yFo qf7!Th-cp/R7'!X=ANIyvK9dC< {/W?N,YǸQ$2t?P!ïZhF zpZ)(?g),* >UQ*d:~XnyAqSBPxD" : R.s*]!|E8#i$hofE uB -^bJ$?M.>t0a$"<|bg"CEJu6 -Oz-ѽ rqSp``0xe$f  -BZ!$q~d`FM*iB%*S -h:^P1 s:6q"Gs?#=jTF5>p;x?!=p:\.0`"..剩`sraKG\EGOŭ4z7TH[o;p^VVoU\c)*GQ t'\@tGGQ7(ɍ |b{e ZTpP *@ 'ځ Q~q 0^ -]I3Z .IPBUTķr^B;aN7:ޙ7q{5*]RD8o.ހ @n.(;<٨ jzn$WMP -06*n%Fu4"Q. -2F٨$dUK$E-lTjy_>)$p)Un \,cbP -KAgr(vS]Hh:{lTZ=o.L.(֧U7*6Ͻs{#n0ɢEn:bBHqFeƍ -:g OC8 u -\|P(I=󖸗5@gKTsϜJ> \:6{j*tԅg.1ZdP \kNJ0íWU9OiLh>'ʇV?afX8E0%v,4B{h*j@h,H RB)u,w.%+9H =n \~Fخ>J:;-pQPDp`#=z%$ q^x 4p<{̀4+) -c>O4CV#y ҟgV;pA;[qK"]ތy#Ѕ7w^-5j|^5 -D;« ]:z OZx .\RP)0 -0*(rb|:d\Љ<Zzt:A*.Z k򧛌L=Ycr̜pyJikv~; qKE'̷,Áԯ%ِD  }h?x6=?M\sWH\^pFB#&X\*!A0Yme&8ڄ"IRQz1 -ED4y,(\! "&4,/5!DO$揚@00/6QQ1Iu\OS \ p6!,^cU\&$1u͎vQXx\JR\&_s 0-rF .7_cQ ]rqfuPma.<-c#.G"k +Jd]~cJ?=pQڝ|KQ+PkYWLa0,(wn"X EtCx5d=|5%J&{Nc8Qeȕi+jBTwM% d> Lϋe>iEM`N/oh&+8s/yUķ6Uf?&һ"7q:>&~f/5A7ׂ[2ŵVKb3W(bgY75$WbN%jMy۷GH5aS6bM[׌ U-aN'ɩw:~-" QOВƜ- ܃"St7it~}lØ5M툛\ںp24=ǀ3ǷԾ"/V;#L\B?vD @/Y5k isH..+ MA"¢\愪!!8\݀{\y^ 14lN&EI.wʍ&$N2N"FMU6p@_7| fПlwu\tcKXhR s6X[a D`7C'ph׮F0WX@EߏzT[/9A.p| r)hKR"?b˫a\C-+p!I9(]Zǿ>)ua\h$.2Fgswjx.A2Ksr.us 耫zMK7#>Ł \̳\2'lj.O@`<<эs\hdk(-:Ɓ 5azE"C\T:04j8sov%FL .pt'gp1Ig;{aħ4XA_V[gh(u jjq.!)xMpAЕd0uzR!\na>$[:Pu\XOq: \` b{N1͹Fe\C7:G!TZ*i()3⭥~/\BDD -3Fa3BWWu"%W806tFV uW_cRNtR4n p/%?\0DeXR-tl1yey} -z"xfU%<( Pm{V\Y[jp=#F>pń%|:K p7 ;׬$ZH0 "oCOIS]T\W- 'i`Ve-'нp9-iGY:,S \- E-i@sgo(2* GS 0^1,YpKd;S$*ZBC-paHR_!*flr\YbK \DE8x.յ, òjhrN`<:ϕ 0px;K " -'IFKW߲'$shxKRvGK=~h M .nUucpl˦J#>"Ψʼ9Zrϲ\nE+"4Ia\P+q%,>dj.*p+(]#pC_zR537Aݮ{ Ħī"пE;qR\ -ݸ{K2%@HQX ,wd|kx&"('_K}}ϭgaV nߢSvjnOFFy. "Ʃ099%,PZ#y0;TQy VN 򓙬i$xE -7rJPC7=:+tJȥې0C:e}Abb!J=CUAX^H.Č/Ė|'T-lN Ҕ|c0]tS'9%t/$SU?SM39Mr9pEP .NTUR"j@"Rb.b HDNu׷EZ/49XK? ߂}lT[F72[8v "~tKB\'Ϫ &bՃ)Aj'1XJ%.7QqdTI4G'm19ƌLُk 0p"S -fM}ٙf66.zÛ6o#D,. #s+h=+v_ {tōӁ b%m-R5nQAܥJZʷZ$ޝ9[0`wղ([i淫ǐԾ,[./[кz[R} ;E KXE?œpߡ$N3-"(f9+U"`H 4ѶLGp*إQnCBS|[pҭo NosJUbx[p=ICv6z6YjrAc{,.0j釗A !'_nImu} >Τ=J'N2Bj5׷p4ٔ9ߢ vGIrHCԉJ[ iĿ#D\^}=} ^Zo1_ޢ&)VU+WXV x[a -å e -K'+`z؇#xŊn7Xl W-XJ++LWzB e7̢pa᭢Nŷ߭[Ul]ay]a$8E{(iuz**\ͩ"ޤ -Y]Az*b2dTt"GL.*VTT!bbTFEʼn -BT*SY!ƪІ85~ձ̯DjoB&mPX8a&LHaA&S|5G5N+€]',̄SМUS\8a<䊅 e, C6* Tc` b1 Wa:G +ݰ0!èz@̊BLhLĴs $$KKMAzJHd1"-NSv1/BcYƚiab1ixcIrVӱ;S 6p)M xUDNd T B2$IU]ęp'QSʓ=Ϡx<)IwwqR'̯[e>+FKyef}ҸKu0tLez"ea -7sܚ&b` -; LA̦x5`ό#5 L`t7SS0zesgLBgF:633ۑRHb_3 na`j"ͺR3U@m>b)dg6+si͚ K)#))"RX.).˥0Q/Q|gQ,GjxFQCF֮?#4_?[EҽI(mR-Qa9H؅ -: l(Pgy Z(pn -fޢ4(#> M ?{ख़i3ʟhv @; OOOW H k|T|-'h&`-y@s'dAO(%/Ow<(F':;!RV[UK#e5HwqԮPGlW>!ks_!lL&7A[;FKvCעgӱ5Gb^zˌ׵BeDu~¡!sa#M {v4B"M-.Ec`gj"xElVD6",CEQ-"G;=aa?Y6։!&"dD@qeCR"g$$g+m."D"B(=$"uCNj4DVI"6f#vCpm!P^Wg8Cat66ro#!:nkSs_-0#5rWs `[-pt3 ۧ{/֍ -Mn!2IMj̛,7~n&6 [²{Te}!T/7#M7D.nηԜ7ԁ0׽aȽUtCMn[ }!@o8S↘6 4o XB P qCC_I/⦾V !|2X0…Pu8Y~gWdwg -!a -PO'<&E*%~ !']+aTnA &ă}`wwSIEΨ ڇKC\0}s?7|Z}8^eC$(đM9w%ň =k'Lt)F8$D:D}MsB}'.A WPlǢ8}tS'n ؔDa: *T_PZV^9LAWL O+>@J\@d( BBE.:="NoR/q bXRMYTLe -\N3廥DS-Tƅ/g8YrANCΗ9JIK`.O_V(*G -.9YNM@\erDDn K9}5sz b&Sʴ9_K B^-:'Ws)kOY8^gdzqZ*ߝ'|/ \9dDsJz o3/~DOt@ -t { -T`A Z@T+D|1D}1?$ PN-֣d"@1  A:ĵ-YrIX_s >݊>gg9UO'^9eX 9ds9ۊs]9f1ĩ%T s<ԙs!Հ.e@t16ѝOat8]tr?`ˋ?6Ɔҙ CM?4v:{ZD"uC~:aա}C~~.Qg~-_A0!,WW|ʲ|`| GJD|>([%+|(Deit=4{Ppuar؃Szaz&/' GN֕Qz=`!aL7<_ɃCSpƃ?*(*ʇxw:'}t` XGxAQC> 1^3l5߁i+{;~l,6CAC5B.:!Afc 6.w>eݬ\&:z~gN/::dkYg8⥃2ı¤FGq" u\lk9 > pyJA_c™jI^eaPrPຐbuvI9d upjXG98ŋA3ˬ;8̛u*X-qx8p᠏ylpzpXH -vQ!p`3}խyX#%A -ThϻX:W7Ԉn0(x}%` y[m8h!۶"I٫2۫T@umkݼ٠N]R)_C&`.+v_  -NvnXÄ}o rvW51S׎XT mm; ƥQt=[ w4 jôq̐3%& 726;C{4$*J% WhpDI^3 'x|^0π%lSa |7ig 9T!A3 w]3ofh™aݎVAӛ%^9365Ox 2@xJRxQx1< Óg3s!'ݙkxXtEFvxi1Cs W<)/ٸhN6țMX?yatIPy$ +cysebu Z 3reB&1Uc|/3=E 7l E=Z/ߩ;.ZW7/ucF=0^*@d}*_ϻ.JS9:^nnw`EIhhЩ6;oWlz(Qq EN>E+|v|a]re}] V|.Yoa1O Caќ 1_ҳO>c4Pr)CL\O د ?XeXH6e36) dX:MJF2իL hn"YV .2nc8ŏ*h31hbgU/wibaR . S;S"% t0L8yt^RQ^>-^hWwe ]hݾpJQqCdN4dO-,I<\-; Pjf q\÷p{pgnAn -o߸->yBGL=B|pՂ4MX_Ή-pw0[f,Yϲ@( 4ؒ aP8KÂ8bE A`egW^ -t>Wݮ`JWq*KGP}m -նo8+0V4l_W -k -*VM&ھ;Ϲ1g@qh>l_c}12{Dž3Gs*'TjT>2ˣ\M98HT2K9{M+Q摧6r̡gY}c"ek/u9/xp CVTjp Fjߘ, U1ݥ1sbP}}O}S'!=*F7⫢BBG \O -PA]NrmBl}:0k*d%T 9}{)>N' -`M  - i¶xs^-e>(T8ŭY;rRh_,T%pi.zDBJQk#T9G00{s,ALKml#tFF.}qbOM'>("43HE>/7e^c^+4ix"]Ki0*LEVw>[S.W?kx_pp}!A!,<!ةyREh0E"D،P}%¢N"0NFC A}g p5kpoHod޷'z}G.MWlԯqQCن M8''\H}ahiXK[zqwd< "}YTQ>a#!dK|^1UCH0iT}$^C@:ZC0)%`ND f…,X*gP`B?>nAXI}QsRja‚}hO<ѓ> -@@0@LA)surADbO>W?8+t`.ϚA[QA]|^كq=pM= (=S|!qO<{NɃ#ǃ&ߚƒ8u/Z;Zm8Qv` v1ׁjbkG t ~,o~?_<$e×+,rdrϐ8qp&(8М# ? t  Ω70 o )8/ێ 6@_)m lpAȰ9ε;Y nj Aj 偣? ip/'))3 W? ?ޣ%~5=h~1# Yp)-bO jplc 5?"A+YԘ P<"PIg4F¸A9I o$X&4hpƝr7M3X̠\HTKBN` Δ>X'X&\(Y/0a5_Њqu5ʏ^u/|E0+>đT~  xN V'V~,)h%Hp..S'ߴpoA[[[`U~Z@X (j洠#凋/teb{oγ`ZhR-ފ?d ~o 1,zaAn/+h1R~CW`[A/)G*7 PUA>*?*X`B*JE*T$\A -n -)r))9?%*Zc `QҨEp&Q -4P@'3Oy2@>ϫ_1h@4'8 Np/󋥛6&H`+ye:3+H?U\1? @)A P#=JJ$AGl JGPG#h2""֊tXk7!rQ*GP!­' [/Z]TjT o'|@LeP`Dj Ch@wB 8WL}>I>`\_zZ~,cBi`]b[~CIq~p -pR8tȣ\_[@-d.b | H -+V`VGgSQ_Sv;p*R 7ȍG -I`~?&-?@nyݰ!]~$IwahK` -t]~glXa;.?8m[P+`Hr-gfuĘ 9O@ -t h'IPl\O 䄊vDGY?< ''lRgCk0 O x"u%[~~YM+&I&77 TUXeGS6ms9<$=t'x,XZ(@l10]XS%Ќ.sedUK {pY F >4 ,&5[6P=awE&A)5=O JZ<Qw:*/*5gg>6/o/@vy6j8n+ezSJA؛zBkjcE HNؑ膀̳ .>pq܌{GtQ ^ ]DiA&`E@ 4H`jL?YA~=n(ڥ,5-BkFJ:_tXHEϪ@ZF./PLIkZʔw$4ikj Z21l'z -bwx+}tuRmثm'EhYc`QjNWfOƴ^.r -G `/0 ۮWk6ie*<kʜJ<EĚBf[Twtfi+'H9M #!V؀p\C`jH뻂k~xI,0^!`\ؕK1y xE;uXwQ%  1lu)Fyx@gD}ˌ J8V^TbzD. Utt1`( J| !ԝ4c(@10'@hc6"v:7:^sRu&` -H83>L@w3pbEJ6u:ΒS95]kKxM+ky:HWEC" tqL "@V},D~ 0̇]n6)y$ 9MLRI |j8% -ј}?@(KTWPNr˚!XϤ̜oMK-ʔ=@|Jl81]h:W*sA=?|p!۶PxapLԡ~5{.9.Mn_Ϳ0 3$[GIyD$xfgg8Jd0-uϠ:_ّte`a/_βQ]>pkÀ }YX*tW _mP.@1dAYkHWEtt˵`On`-'Q -PE!+: ")>^ܘe@3.^cB @FEďaU[] \˔`!ޛE2 4H, hXsG 8Ph{Qա2Co6̍9l1C+@r^og[7ҍUa|&S @%LYDK=YFi"D4j@.hH5[/k5 1Bc JwYo[ -p dfuI /ɕ[&v -c wO%[)ӥ[IX(7lͧ* - ͍(dXv.W#F#hn&wYmX3|Gg14LvǪVrwefXx\b^~^v[Mn9^7'wDs3R#sm^H [f- QNw-> -*yʳ˸(bu3^]bȤݥGӍ%ժϿURz?IJX}nґ>>WYRUƆ7g/4Vl5SSМ9[6\,wnC_锼OMMjEN [Úkh6cS"ٰ2P6'Dblh>#:]Y躚Ժ=9K[5aSPijh"KY)?R ͱa: -˙ e֙ *&Lٝ~vTiU"4 2I)jrf&=5yfCթc,4r_Q[Z!ףf4`08,n3 N͍ -lѪIrE$ 4aHP`P0@ -8(@ ,V+R"!OG,cV bYֶK=uLhpiǖ!^qO}4hɲJIH65SSʍ3m:x4<Os΄N9sZw#Ыn77Չknjg\"G˥3r̭3y&;CZY3? }O=Dߜh>stream -WdQ\rv8f8 dD((.ڣX(xqЧ`(/>(jĬ4%\p0Ht"q+Y;8~[b;3!mF*9[aG{NJwtX - -A ;]̙rDC3)љ&]*ꬎMhZƏbh֨rx?DBFh=KLCב] }V "*WU4PP*Xg:IcnCh%23p! -"ӑ0lZ%s1?a+KLc(a.<5TjM*k[({^JIϻE~JcMcl΍ue]PQUwӈ˄䚜q@PH -0$98yW8$ - -4l` ku$O@=;1G #0xCb2{WX<5Lmrmk""nco{7ipB/.Տp7Mڗ@kY11j+JbL7=eԣp_h+}m+S ZG'amTg|VlvC -_u%'@ή 3)jũM99a r ytߖ؍F~_z}kY=I%ГϜ#hNGG8KG9q,-JH#6%5J5QH@?ήeR ›z Pòuڄ'Եfwzvuٹ;~d2ks߿D*EG!а! ޘN`1: @ĢʁV{[olԐ'Vph*' &:҇B˓!Ng[ -:|U\5o\ZX4Ŀ43N@E -Qql~DI@o`A5޵1uM2]NF,Sn i Go*[UhC>`rd0:P 5|)R^4rxN R4JK9E 6 -:6's*8$ɣ6WYP njeF}v[c٧X!Y2АZ; -?߬}Yc֍l[aEÕI7gzjFy$ט'[ eTI%.yDW m$"IM{oŝPfZaaYN$.[w9K]Ag> $%q~8r#_x,lN26 ]':¿'p#?|Qz"㋋\^5 m,j1!~?KFdxڤio{l nH4s le;mT'Y=&oe)DB)_F/י噱* Qe͍&B_ kGu^Z x :_B1lv 4L4&B<4PLNY'uUs8cv#]Ex$H&B<?.5M瓌eK:X:qJb-r^SHZ;>ݻU\q[+9yU3TZ=ave.pqJ*LcmRQ^.FBU6[.d' 54;MBOdJ:Y r 4,yW'b#;6zeUsERǖp-=]iM\b|!5e,rs(n=y;!E'Bž*i&5gp0+U0v0pT+2l? 6: 57W̬q*quic=I68@LvwY&!y5ATswhc,b`- P 6pcLR`=Q~ďin͍ YD$`GT2dж&zUkF1 V{{ȲnP%-dx4У,80YT3J.NQ<GՒolld9_6Glȩ !];ҋ$Ҝ'q j?@!$THZ`aAxo|_c1=BІz]0saO<1xSu߀Dp9Ğv G{g̅-qCTs)M\L@(8t1mo3qpyQiGȟYoh 94s{6ذ -\.=] -MbH쓨 -Rh&P?_vE=wrD@ J0$_3E焔 ۥ -̇Z~+/Awgk+O)>;@I 9XH0%v%a ゲ̵jX !C>.fAPe+h_tX6EH(3R UVdKо`b]r4*ggޒeqhD `mL/! 2SD*{M.M2b^t#ՖRtbnJ1A\*B,zz,!},6BoG9ScD[ZO7)D]G5 binIdL/XYY{\'adž_W1}5նR`=]{A}b"*vV:#S$tn}uˋ!U=Uї._6 e0̬i湏 ` 8ⲔT/.JޞbX)4Va#l) -h%gxJq#F7o(W;bD0B?kQǺ iֽAX*@ -NMMxC+-"u;\o#9lњl{'rI> GȤF<4ۙ>̃(xviz.zNpTUHgkIq'tR>HYs&9,hYǺ&#ƠBQt &u\TvoR)&?xTi;z┿ԃ!cUљh=Z"\K7;>)koCTWAGC|]V6$F\L#%&]tePQ\hQI zX y-+bO3Eede"$%t3T섬U9C!2bfLDQ4㚧Ex -9i -a$00ոI45bVP>kZhlȐv.L2km^MFiXF=gq]F\eq !;RN*l4O%cwQ e_Aa6z+݉ĺz -frIT5UԊnW a|hC8kZ"83Rn0RN_iE2Z.u&}SeA,< ooLtJDMe!Wi:\PTKKg̕dѤHqsfPKcnRVg.6+*ǀo8ؐUSs.bX,f -v?+\?wTJj SYYLC*$ nO ^ y$Z;' -# BK^RXáԆ;x2qQl/9*cs>L%:h+> -ȪOBz&6[V@w׶wB t9ӗN b/ȥ(Ud%Q%gE%4Cd)w$CqŢliIF7rc(/$nĹΒϒ>en eX̉_t )w.?4mbxmPpe$Ҹ9ivJ1o0+ xdr[+'qg+ -2ЗK0غjR|| ;LD|xhbj\@oUe7 bαD4% -{FS6S/}5-"q+\oPF -/M&9""/̯G -r$!}`\rre>w*عBr',e7tp/4oúfoSS)=$A+Ƚ|UtVox)@I.,Iz{/A -~% -2C ެBE<87 Ksfe|{m>ɥ.3#Md've-&K-p)7~aЕ6'zjA3gjGq0lw{VMKT'T,bv$_R"ΆaxRe$ sv/f - _)Ohad,eULHGc̏BC$BsŒQ5eJd!F6iGW*4*g!{HlaF4X~2z;%\~KX LwDZ>Mi&߻8Дl=Q71P|pCꃉcnVf.%;FW⋙w2J w:ac_U;=9BDY P~b|m,~Z竼‹_38Bp43H<nI>[OI1 \`P<6PW(>e"yϿ8# ~L졼i'.# +o 0M9A. 02]M\v⢱`}< f!EZ/L[1Lo1+- -Q-3m aoKşaHH`>#x'3|L0ՅA -e֣:qQj׻X m5l3o&:@d/>XPa؜ŴCIaSÞ.nfkXai;ba-k5l#Mf$6<0`-5Y\|8w[[\ЊE ~-BvCқ;`h\@ܞWkl{U_Ϡu?"4{Ya hh|34P,^b+C1V8yq=ىzCk텦60*F4Mh6.',&Y *14K6o -$Рƅt0 -TC 9<4$+Fq1 hgo\DhqqAIEF#ٸрmh1e PgX"ZYo\\72hkl9q̞wRh4y~3 C7.fK#0On\X2e׎őchyЮqs&7QhAq1 ܃vSAsY4Z@`TnASոPOhGH@d6N(Th -M - Stƹ --Z>b-E:C ~XE2.Fڣ^! - B].BxhfM⇦ 6sb3 aEa$#4b`a=Mkq1 - -_\ 2BCn!Xh+45F<%/.BE ͬmhm"y4l1ņCHFԢo2ƅjͲU,EDФe0.PjiQŸd*0.Ҵ4Iim%AOc&ڵ5ŅPF2hjSfTݧZX56jhZ.knV5בc /ɱe q!YCe\ekT3..5{kf]y5~א -Fkָ9h\.676nE [[LR6*۲'Q2.*og Xf\, gCag͌H62.2[̻1괤 El9~6 /H˥j# 'fm#bי1.E}oõ-^#Tܠf(Q}@FOvvƖqQtkgzn [vn =6)b)ގy[z۴ްpK5M/%J"}h"K&90.RmT-<9B֑l]~^\@ Zø@-b\lwXFq¹). -pťq.x0qP88S\"ׄfA(ͨh]S:q92A4m=qWKV\Hvsqa|U̩S_\,pq^Lqi{Ś([\/BrDLqk/.$:qY%F`KkqLGy3@bx? -C;=P4kX&,,;ߨc|#h$'YߋS6c\k;fbƸkqeQeq) ˆZ\H/X\6N^#o2ﹸ]~so~*=ыl !1.Fc܍qb؆@gB|'qXSP)<+r`(ʕu1zXB˥5ԃ9/.o05%Ϝbroq>#9^J]AOw\+Яns5@9 ͵#O^¹d/%S3Y9N .Ti#-Ke訳E'=D|2 /)X<*.D׫#kOqᚨ -a!€rJM6]b@S]y"*LIq"As°B9b *."ss@pV+.czh؃ B"3t} WVhᑎ,[qg#WMGI.ԉGz/uD~U;VW@q!lXfXKS T:UPE cUCב-"ZMp&9E ` @②S:ugq-.[;ٳI$4saqaϺo]3: -2-N\u"ɵLX%uUE`5qVu$.<< wB'%Cm҄^Ǩ:qM8 AkB\Ԣ8@\|EC2`Mк~i T^gl5CE6Nqq]N<BB^,ur 2"k:>.p1#*?\1c4t zMr]|j#pnו -׵`'awJɹdfslazއ V}v!vzmBeTl{mL9x8܁ .pQ]"Bs;(W;iuٷCuJ\\&.xz{G -nxgW@s/Jq4x N{*6X3BWx7hw<p8&.PmPpb оc[xץ/{R*=ÏdkߢFIoѬu?xF(}zӾm}a`&koqd`3FtTΡO>}!}`S"[[d໠ooaVҼ}I(l,}br^>a.8[$> -.dNjg\xGў/S'[U}!2UÖd?AG"ۗ~6Ozx|g'%AWt <ߘXۇgs3IhϳXgy >$8C\2l ._BmM1! }o8YdV$pm}%V .H"\E#jwdPS<>wk+qsG_I"1 M (S+_ վ;)*>upR]v|j_?(}!.4ohӃ +UyppI=9+#i_R3Nx.>R éw( --Oࢢ}m" -;EQ(=$}ԒrHpa iv,V=vXf߮Sc\B[Ef8kŏhk߾/! .nk_LmWl_7A[ ¨\G%t}ھͶ}pg5&MGOJ>C ."PⷹOIO.z,}..`\ttO |\D-fB\Χ+ T4F%Yv4hW>&aErn&~ &dT .^ *Od>?' .d["}q F .L.(<mާP\"Di]=?j5>(\$F-'h㼯T}aޗ}}n4. O4@ P;:Kxߢ|BpQw߫X]>pdErf{8 -\xE ~@1M|o!o|>䠔-Do Bl^Eww.pkӷ  3߇ ?Z;p1}a Moպg²?p1=9uʛ;<QܜӁEH .@MN -.Td21763]pP ~ࢡ~^%( u9-hkDTpcQHV\tQ?{8goc(%hKED>>TYK&"h -.Fd ~3 n8=D;?}j,uGp&z \$̀dg{nAvSy~T$?v{". Gɀ_V..$=G9E.eY. 2-p!UX.&jE9V( v?%pqHO  o߫ώSG"@'>0ߓ. -pDfʏmU~˗jxYXT~oF7[LIp @ʟ JLEp_{ٵ)cp5SsW~3|\K(kaJpX9ʏ BKoۡVٕ*l\H\ו_ K-R%[//Go[,-bXRrZ.l+*gWI.0EXa!Tu921f4G^џJ').%//I׹-oA`I8 GE[4}E!8懗;EЇW)ڂ\YmJ-e[ѷ̏M`B[;ƟзL-Joq]+}͎lD˯з f}fN}{P-%Q[X~l [_%ri}۷wjC#ܷ >)|E$W[TV"x)}} ,4Xmo9~ DXo[VxVm߂i{v5E-,7ߢFmIąֿDřAIL&go1ؗyUoQ1]~!-/wBRF)X2i:a-%q~9{x2s~ۢ'?KM\<-Go@[thW#:~&(-4n%-xpdb.&llk&oYWo1\nq ޣ -}j}loe]Ow3 #[.hnQ3p&O ,aЗ{HyY[Ph\\dL훿@PB© :۟Yпu,4Vo .cM,[*oK(Äy6 [H &"H\` e? eVН*e( -pr, E mQ](Y(J.$[D ʻܷ+CoÿŚTAb\ CyeNȿč "@jJ\HzX[/]:~B o~QTſB;ZSR5g9ApA{EVcPX|HnmK9PJR3Uo)oLۨ<+iߢ|Ӊ/{ +՗w |Š -` weG߂ۯ)LH1F=YʹJG)6ԣb^‡I "[\,[-vGˡpfO&B3\Tx-Jgf( -8%%}[H0m`a)%zТ^? ^m]$g-< #$gI6h?$K9%\ğ6%\$iޗꃮЇrU4~Hf3q=A`p -ڷq8ʹ%bU\L*qچ9 -~_Sc<0e.Z.態ёzw<4c"5٤>g1,0[25\q  o(ݦ>cՓY-\. YbjgQE-iVT P:y$)к-I؆/"QmBB/ml z#z!m>5pJBt= j>.tl~OJ5.,W~f 1y^pk -r_=r-+Vse mj-|}%$y_GB#K VMⱑUj#ג3{0 - -|x;1cbha kj -h&(A n""Cv{BO -zBb=s.p1UU|.8kr`vc:sEꅔ˵p1f]0\T\y5J[`Pp=ʶ`c$yJV -:`"q{:'!Mp!vNp.FzD.F[SRau+d}\sJBE4)@ f EhJ. VGp?hg}*K:M{\Oz¤טw)K&&N,o*/+:@yU‰ =\.evLk@p<D#K:t邼\L6gv Dg\Jy?$sc-Jpۛ8,`^+ERApxYR–֯Zl#=L[E tiࢰH,E_0(+.D9u{ߓփutQ(bH3# ^0qda+AE"B/(xKU*-EM¤^ʹ{ mJ/Vnht,.bVIcP[I^k\yn5,~q0҅U lJu"7\0Cՠ{E9{V h )FaJKX.](~Vg/]@CB-sSM/]@NӯfPꂋ0rF̰yYr0E2a_B-dRKȇ[]ntA(ER .U-[]5h! .ŠI.-]XUXp$ZGwǂ!7*'\Ħw7( feB< -DZ<5*\oFAPeje[܈rd%^jh\t h/3$\,>!LopCG$&&)WPߙB,N.,ItqFV"B R3=$Nx܆SN@ų`\SD nɾȥ 2fcP\"7 k/]E5𥃃j_< {aJ= .rUΙ"<]`% of |'Da`K;24H4npjGbMwnZVE${u#C<9.i u`018`!hȨV}2Ǫl}(K3+y$. NP7Ѵ < -֧%sagCM[?g]r=b΅޲5'}p3!c(OzND ;Uй?33G|š%NEbY 29}HsA$: 2,UqO\ |[%T=T ^z 0FV΅IQ > Z8vp#XYDJ tJ,;_Fe8!t\6?x{6R)pasPPހR\#Gdc]gjȽ^!<-]a["a;*Hs +P&D4fh2' .`]9G g(t.Sа\`uĠ'^ȢP!s.ԙ/v\%ל$ 5B]JauqaJ Z\ -q-T"4 $h>;qSPNusrWŰs.1y6.(Bmǀ#[(me*K\H>8Q eW~] x& *$\l#1>!WϹ@`(C& .Ɯ 8(qeva[7'5*1KPs.q ddu_s7IZq)ĉ.gLGO acKNI`Q pO>^.W -F1E%XZҦpURPI2H\D&|hLXx;».eD"?[`W#@Q7tYƴWS3M, QSKVͤNWx}fEEfqY߈jaFH[j|_'Sp{_|4r_ \-XTK&$<< 5?ͺ)CyivUe%>(gi԰nvמI1ک1KNnVt9y=ħ]s+:ɑaix=l @SjGɱT\Q3_km@my QP6xLlFQx %s1en(5r>$bad/`KQ5 -RÀ8~fp 6r!p̕NE/a|!8zWg5PUBy3Pm!44C{t[Nمq"-W߀DbJv-0x ɞ6D\ﺤ{Yp1Zp"\}UBXjr \[TFr8)DYRɚL\0D|)S5PB&DBм B -xjRF!O+;RRDJQsBEJp}`s/J`+^(Jt[׿ aY͔~O~!S<&h (GߑBsVDNI*ނE9}PD}i1EPĢv؅б&rH!Iin@0hR -n׎VKg0Qz7G5_{-#%;b i``i2xpҫdAzh1Y* a"Bϩ7UŬUcPM|] -4h! -1~I,"j##Q¡Ks^wdYh؆IkDS>&}cӅ,#CĿaNʿ7GRQh\D>"9_W ZJ V WūBlW%Ux-ѫҀ\F(<$[u\W_-ы鵫gT!'-HŃv<)&yn!"%$'!PrpQDvėiL|LYFݥ"-h0R#n7]=jє^-%1'O -ŨB|&?ZH5!#dQmъbϗhmN-N?K\dy!xrϏ贋 I%ģxnQ -d[5_0KnjzU˺f5)WqK>X!1NIijUWޔ壣|vO)WKpԦ*\EErjv_Lݖ P^P^D*5}^lɏvT:\#;Bð-ey5IT0Gs66إ6OZn\evjEM깃^z#9M;ٵ#βѺeu(ҝnP璚!m7$Ch:˒448y6ݶ%;Qq˛bN|Z(RM{nEo5ўf97Ď=xe} X4&wmrG*ʂdGMᯓCAYVt#bq"wZ_&s_2'ŐYP4ժ$|ׯ:>m=J㷛n*i=Q,1TwnX)]*B!1jQ9g%weIEIk*r1zdi5Cpÿ<%{zWZSIO-T52)Tdkq1-?BZw S!9}zWn1}T0jO9fwλ?O"=# B;lslAAn6'sr6':ZZجrݽ;H=tݶtJp̛-=YY渚PNpSl2}1ǐ6gNVE)1C𓚦wuu^j @w(oG0Կ6s!A6jtslQ3nݦj4 (LzwNit]o锛qbA:XY'pԌ&yign-Hܖf/|մe;;d9;`[3./8f~q; qơM=ytS)yƹnZN8QNxDwĻq ,h<M5-l,96VN:9~Aan6 {8qkGQQ?0ƺ(TEසGK'F7G{^q `(cr:ttAtO;#xu^g4Q%n: -q·XiNI\Fr@'GRNs$U晵[gWXM39X0ñ:ZsYe즁P\;X0C8v[u#s ݿeN?䦧w;nlp mhC~~IBM HsiݶNhaiM=&e7ISfZU|b qXTd~kpeaB!4liL٬s=[n{jE-k9MĪ#}arK*tZ^VmsȮhf} _q<2`N;9w'EۀMis՜vsişWmhz`EE&JZ\:q՟'{GWFÈ<9:4hɗ KfA RS$Y.s9M:f5Nq@빪iOz' RQYhIׯzpĦEmHEohE?G̞H]oQGQ4iě.8v8qNiwXr8ffZq%nz cq&$javMA@HղVD/o2fYiYn[":.RS]id7Cbl`cw>y&Sݲr<ٍJO[ ٔθ:r2'/񖩝 Xf8A2 Ӻ0<9 6-qK篣: H!q7W먜MizIpGD? Q_ͱGG%eAO rZ*u:)"n v*=ot. [Ufud/Oa*PD2i={Ic$uF/jme9F_y›ֺc"\Ȑx@7)dO^/A9-~z)_Wtͯ2'Qm#I_-xIa(kim(jګe(VC'2<ߐ 9-9/Bn@P-Ad0emY;٨Yoݻ<,z0tlH+ mYNi/ JӜ,eD1Oֹmt0AOVowrSТw,Y_uNG܀(P(NxP(R_gMK7 ( Dzr~4Vv8Z s=n/y(E A@:.y86BR0\)Њؗb}=]Thڡגabȋ"}-Ëċ" -_n B] σ7Mܜv,T[w[ z7v*{Z~L?:J͒כ$I {DnOĦ\6:TJ1UOhxv娏` v5]EfĎ[q+JIZG5\a(QZrUUԓ?IPq钚"xwY/~\* h!\޾!sGj`-Bő:QjҪ~γ<,sQt!phq8-Vtי qRr6!7PsÙZMS;w^nc lX>7N'pJlNW,/zʒE(r[_1IRz'w?{(6smaoq'w\q^n?6r.4P먵%<=%928w]y~)fR/u׉q"sx,39{L)rM89nck3wu%(q._ec6\3X'Kq:βAI`%5~)Lr*#Ubqz#hrY^ Y -/=nӡIp9f"U1BP3b)2:S y3A/&5L*R&]^eMj|<>ŭhEEɛci4bjAQ (}TxP'E^ L_EP6ufٸڦ"5?&qWY8wܻijv8jn6j6LcմbMk4WdnO5}L'Y~ʲ:=rq4=~+NyffzrͲ6븚o[imc^}lI]C'*BS$){m5Gz3LJj)k \t9Śje&2)f#MKkjae栧/S"n6'}3D%2>%SBj$_PUjՔۚ5dF㕊j◤Y.RQX䷴׉P.UQmY̖T?E$,踡"eJly)7ͧy۔zP7B*j`@} -ߣ`O?')R}8~s> yG7I]-[1*Γ퀬Ⱥut=/AAr688:MSo}Ap'IxL!ùָXzP9pVlJf$ wiU?%YJO~LvyYr6fgjϋ ֲXVΦ:^jZGs $nKtRMs7M6w yY=]ךF]_unk=GPId5ã4==[n%=ނ߿EiRSR?vlaEКYDU,9ZUղ=)zFT0E(=dpNeU'r7 hf%&ҦR;4y܌sv6(yn6<Qj{Śeo y(H{ry›Ƌ_*5=dHqN3AGsiVRQX-AN]oۛuG6$qL;67pdc("X__I81bĶq3f NҳD!G\|rOZrm}9d]]ۢ*^&M%]B>D^/> `5%ycKvK,jzWzPc/=q2_Gqr#"$Wʇe+I {)xun -^EV^nY7uP7EQZ~RRԦJ=Xk7ۨZQy)@>嘓I%a1;r,a߮L%*-]"?r(L*M1?Њh21Ej~vb;,Sʏay>1J-byQd9λirםY?Pj^s8~:d[l܀.͞כ^(fr@d.'ETֵ=2tEn$I'yZOSzw}סͻi4G^BMT˒VNo:N)u˾J?KњhIRJwqrE4z)j,݆-CYh-ar OZŷcD]aޏ$"6N \Ϣ)XިEYskߨE18:zSC8?*3iEIuyNRբ(%Cf<)bUfHjM֫EwQ>SMC%DhMY˺iZo9H^v:Ԯr<~CgjSZ")E?*IO{ Mv/CD{MM4IH!i&]p[YK!I3.v0H4ٲ"!Kw{'qkڶ}A44m8<Ӳ].:t5v.oyoN6}{L:].6Ǹ~iyqxƖi{yd.tv~۷Ly~v~{]m4Y8{ߺ64{~$p4o<7/{x8Ƀ|A$0J!keZqko\o>{|iR02c.iۮ~iwi&sȄ43N0jd+Pm雯uuZyYm;y]kauN^5^{y:y^=O4.9=^2=^2Nxn4ﶌ8^|y^yomiq]u7~}6˸X1;x|4^߸:w-#moY~ߺLww߻-w}}ߺ9:O]nz]z~~㹼㵾yr.ߺ-7L4^5x56on.77qo]s뼶yeq\es]uwܖ{iz\u]ys=Z;xo{wy{:\m~Zsᆵ{|qZk]kqs횿[o]{qe]﻾[ooki庮۾ﻮo{۶o<[힮oum9^qu>y=mi{^iڮmo(y!E>moCe!cԮ&*hFH!U_ -sgYjY} A0$s2a7Q ;NY~nfXDGs@##4),":LX]!` մ(B|,ffbv:feN$O8)c -Rק \Јxa'/ ,ffBXAhC/cqpY: A}Q-ۊaf*wIn( sY'o#i8 J#ExW3*LcIq5SVG`Epo͡hfܶfo#%qiAK Q"x`+$2JXYR$ԷFؕyT@{v;N&2oi 2ykk |~ZGUh(1)qkU*Gl˛g-!>Oa4glM7OvV(he?iAӏaxc -˅I!;beR"tOOj24NLDGUuPm 7ri-@|,N6n6cw]GtuۮWIq0IikP!q)}XL>H"L >b/IXn[7mö\ϋ?=b;Iǯ - -ePˮYl,j*z -XhMGp8E3;N@Ȑ y~^ -ɪz.rТHb>45_9_bKIz:I@+u:y\'wg}ar\qɞGx..=9 c0l9.M~ ~fegM ^[(p,ZO]P>#;V@ -00!4*,1űEM=5r _ǚc,n!cr,oCP=Q?*<3Rpb@I$mPGWOMU" -Xw'K:,l7MQY V 3 +1kC&eFK -)U6OSF+9C6{ QqETH{r,q1,l toOQ}PIr -[nwu}Я?@1Fͳ ;~5G Mcl4q9oG۲U(9>}I~u5Rbģxoni` 01|F쏚pggyhR.}9_'-˂N jꔒ"amegC?E*f{XƋȇA/AHOQSΨF5P^*T'ղ$m=49Va͜J/ a%v1&b&聣D%z}TއUMOu1\-J~'Ƕ9s@*}CPU>!T1EQ5>PYN3 ZՑ˾GC|G,;{u/}PӤSRHTB &{ď!Z4]&h F1f\T(Tye!E-Eue=q6"}.FȬqHVrOQ tuxN=Zz?qaERH,]<i$gS`Hn@ șuhPCQC;?Ei5GlԌ1ˏdCM 4gV)4Q2}㎓?+:ReH ,=k؟~}IqY4)UA9nDp r+VDK -c} NQ4dz(IbWz޶ftsD%<C%~H@4BX&yݧ zC )1rx1y*U7M/K֡nKtDSz5ja,DtaBŔ>DIF a;#f2)b,!8XFZD3=ߓGivO@KmݑV=jrڙqV 2땻~>KC%&#d\-9if势]f׃i0)IpӔAV*@hJ7f^dzs$zHAsRKQhI<;;{ Q|أe͠Lu Ԣ,~m,(pj/CӈL@&dD=Y<"/>wݴ~,iLt jW"9bL$$Hلb0JW ) OicRB> WE+!1mߞ+BX/LLDp -dPZR%G>I;5_(D=(s\uxcɮqTu;%.!_ljL2Y+BV,4~dX_qǧMIrٟjq"f/MъRb(^XS[SB>d8ÖR-?k B* @CKƈ -& r[~e]PKDGl%xݖj~btn1!e=f0q<>-AC DЁ" "2!2b$ǑDq0VwInA(Y|ztM@̀!aL$,";Xb"tqnXʎc m u/F`3=x)9ĮQ.gLv\F -MD2 JjQB<86f@%1<\ G+v0+?y"EId;M;vuO.#IHjgUێsnӧl[GMF,#D5*TF*{K @BF - S~f%R #~n>2ݴ:KoiUCm+rTls2P9qB22O 4$ L(ce&5J"jv=V6%EŰ6T2tx=S0\bUm1E:PۆZuש'EY\bUVгp{*i -fYr 3|QzX œt]Nݴ$|=&ŷpL7.?N2ʞMkە-t\W{(0Z<&'5QQ'T܎{??ȸzmA&YdCuViJ:nM%eI(ACOEn9Ć{Pb$WUGI ):q$}鵌ꤢCj[EdGղaPOY>5}l(3Zh 3|(YP>;LQv|'/+ѨH*"I~grd5~݈y˦OsDzё"%PJh]I7oYe G'=iQ&G:Ǵ#OQWn:%$=pp4tGqem)jz[Ҫdi$}[HV}<=$9My$IuGE觹=!&$߾(׭7<e8I5HvXע5:E_6<-%(+vW2̒TΞfyg9OB- ˖E<7M+FIrv,ש*V1nl%\Su# ݁HO$Oq{>2MtzM"LK@"e'5˞5}=5aX9RF -JU 4-o$/XuWC zZD䣌F8QvXq2"O|E8U $iRٟd ~ו^\\W%qs_t׽y׭z_LiuűpJNtLk>֋"Lb=Yv2OUU42G|Eb)HaY 83u eqoHMCjڟGkeɮZ֤5%+oof9`c@*~K.K^=qP*E W-i$"* W2ͭ~~xQ1wQer²(-e7IoÈD,t_QO{BBx񐛪Eb5Ԟ9'M;I1'Ǜ$@6/Xn@xQj)]Gl4˺'N6 -_nkMB4CDN܀bX`yp( Xݗ=\?Mp)C8=BCĐBv9SGݸ5\nMd6͐%lŚѪce6)j4%D47 ܀(kv6 S@TՓ5'N '` -RߢVISȌi^ǕfY7OZ,э9;v}oԪ+Ue}D:#9ޓZVr\ta!r'&usuR$vmvi`zྲ6Y$Q^~ }rt ʹFor񩫗%]U)gnWF$PKȇreT9NpbdC,;bӮY>-uEZfL4f^|̰fiZO=Emrl;;Vд>$iCkIڴ6S۩O󓦟t=7VQT5m:yL1&=Mq(v[P#&kX:s@,f%'B0:; E -u*RS|rl;NpTC5 մ~,UvO>|(6h[f[ezzB$OQZr@vM,G,ۓG}EQͲʼn0IJ|Wj\u - -r]78jYX7>`6 u<4Q?Xkʹ|C/CH9O)SH=&"yoyHz_X^|]&ǑVfI~cb!;ߥiM6 n;ykɠV>\r۷p(PAͼK.h&51tXv2pUuMܴPĬcr8'>ߤvNH7]&s;p)\(},MSH)  鱢8Ɲ@aII5mq)GI#Mq9d_3lvQ%,٪r1RKMmϳӃ^xGQ|=<UNp4ϩn6i۳ou4O*QYv?M;Rn:SEGV܀v{)oܾ fjL8VbW_GֽRtg(ZEz Ȇau4I`iMcӁH5 oYimg4ז%K$OSw$mtKt&V Mnt;IzrGc㶢WN+?khmd6oK7tnrWS,bxڦH5VR+,X6,@6(\7=a+Ghcu^؎E#O{qCѓHfС8=ay$UPtOuu_kO}hY b̋XIOv3.M}Uk| ٭nii^fgaiIaR!W"c>1ո7iޗn\| tDNm8+yD)IH -sT@ >@ TK*jE$ueFjܹu+9jq8VDBPhf`HIu -})Wv.b%{ ,;=#aXT\+(DLvmUaX"v9 QdAbU B+Xq$ZtDZO#ܞMTQziq)n~_څbR`Iq)顔̶} OFS+È#` Nʀ0xQ h  @p V,-x˷nV+:nA `] r%t3h h`ԠD - -6YKm$uEYFFbA(F4A *pA Qj <&%&.!֊H |_mϳg[Ԯze?t@&xB*@a -RxB v&,`#X@ qqN6bᴕMX$WwOvM/.*? H$QD"C'13,dpII -b}ݷvliKh?X@Lb ʩ`%-PͻhD<~/ M'$ I6aI@ -d/A C/%'vڦ^(iv8Y!lH@&A H1 g0 ,h -b(-BPBpؠ h+ZPQz~:z)@&4 -V80x cC@$8 f8`1, IpA RP@6JR+֫$yiΠv}i @,P@ ]B0aMB . h@ .XPp -d@;tiIQy}TMu |@ X@@ Qp %T! -iP@1$ Jh X!A5`/hTn b[} -#bH`1p,d! -X%P -;#X TXBЂ%`;x㇊ӷȦMw2Z  -x/h j@(H TB`0L -UA~05G ` .XPb'*LMS"P dNP1@j`#H8D@D p@hȸByg_,}%!) ,H" Fxp* bȂ @HEbмhQW!}(1 -D0P07 Szt XBh/'&1&%..icUNCiXL  6! -Wp5 `| Ax0Ȁ`phҲj6RQwDJb X`A Y1 Q`p+h -8 @L -NxB`hhF %'*C-d}r^꤃@ -K87 b()P -M' 4p -L dM0@>tAC#2}_ D ; ,d -SP@3 NHBp`6T`KܠQ5BD{\B:%*A B8a _ %4 0 N`"P XЁl@ %AcF ,Z`A҂O$.VH2P$! BB4as0&(a@ !hA UzP@ @e:zrRJD -B `iHC!܀0& b:A *P -$B6N`%%Hd.I7"nA:؀ ]BҰ*P -O,H! -P h h`"a3T`,@9մ ؎!x*&@8"5jJ-nYܶ43i\7wފӉ ieiIYF \ -T@1x a b(aC./-;؈!#" -d$bvp(hcC 0 L!0 @|  4P=FP"KE 7I8r䨗]\)`H"U d &;lV욪imf$-&$%*`-`F CK uP3(!,TL@zϲ3IH+.'΢(2`IAD3B&,;fpbeeDƊ/hdVPT0Q{t}GWQR^""@z`"A8 NXL$>4@D`.XZ<̯Wͯ)Y^2`Ѣ5h ` `L#ࡀ&@ - ( ~xBfEEDD9FB_eaMu0RD&%` ZP̀*TAA -\@t`@HÎ0d̈R"n8bH=ΘmɎE36ΜL+Z,]Hr:pոO*D&+ϐRVmMn'?sI_'@( An=jf7U1./4*r߷Z!הiG A蠑iBkkE:veejՔOs?fcƾxbU%ZGYQQӾ> 9rHBdEZc4 鳫oNaxgV'7KR쪌@-&##r84ųޚN KpX":5Nb.Yg&ڇUOddDLSyKp%_"EE]D:֌DE''β)(3͞H=b( JVx]Nkel.%OU螱Ň9dQVDN+\DTFBq9g_뾐J:YmUq_hd(vNʹ}r²[6}S1CB"9~hwWMP} ѢEEv.IW EKzٞ U/K"HćJQ_O>5ǰ" c5"M7M&eW4$U>U4'e9n6q<7Fs2gXHNxsRQse!;.DM#;[>5 ~qsKQD'I Xjt$7,9gٯ*7Ie㕏?r!8'K,Ire؏v?^Td 1`[.I!nHUK~ sm|jqIQ4Q%>VN`X->V-,QF]T=ǘ@.Xe2F jUeXQ/z%ƪaP&m3)ނecd$[#;h\!c"%R/#$_wD?bZђzy '?qo_Ϟ5T\Q}`(u2 fT9:'헤i#]R.I SD<؟o($ɫ)m9l.&%-@̸X!}^ܲg 0@:5@h2UDO˲_GeU$+% >(xRG -'I4C?:xn[Ԣ-m!bT|`2X`"P:tr~7EgH -EsKbL_y}]U|zXUuQ1 ӢTxvT+o<1&W U Ϸvo#-i`*+!;P`.%IvgP"-&"Sԓ|pOG~ ew\V7I- $􈑀5FF[-WL{4LX0HX1HZ2Ϫ"Ɉz>>7U-0R\6yhUD)V""Unu0|]OtFI7ɱv賌 -dQej_w}a]}Ƴf9 UcP$XF'Vzٱub)v8PDlnrFZ%)4.!BKS -c!RBc" ->3N>_SOzdW,պo>5Gp˺XǬH=bZJ?IǜD:) -U4b, =kla'۞AbRFQƊbNvаJzNB}ܕ$)#>K+ڗuڵ|Xc5,(4 b̴Ru)X#Ԧа@qhRB/[UgQbo3*+j@wߣ`Wz{哓bgQ=jX^J*K4Js/V$a#FUeT⤘DPQ@ - j$#Jɭ z4ѸN?dZL.{HФS㤵dUU -%@"Į, J4c5)}T+b|" BX߳0)/H^(:֑"KlcT&/_>목WJX-i+Y"qxYiYV&PZִ2ώ*">? }ː)_0[+Er?Xbq+".!]ziSDQJnxoNXT8&჈!1 3DX0eAʹJ$b ;b;}EjŪb"U#PJA䦑h4!D`Ç)Twm4A JH'* ~.s9b ?F{È|R>/b0DPqzx`}bPfR0\Tn wc.)4$'!0DZ1QS\(:FP?ZD^T*۶YYO1+D -. HEka~P=^bS~шLl -Z0&EmcX^F">Zʌ%Z̔>0\c:ͳ )⇏-Z)R^8V:=M#4+`R& ,@G je2}N;hqCe$DeQ_QM@}JȃSB2^t)"&$?%d^6f=`H1CSSԦ-,}PҢUQa%F.(h $!#>>,#)qPlC%$CBRJ\eǬ{l M< ĎLPr -^x_7Ѯ Z2pG(œ8S4CIofL`HȠZ:qH*@(/%n!ser:=mԗ 8>xr!TACL/\v^5! bJ1(GĨBulAªA zM1艏uĸx|$=%0^峗5 $o%0o*"G -sψ(ku]*(}deWnk_ub<VU*4 -)Xq)k'vs vIҙbRbf+E яr}dCK1 !CE哻hjȡ"?fz>3 _!ݺSH!]#DUbqVJS~:A<(:b `J1Oz)!l /X%.S{z._Ahyrُe nY%Y{~P#cU)}S\+B K,KdQ0N1MYH=L\>P`1X$O㐛 Q);N`4DREpIBL+VnZ#jp!`HSŪ-[KWON+(=KJr*B DuRaJ!צt˟x-h!T^=J^IPOFIdcVA-*z]%WCerհ N]S:ſW~k{fy$ɛ>UD(L% _]ߎfW}˺ƓhUOn "9Г7IMb8渶IgH~^aڳ/ JBfpB4gnn V*նȚgLe5Cvi-֔/I4ws hCt ]h~j$ӡxB\y|׮VѴ$:Iu[3I AN'B]}SQĪ#V5).v/ޞbkۮf9W=f׍YOڿn jbmi5u<3PHNz>Q9yd.ۧnoy8|-tCdόt@ @F럨IO]|g>5hivt}xKOB -[O<} CˣeӱYسcc}֭##({zJոrA;6HVeR g%)Vf^ p^:J`&N_>1̢Mbf\Za$gRmܿݛdJrJ'm-lRn] E1ó]E/b,BR0MdRK!zt{~z:,ܺuW]7.u;(<2!qyyklwwcӍb8$ -(ql" +xʭ=wo$Q^9D.k:}L~{^&K~-5n趩Wi¸vޠ٣=*>BBpa<eXT"R=i&Pr8LH j<B`jR|Xq2yA2_pWh;b__QdSe9'P%r1`"ԋOLyU맨?0$Ϧo{Y,ʯBcNlJ CʏR;xH;".X h4}HWZZ2hA6$ 0FL4>`|4icqZ~$QTc32Oj%C` (G - -&K`%;dV Ug,dY/׶I5 Fy -&| (Y,8 DB ,0?GiZ竻gDj]!^CSf9Y&:Ɏ!&2DN~@+P3?NjXp"/VI؂ij~Ol';5jLȅ(Rx@ @hLE (!"J"8HQ RE\HyӋW[ߍw+"!XD 0'L` [ X>L/c$,/%*QpO^Ōp$ ` ( - xH*`, @P@JH4`K*gy*WtkXu?BGpx V9`XS4oR&vu(.W[ ^.Y  4!X`<-Uv&|7>4<(ґ0q@ ~ -`-`)A|pA ("At`12 $:b^SdE %ŃxcDaۥh@j`>P0 -L -B ,!(U&z!d%E^j'8aɮDG`*H( K)B Ef #EAnJjKFB=oѴ$BQya(?@!9XB V`Av`~ &02 jl@' -` "JaV|J\NV( -S)1:p,0z`I!(`SJx PBt  pG)nנtTO\G3ow bh"j -( h+ZL`;' f b#Z u,Vr@z@h4 I@$<$0A4Cd|?oɎvrݛ^ AbT.M|QxBP)!Dp  =>S&V<2@+W+ΏIb.CTL/5N8`) v $a 4BЃ(A?*(QB=:&j0AF+*&EIf[nɅ#O F؂PB ` *L@X pJxOɡ$,:_ ՞#CBȀ |Lh/r/c1 A^ :IJuf&̲0.X`4 ~ > K2YY1_$Gl(уL@b:B֠!\ C %` Q`@&!(hbf0{Ѳf>oLyՈ9: $ - Z$$RBz,1 @1;,ԂX֑aLfh`@PA2,A'0 X Et _Q!\Y#GNցl`%>"\Z&wb]}N3ÌPp<U 'պ$6K랏2qpL&%\tࢇ#FbdF`F'*VKܳH>Go߅_lG-ZS/9d%NP(x dD/GXEC O ~$F_䫔R|EzMͣ.jx${J.> AP*0HEMZTb@Hur]"> nmM7|S,Ih:2`Z{DN;O1fݝRAXh|\1~iy42&ukAdr}S&іD&nsζA.n÷Kl+MhS=3)/wU[GV_'z 4BjڐUFUCJPX&ʥ`a_Tm~t>v4UԬrͮxPZȡeF?%qtoI'oL m6$`Eƅ?BSٗ&1<@144SLk;ټFˣi0X"_sXII/b3κsgʟeu#Gk?QKŝ{}=Ժ;on:'~NՃ77vrjSd} ::mmSS|O1vv$d2HdzfN6nK\,C?j_>+r M2Z.%?_6tM$6|xj>Q˪dx~cǟpWYpP@@ƬOalȥr-3dֱ^~!(Pl:Oh"٫,N'OHZW(hbɯn+y\:R!#&uDC7[}q'@^PEz$Gp\DFBDkWXF]T]PMUւ"]b[ז8`Ȝn8*ׁb0O|?Q=Cp|bxE!zjۚ$u5ʹ =(_<0'[vu8:q诫'}p?Z@Mv &wsfI\Wfm#H=XᄂJaPG/SqK/S5uuxɳc!|)Z^$G1tϧϯhvV:QȍS DdӵOWھXz;xTJaxXN4,7m8(71rr]LszuƑt'P f<3l6ߺq_X,Mw#Ť&1їME5n]\㺞SOY$)Hyʞ4߾BU*&KD=kMJ*/NW>eI0QULCn.7,ΖOϝ$=ig.&9FI2-+}|ڧqKCu1veQ"@}ax^G?Q,JR -ŰP.,~mG,|PtVO[Lot.G]=-;Q{LMk[(]9z! qb1B`شFqcE ٫CH}mx^֖o\a2U>]]U}iqW:q%]FSMitє_\iaf/Uw4ò2ߧS8޳+,i)R*lvEugDATR&XEe l܇-䘣i߾*o :޷&GZ =&)Z}{YX'k0Eއn7atB?A號8¸\4"$:@7LFN=jc<:â8~Ʃٖf})(T'xd(#ELk4):.=Ur\WqHm}}qBkDZV<>iUoQ\5î)KWUr[WJ,)7lX=˶ i#EQ`J!<GtD -t=2,8@ ̥۶IB䕂 @ E,D cwsG  (@"Qt!|R2ebݤxĎ@NO+ 4D#eGꅫ"txB&G2K𐡄 4D\1"K=캣FW4$O~Khd{IV@И2*]W1~x%2SXCjaDF|ˣL-'!4,'-R·zR&k˯2Izw:Y =jm'$4 xD=i/VRkeE#4F\"=% *#!%7&u\7ndcU`n9AS q>].Bn۵-V$,IdUu1_G -$Oɯv6yPlLN8VMSe.ŞYU bYSMD$ msQ$q]s)mܚ94êQu/JZ1_2hE[;ą#)dv},:LFTpJmAH0_S* cm^U -&"z մ-Z" &l!j1GDMc+#4\%.pq&H@vLc ,`BĊL,!CL@@ 0 $~Ң*^8TDTX 1-( ϸRu)>+*WW*D\.uG~L_yiH(, -C ,ĕGܘDU%Z4%ϼᐝLC,3ñHA vIEԓmSoYNSӣzʧ #{.1VGEibO/[*i\vއui08x4EGQgn8zI`W%,Z{}[mХ砶 t(M1<5`*N_$t8uxiZ'Kutݴm1/3X9S-<){2Y+-m?"" jvsLsqx.yZyI[QJQ#1);RF^)OOgH,?,SH^O6M-/(/=ĦwG1'EGi[4G*``P.!AF`(0< V@  - WD7F3p2R-G1c -x  &sBfQ‚1)|r4 &!A@< FFLB5Aj!$ HB< /(DbLݶ@Do]+ͥ/ Or jWPA܎6K *`)ف"nX{; j$KIX^Y}nvѲ»'p׍ Tb(Ii_[ di}ؖɈLoׁP4AfX)"BX4( `_%%=۱&'ZrZd5y/wC&p(Tl Jcf 1~puRL=rq,-ۯ*牛}(" Eb^>Uڮ31IdL8BKA#zQ AXpi^}g0CR9Gx!t[ETC 4f1u[֣x vUV̆qKM1 cttɨ MIמ-UH)įUR"fjrs -gb05PZ-`'N)"ic<"LK+IQ_5`N>7… -"#XX#h P;Rh)2q0i(yT5p}N3:5[j QajY,aA6܉#Cam\5?\P,BhZ y\wfIQiP"[|a=slLä.M4Vba;S?dPDko,R #..Z$WKBpD1ځ["xUQd B?յs/\(";IfׅӺ颅FG E4ÅD&$=@)b9U? ("u-9pY-\"dazc%C@D."O G Mk $!D 4\q\ - 0jB+y'+v;8tOvsA;uH☂a]'++R@0;B<>}{5U4̪T tI96Lku==M5<9ۯ%zٗNݴPvIB5J^;`Q^̲cQf)F$8L\3)A {mjbpwiESz>؈U!IdJ2Kn[ A#4I "I{Yб6ӵn|1@)^(hWQ/fؑ# /[}Q # - 4 -:K$=ɲ^+{DMdԲ vMrJ1-D\4NBVT.BT?`YI<,.C>5u\;nlͦ<:$/|-6EI<8ISȔB&}bU#ǵ(̃0^bZ[\=qԔŐD?KO'en1$Ƌ ۟b'Xv2N.\w)2};p󨩈]ImmJs '@ -"a 1VTHD!/VgO=6^'v(5cnXNOs(rȈZ1iơ`X@a U! vGjzG̊}7:dCF+,'ЩyVVWY􈎓V>Me$Z8sM\oe;)T'EG몏$=Zw/M}ePT9h$Q5XDA7yTQӺH[`HkߗIR>QzgfGCSB/ LEGϓ;/E׮]]{ђ3,R];IH -Sf?jޣr\u؎k9&>=qApe1D`+U$OzQB=O˒? Dp#eb<(͏$-q(&?ag%i39 G>uv+>1BݦN|Oa{aOcx #J)}BrbdbED%5 ;Nn'@>Z`'WKUDNp:'N `K0GF*BX!AS2 \`3`fZT&~= DZٝ}Lǰ45foUA/G6qPӓ1*6J>D&dy͌B+L"܆,Q K5ńE WR=jZm祚z_}=Шq]eug/+Q3lE ZA"B>]&_=$qz6=y M   8hƩXxgig^7vϾYw 5\2%9> }bdN 4/=\XYzdzy&z$PT5E4մƁ`\䲤OS߁xժ1/{Vк֡ A@I7cy'bm* VF([ Kz L9\ѢI -CZU캪/D-e J4q4jr$']U յˆsCĠ9BF.>&@'}ۦHL/\`)W=W̮'AnP4Mw~<2q1O31ozΒ1dL+2&2#2-j`!#cEjƌ&3궊^fqy<}|Ӥa18HXbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjbjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj𭳲8`)ylh -')?zu(PEG*o }@2tTmqE$;mzriay :r0*/D#Y}RX]U2xSpgo$7Eφd0(8>/im9JnH!9詜 q,#EaNA-1>bIqo1_ECcxoV q #s[_,=ceQ -S'ÖDlIȐ9[Ts>XL`z.ۊfaN!/ -ǛnkAbEUY:GO Ǐ>vuo -CTsTv&r~(RW=K,d @ϏjٖӁ3M"E]-=5( #$f ۢx߳(Tyo|FO'>kCj:Ūw/z6; W>\ SůKoC9áAO%vljKvqF.> 䇇_UcNX,ĖW|In/IU~[{Gd#jiMNi=lLGlci]7,=tع0ݴxhqyȱ6&4{Ǘ>#)s\ٔ\-rZN=o3L"~ZOnz0"ؒYCԣ894*[2r/|9AC%4ZUS&ܴG s;FJrY!+EOydُ'_{_#vUoee;9;lu]}۽dR/IxfA1O)nI GRS~LlZM鋎OnZ~)GbS&yU(}Z%-Į. (ŰkMYjE?fj[Q(EKkD~Y,rW]Yub.N墰='/r^7-Vǃg OB5b^}8'zd7isiՓ!tIEܦv~Ci`.~wmqu'J͞ c;-_=M'Kꮓ 4F0zuuO]{ pˊbuA?˪hEs=N=M.]{mUIdowRK;q">ֱ?0R"T^4Ԟ zБ\qׅD.v>˻$G꺋.z2brQOޡv:4ҼX!&EK-T"Qᐚc.u!ȓmbXDK X hauMr\8>Ge1#X1PGI2I{b%]w]H]jG d=칈%if.=)TŦ^+ng^(cNOl9$|޲$NGO#9#{ROd{L1FsCLL*D!Į-]jP2f*w]7Z6dM9^vO:uL5 2,7J^{N::u 2qjo /eJ *]z~V% vA_Vzr'\ =zO(>Nrלasg Oh]z\E/Ş7-QӡN8=){e!RB!MR,i)%q1T  )df?(Yӟm477r#h ?eh_nc0|s'] -acӚZfv:6Pdx&D CR1Uz.GPPV;܀ܟbWZOϜgqÑɰH-9e|߷jYe֠G:Uzp'a6>823)2X v]$]Gb,nulT@/A^nUq eHfJ!?~"Vuɱ,Girٗ-xw6Yf.USr\ƴ(j z3!~OSmgRE1 M"آ_wGMCIRMSV?\N;.6,M-k2 :}R(%KRK)eu܌c{یT".Ps햽\v-QY:O)ZB1K"w͋a.24%K*cfe=oDTnCNi ȇx@r6]ZWw[z"57صb5䧚[ dXt?˚$[wczPSgj=mE(`||Q(eq -R&K2Mjyu5}Q00TzXêiؓ5{Xef z' R?=qq.8gUr=8} RpAJ&%rW\jNji2!Wrle0fRSSz$ryo.(i,ofq?ijZk]znݒIʝEPԪ0[f/z$\B] oANg5X-3ծ-5꟢:)2ުe[ۦbT}=:RQv>s|,Qˢ؄]x\n~){.ŭ$KlZbS$W?06Ð2DnA8yIzN6dUƊ$bǾ9ҡ׫BIի``N"ߵ\m dMOU-9n=Õ Wժ*EGyV4l!yM#:rPZ\&Cޤ{*aAQWrW+S\27A[zZwrDwߚ$=n뻰=-kަY㎢}㸃ߧ$]2Cl!_'5crYoГ ZFcՊWrUE9n$GC$]I/G|I$zwP;mCXMˈMC -Ui4*jqmr:@A3q !#cD~ -^o#7 fv:0,O( -kۖuӬvMOŦ/Ͳ}4I5`.c(V}3>pױrn։;v2r)! D -$娚c߿Iу5BZ3bYr>= =tAu^6A>*V?ybu 0.m_=nT䶵"ZOO)q'U0>stream -;{OcU-z~V1{fIEIZ`ut}Zgӕ@3 m俦ybH"Y㸛$ N=lA슚c]WS(:y>eMp%9ZQD-P#F@!#]?% w8m3_4,UuN'C,qqEP|~(@fEѪRTM;ɞz?(,?oA9ߪi*שX$eP|6Q|~mO> -W{[JൈUCrqLmKn:媥qzzTTӱdS{i4ajZ/'DUcmǭrYstMT7[ KDDQscBXLڴn#YǓb+~[3IO$P\;OǞ4AVt_r]e"<02=>izGS=ǐ@-\*Vǡ睝 r0$c Ye)z]~?L;Om׮MmIjYdMn{'EۮcW,gNOe=fx6R`/C;B*ހZ>?K<=KrUfxBdEf3{ Ϸ=o{Ψڬ"z a:nc$#)PjY%0eiwmԔ7utOu:1gSD+PK$cKE6&B-")L`6T>;VʮG/K^˯#s,0ŊӈKmD.r=Io6nsp4l_gzו4gOS|qN l2 ؇U߯#,  -U1\5sm^I9J,]l7ieMAĢ&b0rZu˩6Uu?ZDXrcdBlNP-# u Irp3.RHĞ[dUY˓! IlGYm(GCg[mL%̦ab~Ve?C,T nïD64QMbO^8'G[ o7I_{v7E%RZtNjzۓ~y^J"}J4E.Km䲩MU> GŚ2V(/&,&OoanYBMRD_~WJvUp]z$,&2{4ϳ$!Ѳ5)2GHa5LQ) e7G_g #mj-a$BnÌ@!xncO!xu-ٽ6/ D-(#;I; OW!f p z)7U!J=;-X};%IϞR -nA˖UʪiiÅe Ƥׅ(=BKWޏcA O/VW-m ~Nso,\'RȄEp 5$fJnE,J!]jId0 -ˣt$'l~Ov]2 -hwsEM~eR!+"AbvIv]N/&*~ys$i/SԦ9v-;TBv`1Ro\6zb'I S]H7dPHgdN11}Dh 2Ӎ -j5?jVOH!O?,wEvt\'m 2LfZ[Kv<I¬F>dPvĬL->ݷ_WorS]o߫ :CWOWn)ڣ -ӂz*a=r?-CBbX7Mץm1ZfX5)|aa?IӯӳgˎWpjSV7:RF-ZG -,;` cdbZ?nETaV$)V#n9| fThPW/;t/ﯞ1 -ja*vCGOzf7Eo\)H$3dN$JO{~28 Ѳm,`^`xs z)² -S{M Ke<&=Or{%$"h]Kyųq -NC&|FخF :)zV(1HКʘ@5HT1`!&i-sH{N/B\^RɯZ7 -Qr,%Z'Y,%*]I&A`LaqQNz=aH>o)mհKKxv؎ya{RFD6,E:b-S -"}1ʟ˨D3L\0D\|&9.Tˎ_w|zW UD铟",z`BEZ3^+'%Q.z1;6*Jvr4KGx*H~ PSE$Jle"yZF:QH5:f\;&Pd*d%z"v\]eP,{$k) XƋO2 -XPzSȇ-9RLVG\kZ0{MQ'PZru(Ņ4 -Ƌ#lx!`lrWӫ)!?%QSFȉ9fzP0p_*`@Aذg$hL,Ѓ $VЈR7C0 !TDVF"'3XNf0U2ii'MR$WC7IOKj}1(5c5e 㓼VO֦+)1ǻMcJ2BN5DJKhq1zm~;c2bXmJ"8}'LFedr!R>&]ULV0Sa-O@> JdĥbER--_9]7U=x"*"ZFxrZF-\ӒF%z;4( j""}^@Ь|P{DIp96baeD -U Ģ*'PD].Ez2~=(YqD&^aB3hF!L A 8F;L\BXib(@;1n$ZHtԳ|t-$/F^61˿π+ɃaH '꿢*V. D"p-\U_S/<ˬo˶FzWfhLpU.GO?a2@BazUL-#(0!7`P\{ePBéf[فyyaB" !XahzXFzFJ  z "E=ɒ -e( bFHypDٕK}V˦wQҚqT7MXb"Cz].PF~a>jq[154RL <cVF.$4!Ԫm BH޲dVſQzhnuB*g VV)I{Z'cҊ6V*fˈ~nyJyV^5 -o`H<;ĬxDfDY~drх zא񒲃\HHG^V,(AJ Cpb-X]_1,]e:wO3HDwA;'͗>p9&OCN@ K-tE!MIm" -[ޅu ӆk$IZ{),@߾_)~~2 -W-j)1F?&l?\wqr&Wz=:7avOqȄ& ->һ 9 sm|&;L09D[M~:0dgŸ;lBNC\̈́M -}ӹ C|&&UL-`rGh'03M:4ga\nB΂&w>̄AM>~azv -&-8't_Lfp':0M6!g{B?un&?y ];M|rwr8& >Lxwar`'Wy;!=t6a6τ?yw؄&>› Y  q}< T=&hF hnRj|JBDtGMcʷh 簡i)>Jk #CH4$39).VK =ӳ)s` ӿz#Ңܮ5?!!yܽl-CB$XyL6nm, K<4(~a/T_\Fˆ -+.+E'I ЍYY,_'TplOI6I}0/Xg(s'%5v-/!-ҤQr1uYOԳZu42šUt |4kT?xr4LaޢViY*i088kQ<%&f;)Kw+r>J_6i< -8Eju}[-Qeu}k βP F1P=7V%AK*QYf/qaGA}<5 }|_dㅿFʄYv"pK 4I϶p1CT41%_^M\z0T;M_rHwG3x!yLypm~2E?Mi}> NC4rZrZ 9+ͲB֋Fzs߱=/4HȳgB5,zB N_/mۨg=sxX@b+y09{8]RK -UeX˟)Ha;%UyTHY  P~Esw wn+XfWw{ZuE1~ cYpX`>0F,Fw ||#1vTs2NcG.8 q>.`^UY֘8XKW+ [Iݨfҫ[ ]!A8_6L~o0=LF0}UǤ}#[Q0/Tm9|CSnN!'%=Hqhѡ,LH - {UDgBh?$$A!0us [,mm=,Ո 'imL HD9VY(-䧅m.GMkrrUP<|KC F'Zi&ZAŬmܶ0 `*_-HYlt{XC=c# h6(8D))B(W2{OG]pAձ;iLbj-{hUps'xr"mxށOhě{7Opp&qU%&Q -Y=+jcaH+orbDI "xy m݊V%X}ܜNdSl^ʽL{fhbAFɅo48ԝv+@,cr#eE#+-)>,OY`LP`4D`Uد͖D|F^Ss@7#{Mp3.G/JCbq`l Ω$>if(*ؠ$ *"cw02g  Vl݄%'^aGSDDuMb߳~Ul k:I/gBHV6T+vx;vHhƄ*;ЖIĨl[8NHIVD{5deɖRROIPT~^UG~ZUB٘\9׆u79X0/mCI .TIDFk?"e3;`Q؊Qp#tRXfF²yq{-&-nUq'ZߋYv~>C B+(8kM8_8TFb&e2HBP7zaйį'B=o9 -=LLMU_b29mOh@W+Ihm naxn L6#'_r|k9IacbWe !awEo!2hQ&.p|wOjr $8tEknw: +.|&k"Cn,QzQEgjSCB2|dP$/'iZo`zϸ->Vop,f]`hCur}^A3r.Ͽ -]"BŸĂy7 ԭRjU!PaqW1`7;RBs55RYڅ*ʹc~VBjH^I)$>Ya@}iv"kܛx!#jQ>?\,Kԛr+9wQ1OIQ5$ ;a /^dGCfIO&;G -'y46ozG,O!" b$Q]U?0]%NGK(1UgN d_ q7A?OIc&}5rv7?CNȺEJyO -L.rWD3eB5:bIq  HhcU*zy T eqfeQ.[9*m0ulX3i`iJzDzӂyW`~G'=L$+ԲP~*AP4mxz_̢)B[GTQhGkJ8K^qx O6D8E$9/dT"Kґp5xq -5H]G)3Ȉa@ j Ði K^1A9Кp3f}UQӤu1KrR:)C^? @U0R`6I|AF)L2LtJԜ,c Gڌ鏸U)E-B !-~+;B-Pz̯<.2@@ocx4O{8bE2+fb]yi>n<Ϭi*T2+b4w+j;idzݧ" AJ uOAا&@>%Z>=3'^O# $܅> ;a*T .wVRԀEI ^@W͜ȍؙm=)p6B? Ƥ#[(|s-5lr+Ũ{,O@0da+`g!o0ٜŮJ"qaQZE͂۔E%h(Q5P3Q' x1U w'жg<.^7^bhAoAi,.PG#,&Nh*+IsТ -$";z~. f8v@Uj  7/8hDg MLk<(==ސ'0^KR(zLq9wZt rfkUƟȆMp\>{,'$[qJGPu#8ۙU7GJCaӉqI JE-Bqfrj@3ރ$Fپ%$s!c8"I2KMu2/]_~4zlwo"w(pD,bC,p!{c~ӔoU3IPx)dPf~XK cfX69'I|uLRvuT J `1t1]Ŵ04IJda`E&*-ΔҨC825 _$E|DPp@rHjMx'/aR_r`ޕUkZ̅5kq$stAK -`hS |e1!j]3 \e<\f<-{q`G'8zXNivvrЉ>sI"Uim*Y1QH :\ 0dzf͎a]džN[p m_8Vډ<>¡Iil*ϸ![Ctj#0bχ 3 3]NB]1C0ҁaXYT(X]8v;X"^/?RͷЖc$Vު D7YW^»uusU_*}ڂ)\^@xaS&rAq`xS^`gƇ99F G?XS&>j{ hKI -qN;^qkwꧩa<(Ԁ:+ЬYXˆu_4l)Kl`0pb99}Pݺcn3 Ȩ|(rơ~5d2X;>yFa88p9##=K7ӹ1 J=җC' y\^!yŅ \،"8 S>M'k&kiv8#R5}#5#, k|qÑ8@ Q~R1?. Մ)âYo5bD9xtsʑ`"+%VC{%E5.T3Qb:*Ց?bDլz\1>!C $Kvy^H;DT' -2HZAOYq88#!rNIqe9k 7͈eӈA pAzLrMFnr2Glt9*SYݑ1`O/JY gH]E9}]F9 -,XF- -|ٖ(jK+_*kyD9wȌbmGa@uYhmF -mHhFGp봓<@-TV΢v;KJ#88[pꮩgWg~6g *@x`B$T -@lB T!7(YzPLLxP&@pTȠ -(Uy0,H(\@AAP DI  01>emtيT|I;%Κў';4٩Vtޙ_~,@ @!`Aa.x`D 9;aM1Mί F!w1Ioh)7@a $, R#,0 % ` "I1BNKll.2,8=+}4[~n=L sI UUrTG6Ba>nv'Dэ#q(l憑.kVhRϬʊYcx1ۖuFk;՜˛ pu,]R"CM@UsB0!̳'=;Ιշ/bF(Y(l H)5+jyEQ[<ԒbgH`۪Y)IղҊu-),i5H}TB̗>Z_sUKp%-{M%՛ˋӖ6)=Ӵ+a'[mJFaR֡y])&˩) 2Rt;Á 6miM4h5udK\Ȏv:h;WF,|+!̺r״kFL9{h݇mutG%|= vm{-xifV7VӻeL]˴[Vj[ Qn__S6.Mb   ,H "P$!$  @fSaےN<ٹF*lc6cWwtuN`g6qVΔ&v5jn&^xo$izaM2/1ɜ؎'~W_t$sȮxwξ)cG|_Jz1ԓ}$bK'iVjzwϬg%ŮU^EolMe^6 f{lsbdS8שo3UYuQbτ-FU[}{pMp -zZm%ORuO y~h?lϊ33ih?w?>)OTU)-22KyiOOzy˻"e;5?CSPiihfiiffffhfffhffffifiififvwmv}ݵZwǜEڞ"5 &"o-AͶ׬3[tiMnA`bʂB3H靤GF B9}ƈ]PBo+K‘\cq$+C5)y(Gkh>"ˬHcwQ(dԋaO:(raɩ.Bn0:ê1.X7{%1ZnQ+ -aqNDԨB'o[$gs G> S$JAYZĴ,V59wIUTIv_eDMc| u8B5<ju:zziMNI9BJѼ&ѐ( ]."e|XJ9VxS0.;^@ɡ)KmJv0 jf΢|5ТJOi~Vӱ1\m)yC({[% ڶ3i0;$:q-\? 'N,Ξp7-5@o۷SLԈ S꼦J]?njǥ!:MRvSd_Z#,[%B={q͟"Ŭ.]0UlYc;X].%Tw!^BU?#䭚1T,fJfk(|߈t`Ϝ=ncѪZ}7?'8p JypH|}0(9yLaX' Zl*Zh4 l o.jH5 IMN =ŝXɜsiwSX2C7tAT$mZTBHLG RDUuܹ^.{uS'>`]a{YwjTW  \S%鈩11Shy-qj$r@K7!l9vK!Crl@ I{(iAM@ʋ?)GOhXј+Dn$%pG pKDJYtP\m(KATN- FD Da[^({jrכ-ڙٱٰ#٥غ#>Y;Kh c84\LhM\ƨU\#ٱ֜ #WBeMxJHcb GH`o#Wq.bւ3rU!4KnäQcu~W6RAོӆyZ`@ F-Z-6yd̳T:u@Ws!<|4W!.,0,8MCG-W>y|u"ѱAĺ!T05DW~ɞFJ/*Q؛:UN]5ں~ -ᵣ&JQ^@2A3j;0PE쭰Eb 2$B -3p#8MCp(+& wU6\Q_HDhUtyKU:6sr -C<"΁wRڋU)\r ;ԍVpȣ^i~7^I#x%=RL{LT̯SJn4[lPc0ԩR+|/%ң^Y.} }ŵ\!Q 1 HE4J`zq©<0v. sҵ -=S,X*L28oq>|*hf^(a]` )73Eyt[q}Óf$ -%T])hp˚)/\Nȅ]D6cW _3Tevq3_QtZf5g lRΡ׈lp {YÕA$8=h6c -5M_i&;q7yNY:རgD0HUg# :3088553IPl(g wy`*(Qu}gjI$k]U{ 9{xqKPpc>J8/aCkUazTey`<@~[y]\̋T;{4Ʊ" ;k_:17cN,#nq$8@0ۤ g"0=Ļz7Pyi# b H}ZcIܽa@"NGtq q:C~$w Z:~էa ɲ~~h)? mɗHe_iyߦzE5Ũ H(o!BsڞNq T$hh-~;=3r P8uׂ3DI!uڦ/#~룒`- %""֚;_coTm6ԔGDN4mo%!ݽ@JaZAJeK1Xb~i_oZfC "]Ts{Roٺ0*U&zL]Wsw8ek J2eU\7_6Ve6 DjivѮ"+Vׄt%d`Jz}`>d ,%D9kJJ%'p] w8XQt]uk,rBxYN1JsO ?xЩwzLYQÛT[_1pkuJUy!kkY}T[hAd{!$}*+"̿z-%nĉ*.U۪{v"8K$=h]c<2tQ;|FsϖwVL'sz[+ H -fkHaL]ev5~FQk&p k@:(J-" Gj!(eH:[TlYO> m'iLzJ Ha6([sJTIhtyҬq0>U.)0ӂFuP|C,2eY;ł> g2΢݈{޸ca 4 AjI#i!>D@R',8fsk"gL - Rf$Z "8xD갂`(k#?xE13 Ӆ>QP 9&(.IqsyMb <]&~MrP‘d0\z1A2>A,Wgb#5v,׏~V 4 ^ޓ$~" -lT L}D sjwlME-2ާObۡ9?F_Ͼ_a`d,߅&dXρo W\CtR栮DUF:WeM0ir$ \W혩g}, -2$QYKhnQ,@؃I_Z -aiٶ\7qjs%튳d͘{GiQ l" -yW- uӥK ĠϰdKY+(]J&ݹ1 O0&l#bIˈDS `^Au&Tz {Fc]08I,ّ2/ =}$»eB| -Z_H瘵pd* z5U(~0qCro=ɯcM %E {"߾iǯfuv z-HX*6L&RIDZ: UۄD~_#PkWv楲)Iw)pFVc@XYl}k' V_:PCyiMd!?ij6ӠqZ(,Dp7 -2z@M٬\՚/[@op:q HՖkcR(+.r6i&}'StDA'blc~^h6M N/g@Wi L),Sǻ)9%#4̅m[r^_qit!:Y -QTj3{6i}ۖ 1#^/4P^ T -oU0pQuvSeoFt8O@U{v[h{4Kh<3K1)/|(PllpY׿)C7^;^[-{. -*nKJ/R-堤5 0GrR?}V9$%޳YD J c:K77JȂboU -|8"Q}v1d Im)[-0\8F!䣇(1g4n&4ǃtF ""Hъz#"0nr 13ГW:6ЮO8ȭ!A7oC˓27FiK۷F @ -BK'ի6^3do]W#Pw?@8 :ܐ(t 3∱q' p^-%j1fD0̒R0 -]˗TĕB)L8cYP1YQ,k\gn(;"{'92Py?ݾmO䦻\oSO!{5*WQ@eA6~E8%@h4okǗ_?D˜V@L'10&񨤏X@U d9aXuMo} -E '_d܊+b;0zg)| .w)XMkMvqy,1'Һ7 kzl*Yk#P*DhGs O?cejs-3^3mui0तvs<3`yxKcQX dIJqD cĪk"ޔ*!a̱h0XД)Id> f zݱ#iǽwēC,kȪz}-N- $-pT"X \^%iSo>%KV0ji)0Uۧ#4O6c{>!ʥp3B|Eb!&4  ^ϰjϓH_+8ս4yFw^cC@lu_9F눙/U0r-̓ -< -j@>}<(#N:Mfc@6q~,Or>ǚ[&PS=׈6N:_o`& #MT;\d _WƶWv7I)=R; ݮJk,l"8dHGu_ -"QEiHVp) -F^y?VjڙD ”~VQ|+P˪~|1E61Q{l sQ=&,܅)8o ^jNݶW2Mܳ%fFt)VjƩ԰F%?9=0x'E4-5F6-,؂uE8(N{~X`A步O)Tn KWj]Y:4VOr@.n -!,`!*жCf묣d.eC_I*ݺ=K==$sF,UM6Tn@i -IKy&k4{8> L&37?{PܴȢ1R`S,R;0hivѫ|#B@]]')90ksv?_|I"AYRv -6o J&汹0}GMtE`06&QJӒ=&hw$Scsmٺ=v:dс}_Luf FOe<.)߻ONo|e`K@4NF w)XgZ98s{`+4'n:{hAil]iGR[i0L<$|^;\Qw Ƹ:bw q"f-tn<` @1K+b $ \lA8n4T9V"2~ir%K -K`7HufAҨ4%f6p Q8Xx"~E .Z(P125*݋*a&+L`c@:r홙.%ג)}&NH]KǛ @W4O1 G1g-XBl uddU WRS-*&/K N : A ;DqψHRd -!.Md,ԁLfcdթ$M-&ĥc8NFr}2b$v։7G4/$5#R'c* -Z(IJR?=ӓÛ' Թ4.In` -y)+]Hyy>z2`[]WD>\hNR(|DjRMuFPcq>'em#q38kΐc^5Zd76E!-;?,rm\@wY"+*=ar-1}1/ -'iG \'~RT'yM797OG9ZJ.pxy-LldrCpg B#oy+0#$u7HVL~ȍq9TL-fiFM;PY8P`jw/칖Oo̧_5bij(3VaƷ-L-sVd{1ݺ .Uz1"z;tS4غ5_U=x٭NFQQrc~nW ꨸?@}jz2ȐEʭǃkJ>r+Q&WL?%de.s? du[d,F_Wjk|}gZ -lu2 -q.P`zKL\mhզ -d WD6o5$=ů/ikI f1"%f1pQ_hY˗P[u&3?oyZ!VgBNEE:V M[א[ѕ/Т ^3^3I rMufb5yC=ɽ,j=u,&8]bpە! KKV(Eݓ%fJ(Jr0):sK;k%f_M3`~#g;ցv2=^21h ɨhіd*я?"#YIĀ1D2ZTXvC5c2L zD#uyG[0欉N>-VZ_t{.u`2dE|$3W%䨘Vf X$ɋRxYXO˞Ӥ&$W+a2kămh"I`Q8ɂ%aE+|l?Fd3ɠJ dY׷on[FaQcU1nJwn Y ɱE2^b/?VN N=3y`WbY(\XMա%wf$CAf'6(NXyIVorG:$/݋R%9J8OUSp*{|,!?ph (eGa ,FtF+5:VTNC^x4ѷVgz2 ެ1xɢq?"+_ 3TҔ,"u"?*(R"uLSַ ˎC1qz5^ d~ʓ(T<mY ζȫASu z+`?*miU"Du8GQpm{iaދP݉;HhCR  - -lcÕ&Lcd:Q;FsC`@447,ʭ$PEY.(ۋ.#8TT VlۧK7e5$JoVֲrJS'2;&{L [ /c]Ͷ" iȜ=fؓ d1ֵx6j,_ė6P%_Jauyg/Q%yAE ;pJSe\lifQQL~S!G}v- -DZ>yKIY9*^&l -;ݙF[ŭ|算lHVTk -# -{ǧs._Rz*T/ϨWv#,hV(iW -2 AO(A+(*Av1:/U')p8+G]LƔI}XD:^qbEPCnIw&C.I\mXf$}Z45dABw1ā-K$\ k8j&E͔'RndFDiSn[]:NÊ@5qJa/Zʦ& Q/'4Hu> [ʛwO5$~Pp,xI1d AmѳwQRZw%9@'󀻥Moihl\~(X+r3+"Nŋ]_'8'jg[`e!k mO1_\wq ]pL 5Rqe $ Dĕ?3ƔByJ]vH[;Z=#v!OܥƇ/B]j"EXpY?󜲡:6jrxK8ՙdu BO)o:l|p_LI7 zIfn[Q!FtX, Xy؄mmQYdEH# ,xW-f\+|1O;GWfaRZ#6|@]{ -yř4٢%ҥ>3!#6? 1= ;\w-7Qh Ac 쬦&H_3[ 0[}-qoCny0J/=%s t h|tsjM_Hƴf 9yg%}jEGfAh#!tD>^,&.{eBSE"ּ*官޵ߓc-&ΦKԗ$'M?ӯd;*Y0S4:%_BE8[5!S(_Ĉ|=&`2ln5v>myմ + -kl,%-\l* cA7pS 7@bC{"'b1K^XnRzO\Rhq#͖h?)XF uLN;{boTʓi9\֧cD,-g rԒ~[[v1fwpz9q1/gg~1l[H&P+:v{S^ c38w.9 Bd.*pOָײ=^OJ&%skӐKby?:hw[۬KG7 sx"`0zHz)ڴ?񅞝9`,B؅#z;ZBa.=$L12)Z(rTVq}cENdg׶ D8@G4dE,yߧHɔ"3G/ĝYBܴN viwnl@8d?&BRN#a!C4_MF{/Z&Ϊo!C3r=X_[ -2ot-__ N3$cs܉ڇ  J<$jBcUI@a -\k؁<Ho8]dzBTjJZ!>,*,IbPVX;x?%e/#0sosy;ɨOp1ٸ=OڏЭof?YT(n|?_m0_Tm7e@_\Q4d k†W4u(57ѵD2RƳL#W-a:tWeٹ<4.`=?E'> ?i%0%^-o pjlS&ϟd-γJ8)3eYl2&@]MV7w#H;C[];aM]qz^- 3"vl;ޭ>Н6 v3<BqDaFoX{vXWkI>V,"5PQ}y쉪='@! ׍63D:> 9@2uC 6Eے wlHb:. YHjcIvDJzs/\JcHшŒj:~cʼnF2=y+N P"/f]vXH);UMGߢyෛTƆ`TJKgyE4þ= . Ib/vL؛O _;2NLK͆,̯yT#%+>>4y]rl-$lRoy TB<ξ+4-k;Jcؽ&p{`}UvK[fxVt,b .q76REA:^)y1TUH -ۧF n/4lso^rg5Cn`yWGq{?]GGm/-TŅF6FO6% -Vk4+)1f|覌wH5ISe}R)lVW) -O~-) cgZiFGaHAI -xL9Mɞ8Aۑ> ?/qL`c໷)8ME%QFQ)mMQ=%ocsiݦ8VO\ ʵDht ݱW7˹xcL픎,R&6U$GJ`6[cM:Ԕ0_gh 4(yo`과IR-PhXP2q/VO\L/%w-.L/R A|@Ƃ:I1qVZþX6A|btc'ĝ:Q"OQ;A!ܩ,&D/ƿV v{/8UR5d6J#[bC!)6mGn{;U\:sKY9Mk6{pf@s}")Rk򳤛sϾK~I@(4 ktP @2_ ;.+\hOg[9ՈwײĘmy,qiLcFg¥sRPpcE% pM,Yc)LGas!Ώ0\QSY2c^h/PC_b -C |I䴯l;#'q(ɒKΙsG8RCܰkm^ي5JuPDi QB-x26O҇7۴JHT_ctiASPՔIYĦB"~$ s9җO12Ab.ؤ]XyH8\@p:(|Z9XO<;H R'qgO:dT{L X"0 Lq R:)x(B!`Uth āylRÙ- HxVwܪD@GGa;(tmfK?{ӒYl?MFC',9йȿtPX&YD3ZAJSm FW9jŬ݇BAH)e;u{%򓤆Nťjc4<;=/qASPשEiŤ^y,Q+/f b&;Q6LCwqt7D~TVz:AɃ>;PB*a, |1)뽉!VDR8/:DBÌE=U**pgǸ(m.]N䥎6t9%];dB9!tʃgbIvٜYjT;%rbGߤtT[V fLUReFQ+N@s '7FiޗP'ުV-7t08Oy @ +4Sܥ2n|Zn&'4ĵVreyX 5Yt`u58#P&pfOI 5ђr%wkoL|Y2$Ȅ, -.bN7`-9̼c=i _K($e> x*-p1Ґ`x'g#<5YOv+ -;C,M2~vdڽR)Ć[?A|PLXʄɰ0JZuF,؈R>yrg#4|AT<א \t{֜vv'kTkp/m>X#ݭھ -F0eyq!LRJkrҶ4|f/dAˌx"iг7إ8@-}kAhm-yC}{1"d~J3%,n5VlJbnd1҅ q e7h: 1`0N[cexehţnP -&|; -5iggQW(;Zj7[17N\Df $:$ ʐF{P'>0)ҋ͘[˩6?mM -jԆ/1_&R̉Kı Ł֤ dx.Hȩ?>cnaMW˶na,#{ ;M -C#eNKc+F# 6g7JE1 B$cd?aݑ=CM8J&`+eX -iaqhm~ҙJ6D~ەl9%suV z˜!iէ-|0z  v+R שRA۟@@K`iL^ꅏM+Lfg -YZ{cX/Mi^b˫m1ooiY4Q?S]5gy:[ehf"9 4yrhL-cPyF4Y$l?w&t tԫK^a&gHəHU,s;;UNMPzSBSl]aaX#hP粎,ӬM>XXmu>;WAPCgX@bIHwW0'2Z 5$r+㷎4YJI&(ye4,_A7EXc!hV݄stIsuM*v 1b}L?c—?#SI#yR퍫$"hTmM74E@6k˴x%[bAN9`xE2@e278tȰi1,Xr>+LUhl@m 0A +8= q4žmx-*r U&XoƋ-đ!\+"~؂y b79XyHVnMXc@۟oVrxrUsIXAґTCKˣK$K8ir4="pZX8\+#+lAbq}X=9t¦+C2(4&_Gc7l2N=#΂ދ4埗)+sGMxJҠJ\V?V?21G?Nam$&2|0 tf -5GH%Hnh%T4"A-]+1๐<&@u{6mZidnr(!Nr8-cj7޳0+'ñ|LXau5z oʱ-΄md*80I:DOY ˆq^*УeYO -)*Pz #v K|'Jq&j:eH1X;Y2@ 1;硹sG&|6Š ̏|M \m6;L!4;1* -xc -S!mFqC@Tqfi:Ο/] -1bǤ_rH BRt 0 /_z /7]SeJFنC'&Ng+jfa){%nyD|" ;ihmQ+./Dop,3Ҹ$ -А [#m$D2 =Bʐl=#/cxXlVAۤxy7j!Z g#9cl2-)_d62ULL&XxFC^-hd:J8L'Wlúc0/;ϐba'\4ڕ@O -(7覷dRhFVbz(5(v);]UڜQs!J6,F#'C pIԃxR4pSö*)UH3UGtNLأPpuHD"dBlKmDXvő`}$.2A[*uH.Aי㒡c|'xC KdUXHA ->Jb$bK:[b A!L). ,yu].*d 瑴Z^}z]I0nsF'qrKCjn4*͕1YNVYY*^gH,ٿ/ m}T)nHX(銧)뜙fʴ)^2sO; dώ[V7b T'WoŸwV>0G V39qdU|7M21/+*&!M/֭*lпz0 8eIn@#lRw6^BX=AV;QKvJvB!dX?"_$SB=s3hjfPyVy<w>QDHdCpI -x:5K3F0f@ψC0E<t5aSM2h!w2M} -ŭ1`!7[hihVd e?>r/)%9*#.wS|*GCDIpDn"Il'.jI~Dz. ! ^vkP-j\U"ˬ?0&mx - .PAwN}.ioyj(lV؊)S&ulC=xl@.Vm"a5Q3TYŠ?y⻁AX"қY]x nD4UC0X \ƈCvaXzD!4^WS hK -Bq6šhS{eA -}6  [ rYRfOc ̶JW$auю&A֪[(tja$&-%(lAQI0$\8Eܓ&S[4aj+E2{~7I a!ˁ})=(4d;$8XF5o0MŔ i_,.p~q1Zu @hP؝(1Zq?AʢU_˨^jxb&*Z0za{5Jh!Ho@ K@N0LI9`"a#W@1Z4.IX%#+XuĕhDOq tI)$ -x_@P|-aՔ +.`hԣ8E5RvNO:98!80FZ~z%6 PX`WY? -!31֣g<()ZVC+gXRTm-[t&"XP 3 o"E嘮m4yF6Ԙ7nZa,"bt^zH]e3jq]MAu%1x2 -PJDhcV'^^@6akRD,:],Q J7jH]s8=NI1 %$JGTMʫ`x=5or,3‡UC5 - ߑnX Bp_=?b1m)OYrZD+&sF'a9\Ȃ0MqKWc_ws݋lB ~XXI!}{wkͨʯ)1M/Ⱥ+ PZn\'SKOysfnh3N3cJ6nz@Hu*cioa@\$סfG,>w-}:YxYN$*J LƥOfQ&L٘6V)\L1p j֡DFF({Drwd2ApðDRᏭf4/ -N%C9KGH]'Lz0=~?~a:O$Daêm h&gd|)Qr6|xUKN>R??X>)oQ׋Np/BeW*  xD"凐XX$yqC6?(X=l3nς2L$m+ZP?Zi3 ,3.MJIX;Z+A1H$38< ex8E`^_8}'jǑ}u`l&AC#8o7fx'tNllH-,ҝo 6X;+ao^Z!peԋCS| m !n*~w/g[^VgiMc9lw WY؂CZ,d w$ -Dd!ޭbf Dol^NpX05TaH6ypA6wXB@ HΡUцgZXGB@麯#u0G/lm 3:F -Z+9C;(BeSMyWG6J'4c5bǍ]&hN xicHۋEO@I? Hr14::pxܯ+1H( TaK;:f9tUg}TIn -҈n6:@V6T'n#hSC^~6zx$X=> ot,ŜMLJh\/o]֤3QAr5'mL\2*8}/,1Z}P]X<`@K/IaH4-I7M -JQb+P$)KXcۀK Wa> -\Vd8!"H-'T6{Xn%z);fڀkHZlKYFp(HT'%xUpҵ"(eӟ"UQ*W -֊;xC8ǼN])Ӵ3leAxLOI" R+x'K9|_pVmoX2*opԮ< c o ǃj&R[QW2U@U+Cp' wptZUxD#\D)!`,8Zt03IJjјH8)pWb}¶#Y :3lJpӬp[d ⢢эE뎮b<¤^gZ?DS\4΄k5u*mT*\'?m7 >~[W(0ܢFNXyptV(0O(qKHX-J5cL#fOFn:TS*v[wr@ ~(a yR'J 6В#*hLk{<$Z0N=cq:(72N.db0,[6}H0֍ob&34H[>y;Hd(qn[᱆,DʐW>pk8I/=4m DZR#6` WN, - `Di\o+4A K`ib~Y4Q1![!n2v l:ً(k?l-Īgk຿; u -K~IO.tycY#Dp}NP0g8@TXh)BGۆ60̆Y1YҲ(?'lxLeЋZĸ60dϏ`XvʌgEW{ -V馼_*m6 -"O$) ' 1=!Ph$,i^qV󮣱JaF;>R0vFvgu,^d}"Vs@=`8ؕs`39͢YJKʪiW#FI?&9&͓$Ͼɍ)Y<͒4fsԛ$i&Qd,;Qy(Qq7ɻw?7'Osݹ߾s']Qs'K^MͲ<7I&7Ko%I3Ѿ'˲qNwK?yzeߞ$inO<}rt2OǻCǹ{y8M{|fd?7IDQr%/9ѲwN})nwԟ$7Gnۗ&wis|o_ޗ~td_:6dߤ;Zd}y(ō~_}$J4{߽OvsIǦ'KNy$9Iǩݱ~߼ܨ߻h߾=YrOޡw{5?˒?In$4w'Eǩҟh/9ɽ?O='4I_4I'8u$wi=Q{hߤs}EIܓ4Q^)O7wl:TN$Y|D˾9''jYn~%in4)n"yG;I}Y󣤸Cқ޻nDc}ɍ9ٹSܿ$ir'I?I<"zݕ$LOǩۨcmqoɒ57k'(vG@[xծ,X&/O/9mWZwWE_[ܝ%*wb}Vƺo\y\yOv^&wkevFw0sh]Ȼ'y;W;f|i^aԎϩy)vN=?wғ';OrI^znzQų7MS;5MirMw&?EӗwNNߑfG^q!pYW⯎[㪌h-FF(*¥DԈr@FJhӒ'YI5fBs:v3&S1uRSMՏ _,drFR}PaX@$V"qQT+/"j0!ȸvFcFNSlǵKi<5fWشFk屍@+H`3,7u9@ ˜W2HhhHb $eď3D|]Rܠ$d7 $RORı7(8ED0a)4,PhZ[N$ -MIbE#TzB2`3A:@6MRN0[%0BV|P%;B+(KCׅX ƅ%x FZDU"mv(u/nJ*tDρփHT1PVb82,52T -,`N hbT(`}8E H = hjT meAdx)\ dR H4 -D VK@-֏@( -0ʹ)dHZ80B -(Y,ȵXh¼B?O5g"lg~ؖ|iH]~0_p ? T>qcx2FhYf# !)ºK~)o!D%xr&%X)Py0all]0b LA-$k3aU ip '8h%͠CAÙ @Aj hvB_R= f0 !j]N,PɃv~a^s X^%@DGt,)ཨ.2B*fRA -^0s -0/چ{lAPC4 H^<'jVzټUĞy]y5'22/Q}޺~Qy<$1+x} - _E F+/|LPT! lHlpDnt,qT$Xf pI%&@1t;T&sUE؜428`F%ap͆.,W%2eٹT,El: '$[$2%Y@qID #ERx@Ir#X K.LkQ(]2S  qRk/PIˤϼA$8bԂࢨJmG1Jy E1ͭZpy$Ni} 7 K[w4EYMRĉ* R) -(8`'t, mlv0.xR8JZj@jR$c%a\Q9[جHWvNdVuchf&*Vb7nGXE@Sk|t^ s|?90̌U}"6(ѩ"09QE5#IEV(7`bI:,XM>1ڭ)NḑobgxPBj`I8 [4ްN"$1E50vk]~ fQTc -Q.&M&S8VpYk~f-SxL!1[d*L4HrU!PcPI>$GJQxIQj3ĶO|Zp%BFǤ5L#$jH4[Vll`ۆ,,5ϚL!S$,[m2Ŷ;#>Dog gcI#}7 ? xlcj݆a#| `8# %?U?ne P|w(ixcU]Ejl[d+\: ?B\Apd#8 f73I%tZfKYiX|00PpcIq&@wZNqTBt,O~ |%x|p3 X.~.GƏX˶,4¡eb;&iH)vsPa!nDS8%(4LPf.y;{ZQ6giǑ ihG/ -Th) -(DA *N菓lH#%)0]Φ0(?ƕpUlԉ4nG* F#T<L -P1iK\*9nWX,͘珫W,vn$JUfP\5 HDQFu"?sVlM'rC>o/FqH D(!0ށ<jo9B3j^!PL~܆4Y4/Bj G`?o3mu$"ǝ9LLk>nr*4\Y NO *V[eHA‹G:Ng܈=1d0x tWб$O$Oq˪e5OC+|LH uNKɷW&67,YmȤFOq-R`:`i7`y!#xA>lF [(佨Pv'0fxT!VR8VQ |ziL˲0uىj!24<_?8aBYbƊNO;6a=<7}={&"=BӐhE ] f/ysk8]"]A]+E!E2^"$t_"``}\4DfJ̭Y^JNa0[Gtvkע{|)n4J_jLZoP/+432!`o9.2yB82)ҝg;#Fό̋iUud߽CbT^6Jo Plޯl@(a%P>Tsȅ]x@ s!D- 6WZhV[ yh3Ӌer¢F"k0UL%KW4HZp+*OʮTJԔrRkCd>B1(5x <4@e=T'H59Vxzmh2 ;4Q\|@iEJG$#mنO1D d4 #W:#j&S 1 sir3HB$%} xj$C&29 e.ķrHI ӹ5!X?5v(>L[<‘lyC䓖 -|d}%e%,ONy8{&A7uZ{~Z SNojF2!qd#;RF;lKjQRxM'E#v` =4X{U_Q'lY6bв>,{wq︁s~l4> G+?MMM U"T LÝiUW`+hUtEБ6#;iCzx A"ኵ/'TS6Cl,? v5XjOC vϧ -+>"'LjK}`= ϲ0*.iT,.ԐwL4'Ā<]!i NA˲AOC?>? kOܡxq&.L‹'>? P|9秡(,|C.HYG+aU9Y[T0$5q-XAVJD`idԁUi5him9 =\qǐ?n@^,[1U0igƎ;f7j(p7YWm,V~XKLBpвl$F@p|4JK# DX:E2H4 BIJDž||( jb,<6c%~ ayŴ{A5h;f$yXq8#RF/8ӁtnDž -<Vֶ6iϺ5n\ٓOʖ,^FH$ -O30Kx4 V .lbdL)oi iA.8 ~zd- ojȈS<P([~ȃr}Ut3T(׍y*[T6!&d)$6v\P\AO0<8%8% ?ɲ࣍MwAˀD y$>J&{h I\5ߛŌhl)~u>,606啒mq̲%6PSUi3=)^[8h;(x--’ rƏU -3n4 -ޢ(8²{~zkKPM7T%hC3.g:rj(媀Ǽl5UmXfyD:T -DZn y֚YӐv,[E˲Ue*mw}N>Yd>G>#g>,o063151ROCX6ZuIY&EƲXyiq^+H48NF !0xApSLPh9:vЁ8\0,KEr=/ʺH#*{*t"eD }e Ty O~o]eTbU$ Dp9AAI3>+ぱ^!<B+R+& 32>5^ -hUa9#g,"+"UOƶzQǙL hRRKr媀vt=IQINRb[>y$H6Cl#l@p4:&ŤudPSdo9~1zxgȅA8z̮EaHJa83SB?0S5 /imGxԢDrEfYdk%\8ep/'N)+JqpƓI Y Zoq^Q(ᜠೖUjM87(E"P߿^C&.`rE@N<2 /Zt8Ej9AIaвlX%ecR! -I&%(Q9m"r#$DL>Όb廟&rl<湑x~ͨ%G4Z &IW4v)2Idt73kMg3\ɖVD2hj f'YMQ)#TEF{1i]D\=O$2Lв<,[y4d|#7 `j xacj?j]&'#\ - $ @-U}e/3XBЌ IŒ\ KjH$F<@40$I0,1( R -qFWn8UӷM;ǡOqȎxTz!e;7PadOˎc%TOkbkdcA= cd~.\1ƗȠ8CMa4zrKJu`d)cAǙ.w~*78! `+$z*Py2+|np^]h3/[F+;)IPZ ݒ+LG"YUW2d5דdv!Ix.:n`ѮR -Wf.e ++:vWKR_Mǫ:vëz]^ӱuU:^SʂWbĴ,#=]odwzTBûzo+I}8@}ZH!HpBǕEJ> *ޢ4Xd*i!it8N:U  lV18A9dmXR33ljeD,Uʀ m H[2T9'.!| 0E]3ى旻JNNsrRK"h_3U:D 6Ba݊Ք՜!һ!Zt$擹Od4U$/j> ?GSõ2DN[UGM' -P0N,@F 0 -vͰ -*A‹_q]@ڈqZ"GGoaӔTp-*TK 's\ק -i¹jס2=pkeHQШO~z^Px;N9J^RSu< zɩX g,ߢvok  wR )5fai=bVI$d.Nja\BbXn8+}4AK z{ &ļۖ~޴:x^~@ cnƐJtGrd9gn ̘H2;EBKU8/ an`H| *Ve%lb$ݞmm'q3]F%0>ej7Fz)u.|y'r&R=fぴi\e>G~J`[qnW) ՘!ujt0+ -q~dxD{]Y3G?j剱 O!S 5MP3i ʊoXxQ y\9(ɧ?P[p&^kbrV7e86rfF .;LNsw`|?91dK7P("`V%-eRՌK2[x,0L*!vVko)k{$;(tO*!QATr!/X5 _x!?b_B:{"c2y:׆"qTATS\ʰրcBhFǠc 81tJC)׋P`ȡϝR8V|Vfz8:^1ϮsPn‹T$"TS"lS!5pUCsjNw_< 6'qiƓ* ;VOM++`A -#p⑎u>wJky]dWHaOqMX1'Tӭ2=Cp?]Ɇ_#,)2}o>uկ -MW45$y9ս[< jHHf/tӯE$5z]&I`Xط^1cXܐxY& '\ -nBMy Pd0,.昕f9uɮk-~8!* -}"TԋVǘ^}MApq%og9JU8ym/9$M"A`熌]I=KWUcJQywB6(,F]Ƨ-Z8n[RNCod#;dJMGCS F%I:I^ 0v+^"O -͘A'Bz:g ^ƓiEDDG)KOA?\CH ,00_2zIG/+Q^1KuZ,=:ړwϤ-8ZC+7k||^˴ݍwSLIjek?ˢm[_֠@n Y;ʇeŏS%V7K`vھ:{Ar\*+,9A2bs >jh̽͗!щ99#cU<{> bata۝]N]{ȿ \@4Co\-5nW]# "+6cTubƢj " zs!kRvt׿1MyؾˁyiF\c.TflLǃii!,imRo+8˾5/ɔ!)U`J)o_|YX=M?m_ CS`(6 {r9Vn⌵T-MK!(F0XK*_JF(wпS¿Vt:<_u竅0= 'rE§ 2PWV;][`8#NڜTLx+Pרهm:H3tH~E@Ɯ uJM?DW'Z1!j$E|Q_+$ b5_(xKvk6Z,~Z G% -eRpb4WT'X/lV8>j*it`m]#ެߝaku-*J0去*[ONAh֟TP@\R}&/!e2hrh)"oY^- (_c})J6U>8|#ctH_>M!{-sew 0e@o ?|tqzI#8Pl2#1ZjQF(zXdҦrSHBթ%Mv4A=d:Bگb4܅7a^N@2!4*w&R^Kh>O`\ݕ:7 !w׋82鄘/X!L֍6^Q"=]5d9؄璏NL&)NbЂFsx;) HLj ?B\JȱF u}bܘ1PJL*^A&=bV;St+[aV|6vue1ae8jWp=G Bt ӌKĀQPI++7Cw ѣx󱌡[Xͯf|$zxi F6vdpPE _zBI$Uf|ƮiU8-\BS7/;pz -#^\۶ 4UUgWzEdYLHࣴ=y^4V88f a!,kJ LǿX+K'{x뢲ȖΓiBm'Ô݁=,zL>x#oRBa贋T|wS ja?bA)1Qxۤ#'2׵&%XQ Q)q{0|(G )H4ْ1"AEhn+r0s+,j،8 ;ߊeE:TSf*c˟@ru -L slf/KQDN+d`&[`O (&/#z:"~bg5/%B/:僮wwdZ&2_w{Om_c}w7})9"i&)DFr?ٻ;>0+} C. ˀ^¿,iDnMwek. XS }Ep64U5Jtn=3ҙe}\ -j8V!/>m KjLIʚ@joM߄)ʧ.26![F-v-hMĤ2wL"&)p;1^A2Yշy.^8uȗ&݆V!mɆGw0 -SCjn)'zt;~tR '!70{ؗ_/^oiߚ1|OgvL85k0px)-h(TA*/f iuDJNک~3GaJ{$RjՔ"LYUeJ>$Jwn7̱,!Hrf$V*EM_%RF9ƥq -(*[ϛ0M@W;ҢlCnj#C+rU ) tm/v|忹Z @ %=NYCߘA3$n!sĽ,Lm(2ezvt[pAw)ҽDkm72CQzΤL7*צR,L7 Tb3e73GML73nq n1g_3`{h-/Lk7 WxyM7po$W3ԗrYtQDv{:r3W(= Pç2(/ͬ|r^GcfNq x])͍٩ԯ2.n_ktc.8Er4\~>/CWXh0}sS< %mWZWr'ڬ}4s3!}ccds*%k哏H8,ӷNDx$͗D`o'mBOC% 'UDñ) -!B)`gS%e3h?+`CY-*#A'3i|QĩNvi"nJ -,g?ktD^:tq*zRY:8wָ5 ZE"m!M)}1z~!1ǩ#SeW2ݗ1/,cK~r~ G< ;n(>0,IeK3500?nk@>yWXH@ ?L;HH).i~TzPkpAj6wd'7I ;CjF;с"1*72`JozfHswTAU1;[nrnhLwXs /G` l\1>$u-z{o -E, -7@Q7,G jR v# -D#fr<ɭr(d.8M$0׭ttJ纅`qYEqd&_d^\.vu6/hqL5QI}Ǥe[ BIr)ϲҎ=H1d1!qhRt?|Gp- -8͒P=q&ǜrq33Zj4W`QPe#̨^c j2&XJPB>T')*-yD0SZ3CE y\-o.N,w%P%|o /ZZpaO1TD<sE{G G,bD2c͏PԋN?)-E DFb$h2gNt-1v|4`0=𥢆?Sh#:&QYYVA⦅,ìedl;Iuo^&-y.E$+wۯDž\n}U.d/j4nIϻY;`Q !Uf>-vNnBc5F2#&se@Y{ -bO O"}?P32<(]0]Ì؞ʾsawjK!ħ pCH=^5i᭲ɠ>2&3feaƍ SƳ;Z!8fTy֏G8bgW:WGg(Cx; ->k -սSd endstream endobj 22 0 obj <>stream -}2&ĐMuW f*'%|ˮT^ڗe%y09Y^Y|ֹ=@aeXZ -Yjz0eL2 YP^x=N;jE Hn?ςڄi6E8,U՜gXclG4?9ջPFBS&7j t#`{5=tSR]f<#|a0VP.n/S\Uy}.`XBpߖyыMnʭ#Lxc}tH^v2VV٥-L!cɕ.W#:2.+Zu=hd !LQc!]SL㻂YM~86s_J,Fz'<".bޤddA3kϡ^v57,9 Y,+eyc@2JLNN (4_D? >vZcj`?jM-`@p% >l -]>)n8QɎtqahlx `h7r,\% Dde14iN)y#V[11k::>0!峩WOXLN"զ4z&ubo^Xhaۜ AJ̋рDz0R -p_4AK:_94fQL+K4s4&TK1=8V oWI 5$ѝ-1e9u.Iʁ3ʻ#ml)Mjc{͝)D$~p`&aJ`j悠āgг.On'{XRUB -W|< +&a= Dư2dd*gL{Y`=}3'N]C6ϥ*1Ev!)1;D[ɮM܌oL|RmR)>KA#Q Gڏ4ߢ ˙Ɗ%KAZ&:Wب#Wxw[f$;ݼBbrqR|wp 3ϑ~gYXӤ/סߪ˺VDmDUy~CU5LYMt?X% /ခ6im:ESy@9fرRɒJ8(4Wp4%-\tL_d¢j Ѕ՜;;#Io '6E6K o~|0 h@L3>@ٰ hYTÐOpqu滌Ht i87*IR1rGcUmKվդ˝iov''UIAnxq'H0nALܽ5)?,D0_9 8!sj^Ώadf!73]epKqQe֠=cB~ &E|Պᮺ1+[8mys $ c$+{'ZڥˈSM1-9dڧ?4VvHM,K\]/1pWfu9BCMU#u k;JSx/[%028U ,k:LlHF,_^z$I&|^K%N1Q9k°ߺ4xkBd>-\ⴊ@=lZkpwXxPX?*_8:D]E+ dtlqFO^<&c0eErPHB>C4JNrm>֐y֙,IϬu|Yè^rC;[R9$F6WЕWQHt:OCAM,¥U *@k0_iS=J8 ?mmLpZYxOdAjL#,3| %md)Oǜ^RAuo͝犾J,E$6& k3Tdقښ1w?o!w4J7c\dM^Lv<p g 3 _s iR~,_MP0tX:\|(jx>ᘔ,BGxÝ?7Zڔpg`v~Q<,'ɦhpNyٝPENZ$L &x+:L_n߃(F'??$\׀Zؓа$WB|f@IG y@Qx/ 4$Ub=Tqߴbё?Em>LMQR$Ln+BhWKX0])?3F$z<}  ' &"LK揙, d DGiI(M-20C10%=<R.o_ej:bBDSx0V$1^pY }]8g~ăzgIL*Wf0e7e %Ro67N(r5d2qG.k $I X2jCq/Bl RhWNϵkė4n66-'6(^N<(+Di%;&N8rm:&u@O -Eo=.X]U.MOKۜ+8hf.+ٍ])-kFiCVЅX YҦP'xWKX/łͤJ{nQa7tr|vV:)S2`X' -7g}L}8^*4faz(`. ^6eO".(~TH=s20IeM'$Ki6V$SXEͽZĂ$VB*d׏lHR #ʲhꭀiJ488iЕ#H2;no k\[dƝ/_bFxJ8zPtBzt.gD:a&/PQgށ<mŚ i,a'twM -UdO;qy̢G"-lfx5,O4G7mkHcH"a 4Ɲ`Z"6KvX!~J UϏφ^ʌwSi)zֶQ `׾,D`^1l#sT^\&\ci0U uyw,g&[DƍYiV zpug~%2Zb5sGEU?yyw_@ߘ*Di%&^Ү3r83d!4֙{MˆvE$YH.鉃6Ab'ke*8xMEk`ki$T"-.Db}9$f@kş>LumsBmPqz$|NψBd]D25c|uLN.Lr Kޑ6Ҝ\砗5RSjD - 9 -$*1>nu@uFv.YU| ->kta+-ww -c%A#omPD^r㬎LP~lJ`=F5pg4 hڌcF G'h巊%Ѱ.yBR.k@1D2@}U0ߙUs`MDF)&hGYܠu7̲SBs Ͻ߲Ђ٨`9a73J.pK781طE(ӶsҝQfoIn:"hAvAoG+fT8$ΰ M 2X&HYjwH3-{`CsZsLk RLS8pcH!it-K Iy+E&[Yȡ0?4YZ2#9ɮB.ԠvL1:QeZ5~8W:Aa$~$TAgOQWiIkDu($ﲳG]hw ɴ(x :A|lN.G-ɟcЛ$1 xP -zIw+=W5ר -55zYz8fBgJ3/.]hOkZVm3 [ \M()A'\pwU衚.7 )]. - O~UCG vteZ[X!$⽠'69ӕ|eR@JGW` EBI{Jk?zO+7^T#88BC\fږEBAI:J۪CGq'.#(A`BxM0]J3ϦxBg.N6[(~h&#<ف00CJ~oʹ2iO7c<QqI͕LDU 'fԑq d7:v4:6׼_o5A=) p\c*ߙ ~Z9rp+y LL|pn_xG?!1; u3sl>9t - o" w5}.8nmv(4֓스ǯQSR ZM$L6~h[Q@.Z֞@/fQ2}]#oX,aSM0T0r/H+D>A5/W?l{kA*Bp3kD`=C8'a$C`H@7|"}l7;d=Y;|MC{3 v@eFM3j0d9CSQTOR!'S7wsnX9)6=)) PxARJÈ^xƇ4td\[iNX/wN w)})Jy/R]mP􀥔CB|'}3 H05}E~q ^E:ǷL~7<f,1q6}{5p[kQt%6mHL˰k|Ӊa=W% MZ+oFithS]E4t⭐;*4#`W|Yjp!@s'{"i&H;EvyCri nvI6 OɏVMM Wv f4;ϙv%O\zT'V6Xa[k2&šfײ>fA 5γLj\OzѦy(?"99@Aevz vu3{\>!6ͼEPO :R}P(Eu5-yQ"7ЇO5m -^5'C" hE) Q!f̈!upCl2 -뮲B;#IoX#2=ǖCi|ۇ0Ao@.P0csZJ5PtRZF'}DNԞ8ɳ1;4WEgvH'՜M~hӕùkN-q,[4h(Og7sX?S_BBLjwXxF \@2Is*}0kzgXO}HJ:q +ᤀ\FaL,J=(Xƞy㖌̒m~:E[ʋeg@f2{e]R4M6cb^p,ȘLaZG*~94Ic8WW˞6I, t=)v ҁ1=!]mB(<ؚ% -X"x@\u K87ר!tqRs:"\ -^viF|4R<*J jVhܝA"Jƾ]e㳈 0`p -Bki$ܪlFi*]E,"+| ӟ iIR=諞iXrV+T*8TST)$n+MA!6IM҄$KD`bE$T&.쇹5 &ى Z3Sp)7{%Y:.7)fd -E Ġm2֝QaC>ќgN;Dtr;XA;5lAӯ>HWy',R4u0v֪YÙf`5j|"J2kUf-H^"\sG9Um:5dpnݢB*TZ0t#8\aNUJRШdhh`))vϞߦ (+i#қn180B܎lS%l \jK1;|2 -TF#/nǏ07'#awF"l[yץ^-sjT9*~[WMsNWFq2mT֠>y@Ť"BJec/a!Qianh -We hZ>/+ ?|RLV:G -GAh4($(S' :D/.sat IA鴀HǦL?kqf=t|eOO|equ&OGOyӋi?nBR>/ھ_d6,3kLNbORtTm;O}'wTTXQNٍDs[}Sn1]hjWfeUΜ7<]ڽȻӵ|>& 4 :u:Kc^J"6B*h%kqV,҃ A@c -j A"d  T͇zJ@5Nn)&*+_`eǗ(z5Si-' -xTMTn7pJ46 %#9 y5! -*YAdH(Ew)7*ĺP&f 72o\Rgj.S"+?gV[װg*$w>hNa*:1 m :'W*oN_9ciSU\6wANU@",fLT4 j&mcpaRCQhC5cfn{ ; tP] p:֨dt9ջ+.}:hI"kU9!Ŗz FԠ_ 0@` !;ȋ -6s|(J1#ken`Ao;A7mJ5%@#{RůaR2!m]+ #j aviʼnwF%i!_Є]۸[q¡0`KxMPcWI -4"qfH))J.K-p:gOLG -&yl4W+QȤ\$Z`Z3nM@z^A٢cCáTL%S9( ҌA1Jz.rA%՚p=TlOo(䶉L)u(@Z4h4F+/pGq # J:-gj&2,c@.W\;'Z [ux,Jr bt"9-crgR"TJY2 #.f,'4ꗏpǙ7ꯊ!]UՍT')OCQI-IA׳ R6)?AfO ^AC%?JixI+)^Xďz>`O3P|)s}vF"V9F+*`FC#b1ʥfyha,>z ȬNХfx!b w@O?eh eha-POG͛E~.?&_iIbk:}*win0u2H[pϥS,1J(m1ԉhs?|,@iA,=f9cEJc iAJUmm\$Û+?r#1[uעicq5S?u >TdyGXh⌓]C~щV_xϜG==T Dtf8Q~: G5C"1C^4qj^y3)pJy/~P)D<NJ`# p}O']ˊ.SSBJZê)v9r%XwT_WHuŌ#٬Pqb0g.'\BX՝mA +MbrژsU?cʲ)Lzk-B'Ջ*=g."ԩy6DYMH$An#/cQG9<1ڪ+~.~ i"W]ܨG^4zUE,$:SCR_^JP&GzxJJ4?oƸrA/*Qn0` ivyYTЇA㹤0B;[t m@sNŕeЃN( N#bd' -Ѷ f!jE5.co[UI Aj*9/mzaz^FX7?"W $$s[LtYƷ~ãH%Q/-GQ) otmptiYgx8řc*\(7yǑ#*ɒ 遠o}U𵓰^cVgn5Em@:vO6bFutN?.q4=΍nR,As;}]?j= SӰƽh85q;A7+,E+㬙p=nw4{\E0 endstream endobj 25 0 obj [24 0 R] endobj 39 0 obj <> endobj xref -0 40 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000048263 00000 n -0000000000 00000 f -0000048314 00000 n -0000000000 00000 f -0000054486 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000054559 00000 n -0000054799 00000 n -0000055995 00000 n -0000121583 00000 n -0000187171 00000 n -0000252759 00000 n -0000318347 00000 n -0000000000 00000 f -0000054186 00000 n -0000331922 00000 n -0000048728 00000 n -0000051145 00000 n -0000054373 00000 n -0000051002 00000 n -0000049817 00000 n -0000050441 00000 n -0000050489 00000 n -0000051180 00000 n -0000051538 00000 n -0000051293 00000 n -0000051418 00000 n -0000054257 00000 n -0000054288 00000 n -0000331947 00000 n -trailer <<6ABB7DBB61E3407AB7779DA5689E787D>]>> startxref 332156 %%EOF \ No newline at end of file diff --git a/misc/branding/rounded_square_outline.png b/misc/branding/rounded_square_outline.png deleted file mode 100644 index 9e2e0f08..00000000 Binary files a/misc/branding/rounded_square_outline.png and /dev/null differ diff --git a/misc/legal/django-annoying/LICENSE.md b/misc/legal/django-annoying/LICENSE.md new file mode 100644 index 00000000..95697362 --- /dev/null +++ b/misc/legal/django-annoying/LICENSE.md @@ -0,0 +1,9 @@ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/conreq/core/pwa/LICENSE.md b/misc/legal/django-pwa/LICENSE.md similarity index 100% rename from conreq/core/pwa/LICENSE.md rename to misc/legal/django-pwa/LICENSE.md diff --git a/misc/legal/django-url-or-relative-url-field/LICENSE.md b/misc/legal/django-url-or-relative-url-field/LICENSE.md new file mode 100644 index 00000000..ee9e2ad6 --- /dev/null +++ b/misc/legal/django-url-or-relative-url-field/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Timur Kamanin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/misc/legal/fontawesome_attribution.js b/misc/legal/fontawesome/fontawesome_attribution.js similarity index 98% rename from misc/legal/fontawesome_attribution.js rename to misc/legal/fontawesome/fontawesome_attribution.js index 2af8326a..63aabf2f 100644 --- a/misc/legal/fontawesome_attribution.js +++ b/misc/legal/fontawesome/fontawesome_attribution.js @@ -1,3 +1,3 @@ console.log(`Font Awesome Free 5.15.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) -`) \ No newline at end of file +`) diff --git a/misc/legal/fontawesome_license.txt b/misc/legal/fontawesome/fontawesome_license.txt similarity index 100% rename from misc/legal/fontawesome_license.txt rename to misc/legal/fontawesome/fontawesome_license.txt diff --git a/misc/legal/octoprint/LICENSE.md b/misc/legal/octoprint/LICENSE.md new file mode 100644 index 00000000..7abea911 --- /dev/null +++ b/misc/legal/octoprint/LICENSE.md @@ -0,0 +1,208 @@ +GNU AFFERO GENERAL PUBLIC LICENSE +Version 3, 19 November 2007 + +Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble +The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. + +A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. + +The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. + +An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS 0. Definitions. +"This License" refers to version 3 of the GNU Affero General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based on the Program. + +To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. + The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. + +A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. + All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. + You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. + You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. + You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. + "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. + You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. + You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. + Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. + A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. + If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Remote Network Interaction; Use with the GNU General Public License. + Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. + +14. Revised Versions of this License. + The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. + If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . diff --git a/misc/screenshots/desktop_discover.png b/misc/screenshots/desktop_discover.png deleted file mode 100644 index d0e02d77..00000000 Binary files a/misc/screenshots/desktop_discover.png and /dev/null differ diff --git a/misc/screenshots/desktop_modal_episode_selection.png b/misc/screenshots/desktop_modal_episode_selection.png deleted file mode 100644 index efcd1b98..00000000 Binary files a/misc/screenshots/desktop_modal_episode_selection.png and /dev/null differ diff --git a/misc/screenshots/desktop_modal_filter.png b/misc/screenshots/desktop_modal_filter.png deleted file mode 100644 index d3c911d6..00000000 Binary files a/misc/screenshots/desktop_modal_filter.png and /dev/null differ diff --git a/misc/screenshots/desktop_modal_preview.png b/misc/screenshots/desktop_modal_preview.png deleted file mode 100644 index 43f37076..00000000 Binary files a/misc/screenshots/desktop_modal_preview.png and /dev/null differ diff --git a/misc/screenshots/desktop_more_info.png b/misc/screenshots/desktop_more_info.png deleted file mode 100644 index 4ec5abe3..00000000 Binary files a/misc/screenshots/desktop_more_info.png and /dev/null differ diff --git a/misc/screenshots/desktop_registration.png b/misc/screenshots/desktop_registration.png deleted file mode 100644 index 7b499536..00000000 Binary files a/misc/screenshots/desktop_registration.png and /dev/null differ diff --git a/misc/screenshots/desktop_sign_in.png b/misc/screenshots/desktop_sign_in.png deleted file mode 100644 index 55db145f..00000000 Binary files a/misc/screenshots/desktop_sign_in.png and /dev/null differ diff --git a/misc/screenshots/mobile_discover.png b/misc/screenshots/mobile_discover.png deleted file mode 100644 index fb66cb8a..00000000 Binary files a/misc/screenshots/mobile_discover.png and /dev/null differ diff --git a/misc/screenshots/mobile_modal_episode_selection.png b/misc/screenshots/mobile_modal_episode_selection.png deleted file mode 100644 index cb1aabcf..00000000 Binary files a/misc/screenshots/mobile_modal_episode_selection.png and /dev/null differ diff --git a/misc/screenshots/mobile_modal_filter.png b/misc/screenshots/mobile_modal_filter.png deleted file mode 100644 index 6d283148..00000000 Binary files a/misc/screenshots/mobile_modal_filter.png and /dev/null differ diff --git a/misc/screenshots/mobile_more_info.png b/misc/screenshots/mobile_more_info.png deleted file mode 100644 index 1f9aa3e7..00000000 Binary files a/misc/screenshots/mobile_more_info.png and /dev/null differ diff --git a/misc/screenshots/mobile_registration.png b/misc/screenshots/mobile_registration.png deleted file mode 100644 index 485dbf03..00000000 Binary files a/misc/screenshots/mobile_registration.png and /dev/null differ diff --git a/misc/screenshots/mobile_sidebar.png b/misc/screenshots/mobile_sidebar.png deleted file mode 100644 index 10dc4344..00000000 Binary files a/misc/screenshots/mobile_sidebar.png and /dev/null differ diff --git a/misc/screenshots/mobile_sign_in.png b/misc/screenshots/mobile_sign_in.png deleted file mode 100644 index 49cb9b6d..00000000 Binary files a/misc/screenshots/mobile_sign_in.png and /dev/null differ diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..6cf881e7 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,126 @@ +--- +nav: + - Home: index.md + - Install: + - Unraid: install/unraid.md + - Windows: install/windows.md + - Linux: install/linux.md + - MacOS: install/macos.md + - FreeBSD: install/freebsd.md + - User's Guide: + - Getting Started: users/getting_started.md + - Installing Apps: users/install_apps.md + - Reverse Proxy: users/reverse_proxy.md + - Optimizations: users/optimizations.md + - Configuring Conreq: + - Server Settings Interface: users/configure/server_settings.md + - Settings Config File: users/configure/env_vars.md + - Custom CSS/JS: users/configure/static_files.md + - Developer's Guide: + - Setup a Conreq Enviroment: + - 1. Install Requirements: developers/setup/requirements.md + - 2. Run Conreq from Source: developers/setup/run.md + - Command Line Interface: developers/interface/cli.md + - Python Interface: + - Front-End: + - Components: developers/interface/python/components.md + - Views: developers/interface/python/views.md + - Database & Forms: + - Forms: developers/interface/python/forms.md + - Fields: developers/interface/python/fields.md + - Models: developers/interface/python/models.md + - Validators: developers/interface/python/validators.md + - Widgets: developers/interface/python/widgets.md + - Startup Registration: + - Backup: developers/interface/python/register/backup.md + - Components: developers/interface/python/register/components.md + - Homepage: developers/interface/python/register/homepage.md + - Http: developers/interface/python/register/http.md + - Notifications: developers/interface/python/register/notifications.md + - Startup: developers/interface/python/register/startup.md + - Tabs: developers/interface/python/register/tabs.md + - Templates: developers/interface/python/register/templates.md + - Views: developers/interface/python/register/views.md + - Websockets: developers/interface/python/register/websockets.md + - Services: + - Email: developers/interface/python/services/email.md + - Background Tasks: developers/interface/python/processing/tasks.md + - Creating Your First App: + - Getting Started: developers/apps/getting_started.md + - App File Structure: developers/apps/file_structure.md + - Creating "Hello World": developers/apps/hello_world.md + - Contributing: + - Conreq Source Code Explained: developers/contribute/code_tldr.md + - Updating Conreq Source Code: developers/contribute/source.md + - Updating Conreq Docs: developers/contribute/docs.md + - Listing an App: developers/contribute/apps.md + - Deployment Tips: developers/deploy_tips.md + - Changelog: changelog/index.md + +theme: + name: material + palette: + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/white-balance-sunny + name: Switch to light mode + primary: teal + accent: teal + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/weather-night + name: Switch to dark mode + primary: teal + accent: teal + features: + - navigation.instant + - navigation.tracking + - navigation.tabs + - navigation.top + icon: + repo: fontawesome/brands/github + +markdown_extensions: + - toc: + permalink: true + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.tabbed: + alternate_style: true + - pymdownx.highlight + - pymdownx.superfences + - pymdownx.details + - pymdownx.inlinehilite + - admonition + - attr_list + +plugins: + - search + - include-markdown + - git-revision-date-localized: + fallback_to_build_date: true + +extra: + generator: false + +extra_css: + - stylesheets/extra.css + +watch: + - docs + - mkdocs.yml + - README.md + - CHANGELOG.md + +site_name: Conreq Documentation +site_author: Archmonger +site_description: Conreq Web Platform +copyright: Copyright © 2022 Conreq Team +repo_url: https://github.com/Archmonger/Conreq/ +site_url: https://archmonger.github.io/Conreq/ +repo_name: Archmonger/Conreq +edit_uri: edit/docs +docs_dir: docs/src diff --git a/py.typed b/py.typed new file mode 100644 index 00000000..7632ecf7 --- /dev/null +++ b/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..175e26f0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.black] +target-version = ['py310'] +extend-exclude = 'migrations' + +[tool.isort] +profile = 'black' +skip = 'migrations' + +[tool.mypy] +exclude = [ + 'conreq/templates/.*', + 'migrations/.*', +] +ignore_missing_imports = true +warn_unused_configs = true +warn_redundant_casts = true +warn_unused_ignores = true +check_untyped_defs = true +plugins = ["mypy_django_plugin.main"] + +[tool.django-stubs] +django_settings_module = 'conreq.settings' diff --git a/requirements.txt b/requirements.txt index 4ee61c37..6ffe186c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -r requirements/main.txt --r requirements/dev.txt \ No newline at end of file +-r requirements/dev.txt +-r requirements/docs.txt diff --git a/requirements/dev.txt b/requirements/dev.txt index a9c566ad..9080f78d 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,4 +1,12 @@ black +django-stubs[compatible-mypy] +django_stubs_ext +flake8 +flake8-django +mypy pylint rope -pylint_django \ No newline at end of file +twine +types-requests +types-tzlocal +reactpy-flake8 diff --git a/requirements/docs.txt b/requirements/docs.txt new file mode 100644 index 00000000..088af579 --- /dev/null +++ b/requirements/docs.txt @@ -0,0 +1,4 @@ +mkdocs +mkdocs-git-revision-date-localized-plugin +mkdocs-include-markdown-plugin +mkdocs-material diff --git a/requirements/main.txt b/requirements/main.txt index 82ca6feb..3b4ca245 100644 --- a/requirements/main.txt +++ b/requirements/main.txt @@ -1,31 +1,41 @@ channels[daphne]==4.0.0 -diskcache==5.4.0 -django==3.2.16 -django-cleanup==5.2.0 -django-compression-middleware==0.4.1 -django-compressor==4.1 -django-htmlmin==0.11.0 -django-model-utils==4.2.0 +crispy-bootstrap5==0.7 +diskcache==5.6.1 +django==4.2.1 +django-ace==1.19.0 +django-cleanup==7.0.0 +django-colorfield==0.8.0 +django-compression-middleware==0.5.0 +django-compressor==4.3.1 +django-crispy-forms==2.0 +django-downloadview==2.3.0 +django-health-check==3.17.0 +django-jazzmin==2.6.0 +django-mass-edit==3.4.1 +django-multiselectfield==0.1.12 +git+https://github.com/django-ordered-model/django-ordered-model@add-field-ordered-m2m django-searchable-encrypted-fields==0.2.1 -django-silk==5.0.2 -django-solo==2.0.0 -django-url-or-relative-url-field==0.2.0 +django-silk==5.0.3 +django-solo==2.1.0 +django-split-settings==1.2.0 +django-tables2==2.5.3 +django-versionfield==1.0.3 djangorestframework==3.14.0 -djangorestframework-api-key==2.2.0 +djangorestframework-api-key==2.3.0 docutils==0.19 -drf-yasg==1.21.4 -huey==2.4.4 -hypercorn[h3]==0.14.3 -jsonfield==3.1.0 +drf-spectacular[sidecar]==0.26.2 +reactpy_django==3.6.0 +huey==2.4.5 markdown==3.4.1 -pwned-passwords-django==1.6 -pyarr==3.1.1 -pymysql==1.0.2 -python-dotenv==0.21.0 -strsim==0.0.3 -titlecase==2.4 -tmdbsimple==2.9.1 +pillow==9.5.0 +psutil==5.8.0 +python-dotenv==1.0.0 +requirements-parser==0.5.0 +sarge==0.1.6 +sortedcontainers==2.4.0 Twisted[tls,http2]==22.10.0 tzlocal==4.2 -whitenoise[brotli]==6.2.0 -attrs +uvicorn[standard]==0.22.0 +whitenoise[brotli]==6.4.0 +pip==23.1.2 +wheel diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..e9bcb829 --- /dev/null +++ b/setup.py @@ -0,0 +1,50 @@ +from pathlib import Path + +from setuptools import find_packages, setup + +# Variables +ROOT_DIR = Path(__file__).parent +with (ROOT_DIR / ".version").open() as f: + VERSION = f.read().strip() +with (ROOT_DIR / "README.md").open() as f: + README = f.read().strip() + + +# PyPi Information +PACKAGE = { + "name": "conreq", + "version": VERSION, + "packages": find_packages(str(ROOT_DIR)), + "description": "", + "long_description": README, + "long_description_content_type": "text/markdown", + "author": "Archmonger", + "author_email": "archiethemonger@gmail.com", + "url": "https://github.com/Archmonger/Conreq", + "license": "GPLv3", + "include_package_data": True, + "zip_safe": False, + "classifiers": [ + "Environment :: Web Environment", + "Programming Language :: Python", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Topic :: Internet :: WWW/HTTP", + ], +} + + +# Requirements +requirements = [] +with (ROOT_DIR / "requirements" / "main.txt").open() as f: + requirements.extend( + line + for line in map(str.strip, f) + if not line.startswith("#") and not line.startswith("git+") + ) + +PACKAGE["install_requires"] = requirements + + +# Install +if __name__ == "__main__": + setup(**PACKAGE)