From abb16938f8c1b19262f52415c791597ed88e4760 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Thu, 27 Feb 2025 22:41:38 +0100 Subject: [PATCH] initial commit --- .gitignore | 234 +++++++++++++++ LICENSE | 21 ++ README.md | 0 args.py | 60 ++++ cli.py | 110 +++++++ config.json | 29 ++ config/config.py | 0 pyproject.toml | 24 ++ src/__init__.py | 1 + src/api_tests.py | 11 + src/aria.py | 9 + src/cache_populate.py | 102 +++++++ src/data/Feeds/base.py | 11 + src/data/Feeds/nyaasi.py | 65 ++++ src/data/__init__.py | 0 src/data/apibase.py | 109 +++++++ src/data/base.py | 0 src/data/cache.py | 164 ++++++++++ src/data/comicsorg.py | 108 +++++++ src/data/comicvine.py | 149 ++++++++++ src/data/constants.py | 32 ++ src/data/komga.py | 205 +++++++++++++ src/data/mangadex.py | 323 ++++++++++++++++++++ src/data/metroncloud.py | 0 src/data/ttest.py | 18 ++ src/download.py | 52 ++++ src/errors/__init__.py | 23 ++ src/logic/cli.py | 546 ++++++++++++++++++++++++++++++++++ src/logic/constants.py | 231 ++++++++++++++ src/logic/data.py | 0 src/logic/detect_chapters.py | 16 + src/logic/download.py | 99 ++++++ src/logic/manual.py | 53 ++++ src/logic/move.py | 42 +++ src/logic/move_test.py | 45 +++ src/logic/pickles.py | 7 + src/logic/rename.py | 51 ++++ src/logic/tag.py | 27 ++ src/logic/testing.py | 190 ++++++++++++ src/logic/threads.py | 28 ++ src/logs/__init__.py | 3 + src/logs/debug.py | 23 ++ src/logs/log.py | 54 ++++ src/schema/__init__.py | 0 src/schema/brand.py | 4 + src/schema/comicdata.py | 71 +++++ src/schema/country.py | 7 + src/schema/issue.py | 47 +++ src/schema/language.py | 9 + src/schema/person.py | 14 + src/schema/publicationData.py | 7 + src/schema/publisher.py | 23 ++ src/schema/series.py | 132 ++++++++ src/schema/tmp | 260 ++++++++++++++++ src/test.ipynb | 56 ++++ src/test.py | 66 ++++ src/testcode.ipynb | 178 +++++++++++ testing.py | 13 + tests/test_aria.py | 7 + 59 files changed, 4169 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 args.py create mode 100644 cli.py create mode 100644 config.json create mode 100644 config/config.py create mode 100644 pyproject.toml create mode 100644 src/__init__.py create mode 100644 src/api_tests.py create mode 100644 src/aria.py create mode 100644 src/cache_populate.py create mode 100644 src/data/Feeds/base.py create mode 100644 src/data/Feeds/nyaasi.py create mode 100644 src/data/__init__.py create mode 100644 src/data/apibase.py create mode 100644 src/data/base.py create mode 100644 src/data/cache.py create mode 100644 src/data/comicsorg.py create mode 100644 src/data/comicvine.py create mode 100644 src/data/constants.py create mode 100644 src/data/komga.py create mode 100644 src/data/mangadex.py create mode 100644 src/data/metroncloud.py create mode 100644 src/data/ttest.py create mode 100644 src/download.py create mode 100644 src/errors/__init__.py create mode 100644 src/logic/cli.py create mode 100644 src/logic/constants.py create mode 100644 src/logic/data.py create mode 100644 src/logic/detect_chapters.py create mode 100644 src/logic/download.py create mode 100644 src/logic/manual.py create mode 100644 src/logic/move.py create mode 100644 src/logic/move_test.py create mode 100644 src/logic/pickles.py create mode 100644 src/logic/rename.py create mode 100644 src/logic/tag.py create mode 100644 src/logic/testing.py create mode 100644 src/logic/threads.py create mode 100644 src/logs/__init__.py create mode 100644 src/logs/debug.py create mode 100644 src/logs/log.py create mode 100644 src/schema/__init__.py create mode 100644 src/schema/brand.py create mode 100644 src/schema/comicdata.py create mode 100644 src/schema/country.py create mode 100644 src/schema/issue.py create mode 100644 src/schema/language.py create mode 100644 src/schema/person.py create mode 100644 src/schema/publicationData.py create mode 100644 src/schema/publisher.py create mode 100644 src/schema/series.py create mode 100644 src/schema/tmp create mode 100644 src/test.ipynb create mode 100644 src/test.py create mode 100644 src/testcode.ipynb create mode 100644 testing.py create mode 100644 tests/test_aria.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed468fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,234 @@ +# ---> Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# ---> Qt +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.so.* +*.dll +*.dylib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build-* +*.qm +*.prl + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* + +# QtCreator 4.8< compilation database +compile_commands.json + +# QtCreator local machine specific files for imported projects +*creator.user* + +*_qmlcache.qrc + + +.history +depend +output/output/LOGtoJSON.exe + +.pytest_cache +output +docs/ +config.yaml +**/tempCodeRunnerFile.py + +uv.lock +.history +.venv +venv +*.log diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aec92ac --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 WorldTeacher + +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/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/args.py b/args.py new file mode 100644 index 0000000..7deed2f --- /dev/null +++ b/args.py @@ -0,0 +1,60 @@ +import argparse + +# Default path from settings +DEFAULT_PATH = "/default/path" + + +# Define functions for each action +def action_one(path): + print(f"Performing Action One with path: {path}") + + +def action_two(path): + print(f"Performing Action Two with path: {path}") + + +def action_three(path): + print(f"Performing Action Three with path: {path}") + + +# Map actions to their corresponding functions +ACTIONS = { + "action_one": action_one, + "action_two": action_two, + "action_three": action_three, +} + + +def main(): + # Set up argument parser + parser = argparse.ArgumentParser( + description="Perform actions in a specified order." + ) + + # Add a --path argument to overwrite the default path + parser.add_argument( + "--path", + type=str, + default=DEFAULT_PATH, + help="Path to use for actions (overwrites default path).", + ) + + # Add arguments for each action + parser.add_argument( + "actions", + nargs="+", # Allow one or more actions to be specified + choices=ACTIONS.keys(), # Restrict to valid actions + help="List of actions to perform in order. Choices: " + + ", ".join(ACTIONS.keys()), + ) + + # Parse arguments + args = parser.parse_args() + + # Execute actions in the specified order + for action in args.actions: + ACTIONS[action](args.path) + + +if __name__ == "__main__": + main() diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..b707ffd --- /dev/null +++ b/cli.py @@ -0,0 +1,110 @@ +from src.logic.cli import avail_check, main as cli_main +import os +import argparse +from src.logic.rename import rename +from src.logic.tag import tag_folder +from src.logic.move import move +from src.logic.detect_chapters import detect_chapters +from komconfig import KomConfig + +cfg = KomConfig() + + +def grabber(): + nyaa, komga = avail_check() + print(nyaa, komga) + if nyaa is True and komga is True: + cli_main() + # kill aria2c + os.system("killall aria2c") + else: + print("No connection established, quitting") + + +def main(run_args=None): + parser = argparse.ArgumentParser( + description="A script to call various functions related to Komga File Management." + ) + + help_texts = { + "search": "Starts a search for all ongoing series in Komga.", + "move": "Moves the downloaded files from the download path to the Komga library.", + "tag": "Tries to tag all files in the download dir using comictagger.", + "rename": "Renames the files based on the naming scheme [Title] v[number] #[number] to get best results with comictagger.", + "detect_chapters": "Detects the chapters in the downloaded folders and removes them.", + } + + search_parser = parser.add_argument_group("Search") + search_parser.add_argument( + "-s", + "--search", + dest="actions", + action="append_const", + const="search", + help=help_texts["search"], + ) + move_parser = parser.add_argument_group("Move") + move_parser.add_argument( + "-m", + "--move", + dest="actions", + action="append_const", + const="move", + help=help_texts["move"], + ) + tag_parser = parser.add_argument_group("Tag") + tag_parser.add_argument( + "-t", + "--tag", + dest="actions", + action="append_const", + const="tag", + help=help_texts["tag"], + ) + rename_parser = parser.add_argument_group("Rename") + rename_parser.add_argument( + "-r", + "--rename", + dest="actions", + action="append_const", + const="rename", + help=help_texts["rename"], + ) + detect_chapters_parser = parser.add_argument_group("Detect Chapters") + detect_chapters_parser.add_argument( + "-d", + "--detect_chapters", + dest="actions", + action="append_const", + const="detect_chapters", + help=help_texts["detect_chapters"], + ) + + parser.add_argument( + "-p", + "--path", + type=str, + default=cfg.komgrabber.download_location, + help="Path to use for actions (overwrites default path).", + ) + args = parser.parse_args() + + # based on provided arguments, call the corresponding function + if args.actions is None: + parser.print_help() + return + for action in args.actions: + if action == "search": + grabber() + elif action == "move": + move(src=args.path, dest=cfg.komga.media_path) + elif action == "tag": + tag_folder(args.path) + elif action == "rename": + rename(args.path) + elif action == "detect_chapters": + detect_chapters(args.path) + + +if __name__ == "__main__": + main() diff --git a/config.json b/config.json new file mode 100644 index 0000000..0553c79 --- /dev/null +++ b/config.json @@ -0,0 +1,29 @@ +{ + "komga_server": "http://10.10.20.20:9001/", + "komga_auth": { + "username": "kirchneralexander020@gmail.com", + "password": "3gxjVNW2a@27#Ti" + }, + "comics.org":{ + "location":"src/databases/comics.db" + }, + "comicvine":{ + "api_key":"0d87c5060d8f5f8e5b7f153b367b8b7596be46f8", + "url":"https://comicvine.gamespot.com/api/" + }, + "download_location": "/home/alexander/Downloads/torrents/Manga_test/", + "include_factors": ["digital", "Digital"], + "skip_factors": [ + "(Digital-Compilation)", + "WN", + "Colored", + "EPUB", + "epub", + "Epub", + "PDF", + "pdf", + "Pdf", + "Crazyankan&Rippersanime" + ], + "komga_path": "/mnt/Media/Manga/" +} diff --git a/config/config.py b/config/config.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c013b83 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "komgrabber" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "aria2p>=0.12.1", + "bencodepy>=0.9.5", + "feedparser>=6.0.11", + "jaro-winkler>=2.0.3", + "komconfig", + "komgapi", + "komsuite-nyaapy", + "limit>=0.2.3", + "loguru>=0.7.3", + "natsort>=8.4.0", + "omegaconf>=2.3.0", +] + +[tool.uv.sources] +komgapi = { workspace = true } +komsuite-nyaapy = { workspace = true } +komconfig = { workspace = true } diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..f102a9c --- /dev/null +++ b/src/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.1" diff --git a/src/api_tests.py b/src/api_tests.py new file mode 100644 index 0000000..54014de --- /dev/null +++ b/src/api_tests.py @@ -0,0 +1,11 @@ +from src.data.comicvine import ComicVineAPI + +# comicdata = comic.get_series("The Walking Dead") +comic = ComicVineAPI() +if __name__ == "__main__": + + mangadata = comic.get_series("A Centaur's Life") + + print(mangadata) + +# print(type(mangadex.get_cover("8972b661-13b4-49da-a32b-1450cf9ac31d","f2bfcf6d-6535-4ee2-bc94-6de678a27399"))) \ No newline at end of file diff --git a/src/aria.py b/src/aria.py new file mode 100644 index 0000000..8f8c3f3 --- /dev/null +++ b/src/aria.py @@ -0,0 +1,9 @@ +import subprocess + + +def launch_aria2c(): + subprocess.Popen(["aria2c", "--enable-rpc", "--rpc-listen-all"]) + + +def kill_aria2c(): + subprocess.Popen(["killall", "aria2c"]) diff --git a/src/cache_populate.py b/src/cache_populate.py new file mode 100644 index 0000000..163f540 --- /dev/null +++ b/src/cache_populate.py @@ -0,0 +1,102 @@ +import json +from time import sleep + +from jellyfish import levenshtein_distance as ld + +from APIs import KomgaAPI, MangadexAPI +from APIs.cache import ListCache + +config = json.load(open("config.json")) + +ka = KomgaAPI( + "http://192.168.178.20:9001", auth=(config["username"], config["password"]) +) +# print(ka.get_all_series()) +lc = ListCache("mangacache.db") + +# lc.populate_database() +# mapi=MangadexAPI() +# def test(): +# pass + +# def other(): +# string='One Punch Man' +# test_dict={'id': '77dbfa29-8ef0-446d-82cc-1b4de878dd90', 'title': 'One Punch Man (Webcomic/Fan Colored)', 'alternate_titles': ['One Punch Man', 'Instant Death Cheat', "The Other World Doesn't Stand a Chance Against the Power of Instant Death"]} +# if string==test_dict["title"]: +# print("true") +# elif any(test_dict["alternate_titles"])==string: +# print("true") +# for title in test_dict["alternate_titles"]: +# print(jws(string,title),title) + + +# print("Levenshtein") +# for title in test_dict["alternate_titles"]: +# print(title) +# print(Levenshtein.distance(title.replace(" ",""), string.replace(" ",""))) +def determine_mangadex_id(mangadex_result, series_title: str): + if isinstance(mangadex_result) == list: + for result in mangadex_result: + if result["title"] is None: + continue + if result["title"].lower() == series_title.lower(): + return result["id"] + elif ld(result["title"].lower(), series_title.lower()) < 10: + return result["id"] + else: + for title in result["alternate_titles"]: + if ld(title.lower(), series_title.lower()) < 10: + return result["id"] + else: + if mangadex_result["title"].lower() == series_title.lower(): + return mangadex_result["id"] + elif ld(mangadex_result["title"].lower(), series_title.lower()) < 10: + return mangadex_result["id"] + else: + for title in mangadex_result["alternate_titles"]: + if ld(title.lower(), series_title.lower()) < 10: + return mangadex_result["id"] + return None + + +def mangadex_test(): + md = MangadexAPI() + series = ka.get_all_series() + for serie in series: + # print(serie) + # complete=ka.get_complete_status(serie[1]) + series_title = serie[0] + print("title", series_title) + series_id = serie[1] + mangadex_result = md.search_manga_id(series_title) + # print("resulting:",mangadex_result) + if mangadex_result is not None: + mangadex_id = determine_mangadex_id(mangadex_result, series_title) + print(mangadex_id) + lc.update_database(series_id, mangadex_id) + print("updated,sleeping to prevent ratelimit") + sleep(2) + + +# lc.populate_database() +# resutl=MangadexAPI().get_manga("77dbfa29-8ef0-446d-82cc-1b4de878dd90") + +# print(resutl) +# md=MangadexAPI() +# print(md.search_manga_id("My Instant Death Ability Is So Overpowered, No One in This Other World Stands a Chance Against Me! —AΩ—")) +# # print(MangadexAPI().search_manga_id("My Instant Death Ability Is So Overpowered, No One in This Other World Stands a Chance Against Me! —AΩ—")) +mangadex_test() + + +string1 = "Karakai Jouzu no Takagi-san Doujin" +s2_1 = "Karakai Jouzu no Takagi-san" +string2 = "Karakai Jouzu no Takagi-san" +print(ld(string1, string2)) +print(ld(string1, s2_1)) + +print( + determine_mangadex_id( + MangadexAPI().search_manga_id("Karakai Jouzu no Takagi-san"), + "Karakai Jouzu no Takagi-san", + ) +) diff --git a/src/data/Feeds/base.py b/src/data/Feeds/base.py new file mode 100644 index 0000000..c8bde86 --- /dev/null +++ b/src/data/Feeds/base.py @@ -0,0 +1,11 @@ +import feedparser as fp +class Feed: + def __init__(self) -> None: + pass + + def parse_feed(self,feed_url)->list: + try: + dataset = fp.parse(feed_url) + return dataset.entries + except: + return None diff --git a/src/data/Feeds/nyaasi.py b/src/data/Feeds/nyaasi.py new file mode 100644 index 0000000..9007a6e --- /dev/null +++ b/src/data/Feeds/nyaasi.py @@ -0,0 +1,65 @@ +# Nyaa.si will be parsed using feedparser, as they provide a RSS feed. +from komsuite_nyaapy import Nyaa +from natsort import natsorted +import re + + +class NyaaFeed(Nyaa): + def __init__(self) -> None: + super().__init__() + + def list_volumes(self, inpt) -> list[int]: + volumes = [] + inpt = inpt[0].replace("v", "") + + if "-" in inpt: + start, end = inpt.split("-") + for i in range(int(start), int(end) + 1): + volumes.append(i) + else: + volumes.append(int(inpt)) + return natsorted(volumes) + + def search(self, title: str): + dataset = super().search(title, 3, 1) + datalist = [] + if dataset is None: + return datalist + for entry in dataset: + data = {} + # print(entry) + # if not "digital" in entry.title.lower(): + # # print("Skipping {}".format(entry.title)) + # # log.log("Skipping {}".format(entry.title)) + # continue + data["title"] = entry.name + data["volumes"] = re.findall(regex, data["title"]) + try: + match = re.match( + r"^(.*?)\s(vol\.\s\d{2})|(v\d{2,3})", data["title"].lower() + ) + if match: + data["title"] = match.group(1) + except AttributeError: + # chapter check + try: + match = re.findall(r"(? bool: + tries = 10 + delay = 1 + for _ in range(tries): + try: + requests.get(self.url) + return True + except: + print(f"Connection failed, retrying in {delay} seconds") + time.sleep(delay) + delay *= 2 + return False + + def get(self, url, options: dict = None) -> requests.models.Response | None: + """Get the response from the api. + + Args: + ---- + - url (str): the part after the default api url (e.g. api.mangadex.org/*manga*) + - options (dict, optional): Options available by the API. Defaults to None. + + Returns: + ------- + - Response: the response from the api formatted as a json + - None: if the response is not 200 + """ + url = f"{self.url}/{url}" + # print(url) + result = requests.get(url, auth=self.auth, params=options if options else None) + if not result.status_code == 200: + print(result.text) + return None + if "thumbnail" in url: + return result.content + return result.json() + + def put(self, url, data: dict = None) -> requests.models.Response | None: + """put the data to the api + + Args: + url (str): the part after the default api url (e.g. api.mangadex.org/*manga*) + data (dict, optional): the data to be put. Defaults to None. + + Returns: + Response: the response from the api formatted as a json + None: if the response is not 200 + """ + url = f"{self.url}/{url}" + result = requests.put(url, auth=self.auth, json=data if data else None) + if not result.status_code == 200: + print(result.text) + return None + return result.json() + + def patch(self, url, data: dict) -> requests.models.Response | None: + """patch the data to the api + + Args: + url (str): the part after the default api url (e.g. api.mangadex.org/*manga*) + data (dict): the data to be patched + + Returns: + Response: the response from the api formatted as a json + None: if the response is not 200 + """ + url = f"{self.url}/{url}" + result = requests.patch(url, auth=self.auth, json=data if data else None) + if not result.status_code == 200: + print(result.text) + return None + return result.json() + + def post(self, url, data: dict = None) -> requests.models.Response | None: + """post the data to the api + + Args: + url (str): the part after the default api url (e.g. api.mangadex.org/*manga*) + data (dict): the data to be posted + + Returns: + Response: the response from the api formatted as a json + None: if the response is not 200 + """ + url = f"{self.url}/{url}" + result = requests.post(url, auth=self.auth, json=data if data else None) + if not result.status_code == 200: + print(result.text) + return None + return result.json() + + +if __name__ == "__main__": + print("This is a module, not a script") + ap = API("https://api.mangadex.org") + res = ap.get( + "/manga?title=My Instant Death Ability Is So Overpowered, No One in This Other World Stands a Chance Against Me! —AΩ—" + ) + print(res) diff --git a/src/data/base.py b/src/data/base.py new file mode 100644 index 0000000..e69de29 diff --git a/src/data/cache.py b/src/data/cache.py new file mode 100644 index 0000000..273ba3c --- /dev/null +++ b/src/data/cache.py @@ -0,0 +1,164 @@ +import os +import sqlite3 as sql + +from src.data.komga import KomgaAPI + +template = "name,komga_id,complete,mangadex,anilist,comicvine,myanimelist,kitsu,lastcheck" +template_cache = "name, komga_id,cover,metadata,provider" + +ka = KomgaAPI() + + +class ListCache: + def __init__(self, db_name): + if not os.path.exists(db_name): + self.create_database(db_name, template) + self.con = sql.connect(db_name) + self.cursor = self.con.cursor() + + def create_database(self, db_name, template): + print("Creating database") + con = sql.connect(db_name) + cursor = con.cursor() + cursor.execute( + f"CREATE TABLE IF NOT EXISTS cache (id INTEGER PRIMARY KEY AUTOINCREMENT, {template} TEXT, UNIQUE(komga_id))" + ) + cursor.execute( + f"CREATE TABLE IF NOT EXISTS series (id INTEGER PRIMARY KEY AUTOINCREMENT, {template_cache} TEXT)" + ) + con.close() + con.close() + return self + + def populate_database(self): + print("Populating database") + for series in ka.getAllSeries(): + print(series) + name = series.name.replace("'", "''") # escape single quotes + komga_id = series.id.replace("'", "''") # escape single quotes + status = series.metadata.status.replace("'", "''") # escape single quotes + self.cursor.execute( + f"INSERT INTO cache (name, komga_id, complete) VALUES ('{name}', '{komga_id}', '{status}')" + ) + self.con.commit() + + def update_database( + self, + komga_id, + id_type, + id + ): + local_vars = locals() + print(local_vars) + if id_type in local_vars: + local_vars[id_type] = id + print(local_vars) + print(f"Updating database with {id_type} id {id}") + # check if the id is already in the database + query = f"SELECT * FROM cache WHERE {id_type} = '{id}'" + self.cursor.execute(query) + result = self.cursor.fetchone() + if result: + print(f"ID {id} already in database") + print("Updating database") + query = f"UPDATE cache SET {id_type} = '{id}' WHERE komga_id = '{komga_id}'" + print(query) + try: + self.cursor.execute(query) + self.con.commit() + except sql.OperationalError: + print( + "Error updating database, possibly due to missing data, repopulate the database" + ) + self.populate_database() + + return 0 + else: + print(f"ID {id} not in database") + print("Adding ID to database") + query = f"INSERT INTO cache ({id_type}) VALUES ('{id}') WHERE komga_id = '{komga_id}'" + print(query) + try: + self.cursor.execute(query) + self.con.commit() + except sql.OperationalError: + print( + "Error updating database, possibly due to missing data, repopulate the database" + ) + self.populate_database() + return 0 + def get_cached_ids(self): + self.cursor.execute("SELECT name,provider FROM series") + return self.cursor.fetchall() + + def add_cached_entry(self, name, komga_id, cover, metadata,provider): + self.cursor.execute( + "INSERT INTO series (name, komga_id, cover, metadata,provider) VALUES (?, ?, ?, ?,?)", + (name, komga_id, cover, metadata,provider), + ) + self.con.commit() + + def get_cached_entry(self, komga_id,provider)->tuple: + try: + self.cursor.execute(f"SELECT metadata FROM series WHERE komga_id='{komga_id}' AND provider='{provider}'") + return self.cursor.fetchone() + except: + return 0 + + def delete_cached_entries(self): + self.cursor.execute("DELETE FROM series") + + + def get_series_by_id(self, search_id: str, search_field: str) -> tuple: + """Search the database for a series by id. + + Args: + ---- + search_id (str): the id to search for + search_field (str): the field to search in. Must be one of the following: komga_id, mangadex_id, anilist_id, comicvine + + Returns: + ------- + tuple: a tuple containing the series data + """ + self.cursor.execute(f"SELECT * FROM cache WHERE {search_field}='{search_id}'") + return self.cursor.fetchone() + + def get_all_series(self, return_data: str = "*") -> list[tuple]: + self.cursor.execute(f"SELECT {return_data} FROM cache") + return self.cursor.fetchall() + + def add_series(self, name: str, komga_id: str, complete: str = "ONGOING") -> None: + self.cursor.execute( + "INSERT INTO cache (name, komga_id, complete) VALUES (?, ?, ?)", + (name, komga_id, complete), + ) + self.con.commit() + + def query(self, query: str) -> list[tuple]: + self.cursor.execute(query) + return self.cursor.fetchall() + + def query_all_missing_id_type( + self, id_type: str + ) -> list[tuple[int, str, str, str, str, str, str]]: + """Queryl all entries in the database that do not have the requested id type. + + Args: + ---- + id_type (str): The string describing the id type. Can be mangadex, comicvine or anilist + + Returns: + ------- + list[str]: The result of the query + """ + query = f"SELECT * FROM cache WHERE {id_type}_id IS NULL" + self.cursor.execute(query) + return self.cursor.fetchall() + + +if __name__ == "__main__": + from komga import KomgaAPI + + lc = ListCache("mangacache.db") + # lc.populate_ diff --git a/src/data/comicsorg.py b/src/data/comicsorg.py new file mode 100644 index 0000000..bf5b824 --- /dev/null +++ b/src/data/comicsorg.py @@ -0,0 +1,108 @@ +import json +import sqlite3 as sql +from src.schema.brand import BrandMetadata +from src.schema.country import CountryMetadata +from src.schema.language import LanguageMetadata +from src.schema.publicationData import PublicationTypeMetadata +from src.schema.series import GenericSeries +from src.schema.comicdata import ComicsORGdata +from src.schema.issue import IssueMetadata +from src.schema.publisher import PublisherMetadata +from typing import Optional, Union + + +config = json.load(open("config.json")) + + +class ComicsORGDB: + name = "ComicsORG" + + def __init__(self) -> None: + self.conn = sql.connect(config["comics.org"]["location"]) + self.cursor = self.conn.cursor() + + def get_series(self, title: str) -> Optional[list[GenericSeries]]: + """TODO: implement this + Here, a conversion from the ComicsORGdata object to a GenericSeries object should be done. + The series will be displayed in a new gui to select the correct series. + """ + ret_lst = [] + series = self.get_series_data(title) + + for serie in series: + ret = GenericSeries() + ret.series_id = serie.id + ret.provider = "comics.org" + ret.name = serie.name + ret.alternate_names = None + ret.sort_name = serie.sort_name + ret.releaseDate = serie.year_began + ret.publisher = serie.publisher.name + ret.people = None + ret.description = serie.notes + ret.language = serie.language.name + ret.issues = serie.issue_count + ret.links = None + ret.cover = None + ret.tags = None + ret_lst.append(ret) + + return ret_lst if ret_lst != [] else None + + def get_series_data(self, series_name: str) -> Union[list[ComicsORGdata], list]: + """Return a ComicsORGdata object for the specified series.""" + query = "SELECT * FROM gcd_series WHERE name =?" + params = (series_name,) + self.cursor.execute(query, params) + series_data = self.cursor.fetchall() + results = [] + for series in series_data: + tmp = ComicsORGdata(*series) + tmp.assign(first_issue=self.get_issue(tmp.first_issue_id)) + tmp.assign(last_issue=self.get_issue(tmp.last_issue_id)) + tmp.assign(publisher=self.get_publisher(tmp.publisher_id)) + tmp.assign(country=self.get_country(tmp.country_id)) + tmp.assign(language=self.get_language(tmp.language_id)) + tmp.assign( + publication_type=self.get_publication_type(tmp.publication_type_id) + ) + + results.append(tmp) + + return results + + def get_issue(self, first_issue_id: int) -> IssueMetadata: + """Return a ComicsORGdata object for the first issue of the specified series.""" + self.cursor.execute( + f"SELECT * FROM gcd_issue WHERE id = {first_issue_id} ORDER BY sort_code ASC LIMIT 1" + ) + issue_data = self.cursor.fetchone() + return IssueMetadata(*issue_data) + + def get_publisher(self, publisher_id: int) -> PublisherMetadata: + """Return a ComicsORGdata object for the specified publisher.""" + self.cursor.execute(f"SELECT * FROM gcd_publisher WHERE id = {publisher_id}") + publisher_data = self.cursor.fetchone() + return PublisherMetadata(*publisher_data) + + def get_language(self, language_id: int) -> LanguageMetadata: + """Return a ComicsORGdata object for the specified language.""" + self.cursor.execute(f"SELECT * FROM stddata_language WHERE id = {language_id}") + language_data = self.cursor.fetchone() + return LanguageMetadata(*language_data) + + def get_publication_type(self, publication_type_id: int) -> PublicationTypeMetadata: + """Return a ComicsORGdata object for the specified publication type.""" + if publication_type_id is None: + return None + self.cursor.execute( + f"SELECT * FROM gcd_series_publication_type WHERE id = {publication_type_id}" + ) + publication_type_data = self.cursor.fetchone() + return PublicationTypeMetadata(*publication_type_data) + + def get_country(self, country_id): + """Return a ComicsORGdata object for the specified country.""" + self.cursor.execute(f"SELECT * FROM stddata_country WHERE id = {country_id}") + country_data = self.cursor.fetchone() + return CountryMetadata(*country_data) diff --git a/src/data/comicvine.py b/src/data/comicvine.py new file mode 100644 index 0000000..b31cd24 --- /dev/null +++ b/src/data/comicvine.py @@ -0,0 +1,149 @@ +from src import __version__ +from typing import Any, List +import json +import platform +import requests +from src.errors import * +from src.schema.series import GenericSeries +from src.schema.person import PersonData +from enum import Enum +from limit import limit + +MINUTE = 60 + + +config = json.load(open("config.json")) +url = config["comicvine"]["url"] +api_key = config["comicvine"]["api_key"] + + +class COMICDATA(Enum): + SERIES = (4000, "volumes", List[GenericSeries]) + + @property + def prefix(self) -> int: + return self.value[0] + + @property + def endpoint(self) -> str: + return self.value[1] + + @property + def schema(self) -> Any: + return self.value[2] + + +c = COMICDATA.SERIES.endpoint + + +class ComicVineAPI: + name = "ComicVine" + + def __init__(self): + self.url = url + self.api_key = api_key + self.timeout = 30 + self.headers = { + "Accept": "application/json", + "User-Agent": f"KomGrabber/{__version__}/{platform.system()}: {platform.release()}", + } + + @limit(20, MINUTE) + def get_data( + self, + url: str, + params: dict[str:str] | None = {"api_key": api_key, "format": "json"}, + ) -> dict[str:Any]: + if params is None: + params = {} + try: + response = requests.get( + url, params=params, headers=self.headers, timeout=self.timeout + ) + response.raise_for_status() + status_code = response.status_code + if status_code == 200: + results = response.json() + return results["results"] + except ConnectionError as e: + msg = f"Unable to get access to `{url}`" + raise ConnectError(msg) from e + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + msg = "Invalid API Key" + raise LoginError(msg) from e + if e.response.status_code == 404: + msg = "Unknown endpoint" + raise AccessError(msg) from e + if e.response.status_code == 502: + msg = "Service error, retry again in 30s" + raise AccessError(msg) from e + raise ResponseError(e.response.json()["error"]) + except json.JSONDecodeError as e: + msg = f"Unable to parse response from `{url}` as Json" + raise JSONError(msg) from e + except requests.exceptions.ReadTimeout as e: + raise TimeoutError("Request timed out") from e + + def get_series( + self, title: str = None, id: str = None + ) -> GenericSeries | List[GenericSeries]: + url = f"{self.url}{COMICDATA.SERIES.endpoint}" + if id: + url = f"{url}/{COMICDATA.SERIES.prefix}-{id}" + if title: + url = f"{url}/?filter=name:{title}" + params = {"api_key": self.api_key, "format": "json"} + print(url) + data = self.get_data(url, params) + ret = self.parseData(data) + + return ret + + def get_cover(self, link: str) -> str: + """Take the link to the cover image and return the image as a byte string + + Args: + link (str): Link to the image, ususally found in ["image"]["original_url"] + + Returns: + str: Bytestring of the image + """ + return requests.get(link).content + + def getPeople(self, link) -> List[PersonData]: + data = self.get_data(link) + people = [] + for person in data["person_credits"]: + name = person["name"] + role = person["role"] + if "," in role: + roles = role.split(",") + for r in roles: + people.append(PersonData(name=name, role=r)) + else: + people.append(PersonData(name=name, role=role)) + return people + + def parseData(self, data: dict[str, Any]) -> List[GenericSeries]: + ret = [] + for series in data: + seriesData = GenericSeries() + seriesData.series_id = series["id"] + seriesData.provider = "ComicVine" + seriesData.name = series["name"] + seriesData.alternate_names = ( + series["aliases"] if series["aliases"] is not None else [] + ) + seriesData.sort_name = series["name"] + seriesData.releaseDate = series["start_year"] + seriesData.publisher = series["publisher"]["name"] + seriesData.people = self.getPeople(series["first_issue"]["api_detail_url"]) + seriesData.description = series["description"] + seriesData.issues = series["count_of_issues"] + seriesData.cover = self.get_cover(series["image"]["original_url"]) + seriesData.language = "en" + seriesData.links = [{"comicvine": series["site_detail_url"]}] + + ret.append(seriesData) + return ret diff --git a/src/data/constants.py b/src/data/constants.py new file mode 100644 index 0000000..5562c13 --- /dev/null +++ b/src/data/constants.py @@ -0,0 +1,32 @@ +_constants_link = { + "al": "https://anilist.co/manga/()", + "ap": "https://www.anime-planet.com/manga/()", + "md": "https://mangadex.org/title/()", + "kt": "https://kitsu.io/manga/()", + "bw": "https://bookwalker.jp/()", + "mal": "https://myanimelist.net/manga/()", + "mu": "https://www.mangaupdates.com/series.html?id=()", + "nu": "https://www.novelupdates.com/series/()", +} + + +_constants_label = { + "al": "Anilist", + "ap": "Anime Planet", + "bw": "BookWalker", + "kt": "Kitsu", + "mu": "MangaUpdates", + "nu": "NovelUpdates", + "amz": "Amazon", + "cdj": "CDJapan", + "mal": "MyAnimeList", + "raw": "Raw", + "engtl": "Official English Translation", + "md": "MangaDex", + "ebj": "EBookJapan", +} + +LINKS = _constants_link +LABELS = _constants_label +VALID_ROLES = ["author", "artist", "letterer", "editor", "publisher"] + diff --git a/src/data/komga.py b/src/data/komga.py new file mode 100644 index 0000000..828feb4 --- /dev/null +++ b/src/data/komga.py @@ -0,0 +1,205 @@ +import json + +import requests + +from komgapi import komgapi as KOMGAPI_REST +from src.schema.series import SeriesMetadata +from src.logs.log import Log +from komconfig import KomConfig + +config = KomConfig() + + +class KomgaAPI(KOMGAPI_REST): + def __init__(self) -> None: + self.logger = Log("KomgaAPI") + url = config.komga.url + self.auth = config.komga_auth + super().__init__( + url=url, + username=self.auth[0], + password=self.auth[1], + timeout=100, + ) + + self.connected = self.test_connection(url) + if not self.connected: + print("Komga API not connected") + exit(1) + + def test_connection(self, url) -> bool: + try: + response = requests.get(f"{url}/api/v1/series", auth=self.auth) + if response.status_code == 200: + return True + return False + except Exception as e: + print(e) + return False + + def getSeriesStatus(self, series_id) -> str: + """Request the state of the given series. + + Args: + - series_id (str): the id of the series + + Returns: + str: the status of the series + """ + response = self.series_controller.getSeries(series_id=series_id) + self.logger.log_debug(response) + return response.metadata.status + + def getCompleteStatus(self, series_id) -> bool: + """Request the state of the given series. + + Args: + - series_id (str): the id of the series + + Returns: + bool: wheter the series is complete or not + """ + response = self.series_controller.getSeries(series_id=series_id) + self.logger.log_debug(response) + curr_books = response.booksCount + total_books = response.metadata.totalBookCount + if total_books == "null" or total_books is None: + total_books = 0 + if int(curr_books) == int(total_books): + return True + return False + + def _get_series_id(self, title) -> str: + result = self.series_controller.getAllSeries() + for series in result: + # print(series["name"]) + if series.name == title: + series_id = series.id + return series_id + return None + + def lastModified(self, title: str) -> str: + """Get the last modified date of a series.""" + api_url = f"api/v1/series/{self._get_series_id(title)}" + result = self.series_controller.getSeries(api_url) + return result.lastModified.split("T")[0] + + def getVolumes( + self, + series_id: str, + media_status: list[str] = None, + read_status: list[str] = None, + tag: list[str] = None, + unpaged: bool = True, + page_integer: int = None, + size: int = None, + sort: list[str] = None, + author: list[str] = None, + ) -> list[int]: + """Get a list of all volumes matching the given criteria. + + Args: + series_id (str, optional): The series_id determined by a previous api request. Defaults to None. + media_status (list[str], optional): A List of applicable options "UNKNOWN", "ERROR", "READY", "UNSUPPORTED", "OUTDATED". Defaults to None. + read_status (list[str], optional): Options: "UNREAD", "READ", "IN_PROGRESS". Defaults to None. + tag (list[str], optional): Any tag from the database. Defaults to None. + deleted (bool, optional): wether the media was deleted. Defaults to False. + unpaged (bool, optional): if the result should stop after a page (def. to 20 results). Defaults to True. + page_integer (int, optional): integer of the resulting page. Defaults to None. + size (int, optional): idk. Defaults to None. + sort (list[str], optional): sort using property(asc|desc). Defaults to None. + author (list[str], optional): name,role. Defaults to None. + + Returns: + list[int]: _description_ + """ + + volumes = [] + # api_url=f'{self.url}/api/v1/series/{self._get_series_id(title)}/books' + result = self.series_controller.getSeriesBooks( + series_id, + media_status=media_status, + read_status=read_status, + tag=tag, + unpaged=unpaged, + page=page_integer, + size=size, + sort=sort, + ) + if result is None: + return volumes + # print(result) #! uncomment for debugging + for volume in result: + name = volume.name + if "#" in name: + vol = name.split("#")[-1] + if " " in vol: # in case something is added after the volume number + vol = vol.split(" ")[0] + if "-" in vol: + numba = vol.split("-") + m_numba = max(numba) + vol = m_numba + volumes.append(int(float(vol))) + return volumes + + def getReadCount(self, series_id: str) -> int: + """Get the number of read volumes of a series.""" + result = self.series_controller.getSeries(series_id) + return result.booksReadCount + + def getUnreadCount(self, series_id: str) -> int: + """Get the number of unread volumes of a series.""" + result = self.series_controller.getSeries(series_id) + return result.booksUnreadCount + + def getInProgressCount(self, series_id: str) -> int: + """Get the number of volumes in progress of a series.""" + result = self.series_controller.getSeries(series_id) + return result.booksInProgressCount + + def getBooksMetadata(self, series_id: str) -> list: + """Get the metadata of all books in a series.""" + result = self.series_controller.getSeries(series_id) + return result.booksMetadata + + def updateMetadata(self, series_id: str, metadata: SeriesMetadata) -> None: + metadata_komga = { + "status": metadata.status, + "statusLock": False, + "title": metadata.series_name, + "titleLock": metadata.series_name_lock, + "titleSort": metadata.series_name_sort, + "titleSortLock": metadata.series_name_sort_lock, + "summary": metadata.description, + "summaryLock": metadata.description_lock, + "publisher": metadata.publisher, + "publisherLock": metadata.publisher_lock, + "readingDirection": metadata.reading_direction, + "readingDirectionLock": metadata.reading_direction_lock, + "ageRating": metadata.ageRating, + "ageRatingLock": metadata.ageRating_lock, + "language": metadata.language, + "languageLock": metadata.language_lock, + "genres": metadata.genres, + "genresLock": metadata.genres_lock, + "tags": metadata.tags, + "tagsLock": metadata.tags_lock, + "totalBookCountLock": metadata.total_volumes_lock, + "linksLock": metadata.links_lock, + "alterateTitleLock": metadata.alternate_names_lock, + "links": metadata.links, + "alternateTitles": metadata.alternate_names, + "totalBookCount": metadata.total_volumes, + } + api_url = f"api/v1/series/{series_id}/metadata" + self.series_controller.patchMetadata(api_url, metadata_komga) + + pass + + +if __name__ == "__main__": + from data import SeriesMetadata + + api = KomgaAPI() + api.getSeriesBooks("095S763VH28SQ") + # print(api.get_all_series()) diff --git a/src/data/mangadex.py b/src/data/mangadex.py new file mode 100644 index 0000000..9ec7d8c --- /dev/null +++ b/src/data/mangadex.py @@ -0,0 +1,323 @@ +from src.data.apibase import API as _API +from src.data import constants +from src.schema.series import GenericSeries, SeriesMetadata +from src.schema.person import PersonData +import requests +# from jellyfish import jaro_similarity +# +# import thread signal emitter + + +class MangadexAPI(_API): + name = "MangaDex" + + def __init__(self, username: str = None, password: str = None): + self.url = "https://api.mangadex.org/" + super().__init__(self.url, username, password) + + def get_alternate_titles(self, titles: list[dict]) -> list: + """Get the alternate titles from the mangadex api. + + Args: + titles (list[dict]): a list of dictionaries containing the alternate titles + + Returns: + list:a list of alternate titles + """ + titles = [title for title in titles if title.keys() == {"en"}] + lst = [] + for title in titles: + lst.append(title["en"]) + return lst + + def search_manga_id(self, title: str, options: dict = None) -> dict: + """Search for a manga id using the title. + + Args: + title (str): the title of the manga + """ + title = title.replace(" ", "%20").replace("&", "%26") + data = self.get(f"/manga?title={title}&order[relevance]=desc", options=options) + result_list = [] + # print(type(data)) + # print(len(data["data"])) + for manga in data["data"]: + cleaned_data = {} + if options is not None: + for key in options.keys(): + cleaned_data[key] = [key] + return_title = ( + manga["attributes"]["title"]["en"] + if "en" in manga["attributes"]["title"].keys() + else None + ) + alternative_titles = self.get_alternate_titles( + manga["attributes"]["altTitles"] + ) + mangadex_id = manga["id"] + cleaned_data = { + "title": return_title, + "alternate_titles": alternative_titles, + "id": mangadex_id, + } + result_list.append(cleaned_data) + + # print(manga, type(manga)) + # cleaned_data["id"]=manga[0]["id"] + # if dict.keys(manga[0]["attributes"]["title"])=={"en"}: + + # cleaned_data["title"]=manga[0]["attributes"]["title"]["en"] + if len(result_list) > 0: + return result_list + # return cleaned_data + + def get_manga_id(self, title: str, options: dict = None) -> dict: + titles = self.search_manga_id(title=title, options=options) + if titles is not None: + for title in titles: + print(title) + return titles + + def get_series(self, title) -> list[GenericSeries]: + """Search the MangaDex API using the title and returl all assumed matches for the user to select from. + + Args: + ---- + - title (str): The title of the series to search for. + + Returns: + ------- + - list[GenericSeries]: A list of GenericSeries objects containing the series information. + """ + + def __publisher(links: dict) -> str: + if "engtl" in links.keys(): + link = links["engtl"] + link = link.replace("www.", "") + publisher = link.split("//")[1].split(".")[0] + return publisher + else: + return ( + links["raw"].split("//")[1].split(".")[0] + if "raw" in links.keys() + else None + ) + + def __people(relationships: list[dict]) -> list[PersonData]: + ret = [] + for p in relationships: + if p["type"] in constants.VALID_ROLES: + ret.append(self.get_author(p["id"], p["type"])) + + return ret + + def __cover(relationships: list[dict]) -> str: + for r in relationships: + if r["type"] == "cover_art": + return r["id"] + return None + + def __issues(status, lastVolume, lastChapter) -> str: + if status != "completed": + return status + elif lastVolume != "" and lastChapter != "": + return f"{lastVolume} ({lastChapter})" + else: + return lastVolume + + def __get_tags(tags: list[dict], type) -> list: + ret = [] + for t in tags: + if t["attributes"]["group"] == type: + ret.append(t["attributes"]["name"]["en"]) + return ret + + def __links(links: dict) -> list[dict]: + def __is_valid_link(link: str) -> bool: + if link.startswith("http") or link.startswith("https"): + return True + else: + return False + + link_list = {} + for key in links.keys(): + if __is_valid_link(links[key]): + link_list[key] = links[key] + else: + link_list[key] = constants.LINKS[key].replace("()", f"{links[key]}") + return link_list + + response = self.get(f"manga?title={title}") + data = response["data"] + ret = [] + for entry in data: + series_name = ( + entry["attributes"]["title"] + if "en" or "ja" in entry["attributes"]["title"].keys() + else "No Eng or Jap title found" + ) + gs = GenericSeries() + gs.series_id = entry["id"] + gs.provider = "Mangadex" + # set gs.name to value of key in series_name if it is a dict + gs.name = ( + list(series_name.items())[0][1] + if isinstance(series_name, dict) + else series_name + ) + gs.alternate_names = entry["attributes"]["altTitles"] + gs.sort_name = ( + list(series_name.items())[0][1] + if isinstance(series_name, dict) + else None + ) + gs.releaseDate = entry["attributes"]["year"] + gs.publisher = __publisher(entry["attributes"]["links"]) + gs.people = __people(entry["relationships"]) + gs.description = ( + entry["attributes"]["description"]["en"] + if "en" in entry["attributes"]["description"].keys() + else None + ) + gs.cover = self.get_cover(gs.series_id, __cover(entry["relationships"])) + gs.language = entry["attributes"]["originalLanguage"] + gs.issues = __issues( + status=entry["attributes"]["status"], + lastVolume=entry["attributes"]["lastVolume"], + lastChapter=entry["attributes"]["lastChapter"], + ) + gs.links = __links(entry["attributes"]["links"]) + gs.tags = __get_tags(entry["attributes"]["tags"], "theme") + gs.tags.append(entry["attributes"]["publicationDemographic"]) + gs.genres = __get_tags(entry["attributes"]["tags"], "genre") + gs.rating = entry["attributes"]["contentRating"] + ret.append(gs) + + return ret + + def get_author(self, author_id: str, role: str = None) -> PersonData: + data = self.get(f"author/{author_id}") + pd = PersonData() + pd.name = data["data"]["attributes"]["name"] + pd.role = role if role is not None else data["data"]["attributes"]["role"] + return pd + + def get_series_by_id(self, id: str) -> GenericSeries: + data = self.get(f"manga/{id}") + series_name = ( + data["attributes"]["title"] + if "en" or "ja" in data["attributes"]["title"].keys() + else "No Eng or Jap title found" + ) + gs = GenericSeries() + gs.series_id = data["id"] + gs.provider = "Mangadex" + # set gs.name to value of key in series_name if it is a dict + gs.name = ( + list(series_name.items())[0][1] + if isinstance(series_name, dict) + else series_name + ) + return gs + + def get_metadata(self, id: str, lang: str) -> SeriesMetadata: #!Deprecate ? + def __create_links(links: dict) -> list[dict]: + def __is_valid_link(link: str) -> bool: + if link.startswith("http") or link.startswith("https"): + return True + else: + return False + + link_list = [] + for key in links.keys(): + link_struct = {"label": None, "url": None} + if __is_valid_link(links[key]): + link_struct["label"] = constants.LABELS[key] + link_struct["url"] = links[key] + link_list.append(link_struct) + else: + link_struct["label"] = constants.LABELS[key] + link_struct["url"] = constants.LINKS[key].replace( + "()", f"{links[key]}" + ) + link_list.append(link_struct) + return link_list + + def __get_genres(genres: list[dict]) -> list: + genre_list = [] + for t in genres: + if t["attributes"]["group"] == "genre": + genre_list.append(t["attributes"]["name"]["en"]) + return genre_list + + def __get_tags(tags: list[dict]) -> list: + tag_list = [] + for t in tags: + if t["attributes"]["group"] != "genre": + tag_list.append(t["attributes"]["name"]["en"]) + return tag_list + + def __get_people(ppl: list[dict]) -> list[dict]: + VALID_ROLES = ["author", "artist", "letterer", "editor", "publisher"] + + def __get_author(author_id: str) -> str: + data = self.get(f"author/{author_id}") + return data["data"]["attributes"]["name"] + + ppl_list = [] + for p in ppl: + if p["type"] not in VALID_ROLES: + continue + struct = {"name": None, "role": None} + struct["name"] = __get_author(p["id"]) + struct["role"] = p["type"] + ppl_list.append(struct) + return ppl_list + + data = self.get(f"manga/{id}") + # print(data) + # print("-------------------") + metadata = SeriesMetadata() + + metadata.alternate_names = self.get_alternate_titles( + data["data"]["attributes"]["altTitles"] + ) + metadata.series_type = data["data"]["type"] + metadata.description = ( + data["data"]["attributes"]["description"][lang] + if lang in data["data"]["attributes"]["description"].keys() + else None + ) + metadata.links = __create_links(data["data"]["attributes"]["links"]) + metadata.status = data["data"]["attributes"]["status"] + metadata.genres = __get_genres(data["data"]["attributes"]["tags"]) + metadata.tags = __get_tags(data["data"]["attributes"]["tags"]) + metadata.authors = __get_people(data["data"]["relationships"]) + + return metadata + + def get_cover(self, series_id: str, cover_id: str): + def __filename(cover_id: str): + result = self.get(f"cover/{cover_id}") + if result is not None: + return result["data"]["attributes"]["fileName"] + else: + return "ParseError" + + url = "https://mangadex.org/covers/{}/{}".format( + series_id, __filename(cover_id) + ) + if "ParseError" in url: + return None + ret = requests.get(url) + if ret.status_code == 200: + return ret.content + # return ret + # result = self.get(f"cover/{manga_id}") + # if result.status_code == 200: + # print(result.json()) + + +if __name__ == "__main__": + md = MangadexAPI() + md.get_metadata("77dbfa29-8ef0-446d-82cc-1b4de878dd90") diff --git a/src/data/metroncloud.py b/src/data/metroncloud.py new file mode 100644 index 0000000..e69de29 diff --git a/src/data/ttest.py b/src/data/ttest.py new file mode 100644 index 0000000..bea9b46 --- /dev/null +++ b/src/data/ttest.py @@ -0,0 +1,18 @@ +import requests +from urllib.parse import urljoin + + +url = "http://comicvine.gamespot.com/api/" +params = { # CV uses volume to mean series + "api_key": "0d87c5060d8f5f8e5b7f153b367b8b7596be46f8", + "format": "json", + "resources": "volume", + "query": "86--EIGHTY-SIX", + "field_list": "volume,name,id,start_year,publisher,image,description,count_of_issues,aliases", + "page": 1, + "limit": 100, + } +qurl = urljoin(url, "search") +print(qurl) +data = requests.get(qurl, params=params,headers={"Accept": "application/json"}) +print(data.content) \ No newline at end of file diff --git a/src/download.py b/src/download.py new file mode 100644 index 0000000..f3f3719 --- /dev/null +++ b/src/download.py @@ -0,0 +1,52 @@ +import requests, os, sys +import threading +from aria2p import Client, API + + +class Download: + def __init__(self, settings:dict)->None: + self.settings = settings + self.download_queue = [] + self.download_lock = threading.Lock() + self.download_thread = threading.Thread(target=self.download_worker) + self.download_thread.start() + self.aria2_running=self.check_aria2() + self.api = API( + client=Client( + host="http://localhost", + port=6800, + secret="", + timeout=60, + ) + ) + self.api.set_global_options({"dir": self.settings}) + if not self.aria2_running: + print("Aria2 is not running") + sys.exit() + + def check_aria2(self): + #check if aria2 is running + if os.system("ps -A | grep aria2c") == 0: + return True + else: + return False + + def add_download(self, url:str, )->None: + self.download_lock.acquire() + self.download_queue.append(url) + self.download_lock.release() + + def download_worker(self)->None: + while True: + if len(self.download_queue) > 0: + self.download_lock.acquire() + url, path = self.download_queue.pop(0) + self.download_lock.release() + self.download(url, path) + else: + pass + + def download(self, url:str, path:str)->None: + #aria2 torrent download + if url.endswith(".torrent"): + self.api.add_torrent(url) \ No newline at end of file diff --git a/src/errors/__init__.py b/src/errors/__init__.py new file mode 100644 index 0000000..18a4296 --- /dev/null +++ b/src/errors/__init__.py @@ -0,0 +1,23 @@ +class ConnectError(Exception): + def __init__(self, message): + super().__init__(message) + +class LoginError(Exception): + def __init__(self, message): + super().__init__(message) + +class AccessError(Exception): + def __init__(self, message): + super().__init__(message) + +class JSONError(Exception): + def __init__(self, message): + super().__init__(message) + +class ResponseError(Exception): + def __init__(self, message): + super().__init__(message) + +class ResultError(Exception): + def __init__(self, message): + super().__init__(message) \ No newline at end of file diff --git a/src/logic/cli.py b/src/logic/cli.py new file mode 100644 index 0000000..b6c529d --- /dev/null +++ b/src/logic/cli.py @@ -0,0 +1,546 @@ +import os +import re +import shutil +import subprocess +import time +import zipfile +import jaro +from src.data.komga import KomgaAPI +from komgapi.schemas.Series import Series +from src.data.mangadex import MangadexAPI +from src.data.cache import ListCache +from src.data.Feeds.nyaasi import Nyaa +from src.logic.download import Download +from komconfig import KomConfig +import loguru +import sys + +config = KomConfig() + +logs = loguru.logger +logs.remove() +logs.add("komgrabber.log", level="INFO") +Komga = KomgaAPI() +md = MangadexAPI() + + +LINE_CLEAR = "\x1b[2K" # <-- ANSI sequence +failed_items = [] + + +class utils: + def __init__(self) -> None: + self.dl = Download("/home/alexander/Downloads/torrents/Manga_test/") + self.file = None + self.serie = "" + self.serie_id = "" + self.series_data: Series = None + self.volumes = [] + self.download_path = config.komgrabber.download_location + if "~" in self.download_path: + self.download_path = os.path.expanduser(self.download_path) + # self.allSeries = Komga.getAllSeries() + pass + + def download(self, feed_url: str): + def __chapter_check(title: str) -> bool: + if title.endswith(".cbz") or title.endswith(".cbr"): + if not re.search(r"(v\d{1,3}(-\d{1,3})?)|(Vol\. \d{1,3})", title): + return True + else: + return False + + def __epub_check(title: str) -> bool: + if title.endswith(".epub"): + return True + else: + return False + + file: str + file = self.dl.get_file(feed_url) + if __chapter_check(file): + print(f"Skipping {file}, reason: no volume number, likely a chapter") + return False + if __epub_check(file): + print(f"Skipping {file}, reason: epub file") + return False + + self.file = file + + print(f"Filename: {file}") + file_move = False + if file.endswith(".cbz") or file.endswith(".cbr"): + new_folder = f"{self.download_path}{self.serie}" + os.makedirs(new_folder, exist_ok=True) + file_move = True + + state = self.dl.add_torrent(feed_url.split("/")[-1]) + if state is False: + print("Error adding torrent") + return False + + gid = self.dl.api.get_downloads()[0].gid + # check if the download is complete usin the gid + dl_complete = True + check_done = False + while not self.dl.api.get_downloads(gids=[gid])[0].seeder: + # while not self.dl.api.get_downloads()[0].seeder: + progress = self.dl.check_progress() + progress = "{:.2f}".format(progress) + eta = self.dl.api.get_downloads()[0].eta_string() + print(end=LINE_CLEAR) + print("Progress: ", progress, "ETA: ", eta, end="\r") + # if progress remains the same for 30 seconds, stop the download + progress = self.dl.check_progress() + time.sleep(30) + n_progress = self.dl.check_progress() + if not check_done: + local_files = os.listdir(f"{self.download_path}") + for f in local_files: + # print(f) + if os.path.isdir(f"{self.download_path}/{f}"): + local_files.extend( + [ + f"{self.download_path}/{f}/{file}" + for file in os.listdir(f"{self.download_path}/{f}") + ] + ) + local_files = [ + file + for file in local_files + if file.endswith(".cbz") or file.endswith(".cbr") + ] + local_volumes = Komga.getVolumes(self.series_data.id) + # if not local_files: + # dl_complete=False + # break + local_files_volumes = [] + for file in local_files: + vol_regex = r"(v\d{1,3}(-\d{1,3})?)|(Vol\. \d{1,3})" + # if the file does not match the naming convention, skip it + if re.search(vol_regex, file): + match = re.search(vol_regex, file) + if match: + vol = match.group(0).replace("v", "").replace("Vol. ", "") + if "-" in vol: + local_files_volumes.extend( + [int(volume) for volume in vol.split("-")] + ) + continue + vol = int(vol) + local_files_volumes.append(vol) + print(f"Grabbed volumes: {local_files_volumes}") + print(f"Komga volumes: {local_volumes}") + if local_files_volumes == []: + pass + # check íf any local_file_volumes are not in local_volumes + if all([vol in local_volumes for vol in local_files_volumes]): + print("all volumes downloaded, stopping...") + dl_complete = False + break + else: + print("not all volumes downloaded, continuing...") + check_done = True + if progress == n_progress: + print("Progress has not changed for 30 seconds, stopping the download") + self.dl.api.get_downloads()[0].remove(force=True) + dl_complete = False + break + else: + pass + # stop the download, remove the torrent files + try: + self.dl.api.get_downloads()[0].remove(force=True) + except: + pass + self.dl.remove_torrents() + print(end=LINE_CLEAR) + print("Download complete") + # self.dl.download(feed_url, file_rename=True) + if not dl_complete: + # remove everything from the download folder + data = os.listdir(f"{self.download_path}") + for file in data: + try: + os.remove(f"{self.download_path}{file}") + except IsADirectoryError: + shutil.rmtree(f"{self.download_path}{file}") + + if dl_complete is True: + # for dfile in os.listdir(f'{self.download_path}{file}'): + # if __chapter_check(dfile): + # os.remove(f'{self.download_path}{file}{dfile}') + try: + if file_move is True: + shutil.move( + f"{self.download_path}{file}", + f"{new_folder}/{file}", + ) + except Exception as e: + print(e) + return False + return True + return False + + def tag_files(self, folder: str, interactive: bool = False): + """Tag all files in the specified folder. + + Args: + ---- + - folder (str): the path to the folder containing the files to tag + - interactive (bool, optional): if set to True, the shell will pause and await user input instead of not writing data to file. Defaults to False. + """ + + def is_valid_cbz(file_path) -> bool: + try: + with zipfile.ZipFile(file_path, "r") as cbz_file: + # Check if the file is a valid ZIP archive + if cbz_file.testzip() is not None: + return False + + # Check if the CBZ file contains at least one image file + for file_info in cbz_file.infolist(): + if ( + not file_info.is_dir() + and file_info.filename.lower().endswith( + (".jpg", ".jpeg", ".png") + ) + ): + return True + + return False + + except (zipfile.BadZipFile, FileNotFoundError): + return False + + for file in os.listdir(f"{folder}"): + print(f"Checking {file}") + # if file is a not cbz file, skip + if not file.endswith(".cbz"): + print(f"Skipping {file}") + continue + + try: + # if not is_valid_cbz(f"{folder}/{file}"): + # print(f"removing {file}, not a valid cbz file") + # os.remove(f"{folder}/{file}") + # continue + print(f"Tagging {file}") + regex = r"v(\d{2,3}) #(\d{2,3})" + match = re.search(regex, file) + if not match: + print(f"Skipping {file}, no match") + os.remove(f"{folder}/{file}") + continue + if interactive: + subprocess.call( + f'comictagger -s -t cr -f -o "{folder}/{file}" --nosummary --overwrite -i', + shell=True, + ) + subprocess.call( + f'comictagger -s -t cr -f -o "{folder}/{file}" --nosummary --overwrite', + shell=True, + ) + print(f"Tagged {file}") + except Exception as e: + print(e) + continue + + def rename_folder_and_files(self, file: str, komga_data, remove=False): + logs.info(f"Renaming {file}") + # rename the folder to the komga name + series_id = komga_data.id + series_name = komga_data.name + new_folder = f"{self.download_path}{series_name}" + try: + os.rename(f"{self.download_path}{file}", new_folder) + except Exception as e: + print(e) + try: + files = os.listdir(new_folder) + except NotADirectoryError: + return + volumes = [] + for file in files: + if not (file.endswith(".cbz") or file.endswith(".cbr")): + print(f"Skipping {file}, not a comicarchive file") + continue + ext = file.split(".")[-1] + + # match = re.search(r"v\d{2,4}(-\d{2,4})*", file) + match = re.search(r"v\d{2,4} ", file) + + if match: + # print(match) + split_start = match.start() + split_end = match.end() + # Split the filename between split_start and split_end + volume = file[split_start:split_end] + # Split the filename at the split index, but keep the "v" and digits in the title + title = file[:split_start].strip() + # add the volume number to the title as a suffix #nr + title = f"{title} {volume} #{volume.replace('v', '')}".strip().replace( + " ", " " + ) + # print(title) + # rename the file + os.rename(f"{new_folder}/{file}", f"{new_folder}/{title}.{ext}") + volumes.append(int(volume.replace("v", ""))) + logs.info(f"Renamed {file} to {title}") + if remove: + print("removing files that are already in komga") + # search komga_name in series + # get all volumes of the serie + local_volumes = Komga.getVolumes(series_id=series_id) + # remove the volumes that are already in komga + self.remove_if_alr_in_db(local_volumes, volumes, series_name) + self.tag_files(new_folder) + + def process_serie(self, data: Series): + """Pprocess a single serie based on its title. + The process is as follows: + 1. get all volumes of the serie from komga using the api + 2. get all feed entries from nyaa.si using the api + 3. compare the volumes from komga with the volumes from nyaa.si + 3.1 if the volumes from nyaa.si are greater than the volumes from komga, add the entry to the download list. + + Args: + ---- + - data (dict): a dict containing the title of the serie at ["title"] and the id of the serie at ["id"] + + + Returns: + ------- + - list[dict]: a list of dictionaries containing the entries to download + """ + serie = data.name + series_id = data.id + vols = Komga.getVolumes(series_id=series_id, unpaged=True) + feed_titles = Nyaa.search(keyword=serie, category=3, subcategory=1) + print(feed_titles) + f_d = [] + if feed_titles == []: + failed_items.append(serie) + added_max_vols = vols if vols else [0] + # #print(len(added_max_vols)) + for entry in feed_titles: + if entry.seeders > 0: + if ( + serie.lower() in entry.name.lower() + or jaro.jaro_metric(entry.name.lower(), serie.lower()) > 0.7 + ): + volumes = entry["volumes"] + if isinstance(volumes, list): + volumes = volumes[ + ::-1 + ] # reverse the list to get the highest volume number quickly + for vol in volumes: + if vol not in added_max_vols: + f_d.append(entry) + added_max_vols.append(vol) + break + + return f_d + + def media_grabber(self, serie: Series): + result = self.process_serie(serie) + logs.info(f"Found {len(result)} new volumes for {serie.name}") + logs.info(f"Data: {result}") + print( + f"current volumes: {Komga.getVolumes(series_id=serie.id, unpaged=True)}, new volumes: {result}" + ) + + # print(result) + if len(result) != 0: + for entry in result: + # print(entry["link"]) + if self.download(entry["link"]) is True: + print("renaming...") + self.rename_folder_and_files( + self.file, komga_data=serie, remove=True + ) + # self.move_to_komga(serie=entry) + print("done") + return True + else: + # remove the folder + try: + folders = os.listdir(self.download_path) + for folder in folders: + os.remove(f"{self.download_path}{folder}") + except Exception as e: + print(e) + + return False + + def remove_if_alr_in_db( + self, present_volumes: list, downloaded_volumes: list, folder: str + ): + """Delete any file from the folder that is already in the database, or does not conform to the naming convention. + + Args: + ---- + present_volumes (list): a list of volumes that are already in the database, retrieved from komga api + downloaded_volumes (list): the list of volumes that are downloaded from the corresponding feed/api + folder (str): relative path to the folder containing the downloaded files + """ + print(f"present_volumes: {present_volumes}") + print(f"downloaded_volumes: {downloaded_volumes}") + content_folder = f"{self.download_path}{folder}" + content_files = [file for file in os.listdir(content_folder)] + print(f"content_files: {content_files}") + duplicates = [any(file in content_files for file in present_volumes)] + for file in os.listdir(content_folder): + if "#" not in file: + try: + os.remove(os.path.join(content_folder, file)) + if IsADirectoryError: + shutil.rmtree(os.path.join(content_folder, file)) + if FileNotFoundError: + continue + except Exception as e: + # print(e) + continue + # print(f"removed {file}, Reason: not a valid file") + content_files.remove(file) + for vol in present_volumes: + if vol < 10: + vol = f"0{vol}" + for file in content_files: + if str(vol) in file: + # print(f"removing {vol}") + try: + os.remove(os.path.join(content_folder, file)) + except: + print(f"could not remove {vol}") + + def move_to_komga(self, serie: tuple[str, str] = None): + komga_path = f"{config.komga.media_path}{self.serie}" + # print(f"komga_path: {komga_path}") + # print("moving to komga") + # move files to komga + for file in os.listdir(f"{self.download_path}{self.serie}"): + file_path = os.path.join(f"{self.download_path}{self.serie}", file) + final_path = os.path.join(komga_path, file) + + shutil.move(file_path, final_path) + + print(f"moved {file} to {komga_path}") + # delete empty folder + try: + os.rmdir(f"{self.download_path}{self.serie}") + logs.info(f"moved {self.serie} to komga") + except: + print(f"could not remove {self.serie}") + logs.error(f"could not remove {self.serie}") + return self + + def search_for_new_volumes(self): + series = Komga.series_controller.getAllSeries( + body={ + "condition": { + "seriesStatus": { + "operator": "is", + "value": "HIATUS", + "value": "ENDED", + } + } + } + ) + shutil.rmtree(self.download_path) + os.mkdir(self.download_path) + + for serie in series: + position = series.index(serie) + print("Working on serie", position, "of ", len(series)) + logs.info(f"searching for new volumes for {serie.name}") + print(serie.name) + self.series_data = serie + self.serie = serie.name + self.serie_id = serie.id + + if self.media_grabber(serie) is True: + self.move_to_komga(serie) + time.sleep(5) + # print("done", serie.name) + return self + + def add_missing_to_db(self): + database_series = ListCache("mangacache.db").get_all_series("name") + database_series = [serie[0] for serie in database_series] + database_set = set(database_series) + # print(database_series) + komga_series = Komga.series_controller.getAllSeries() + + db_added = [] + for serie in komga_series: + if serie.id not in database_set: + # print(serie.id) + db_added.append(serie) + ListCache("mangacache.db").add_series( + serie.id, serie.name, serie.metadata.status + ) + else: + print(f"{serie.id} already in db") + print("added to db:", len(db_added)) + + # print(f"{serie[1]} has status {komga_series}") + + @DeprecationWarning + def get_md_metadata(self, id: str): + data = md.get_metadata(id, lang="en") + db_data = ListCache("mangacache.db").get_series_by_id(id, "mangadex_id") + + def automated(self, series_data: tuple[str, str]): + """_summary_. + + Args: + ---- + series_data (list[tuple[str,str]]): _description_ + """ + if self.media_grabber(series_data) is True: + self.move_to_komga(series_data) + time.sleep(5) + + +def parallel_execution(series: list[tuple[str, str, str]]): + """_summary_. + + Args: + ---- + series (list[tuple[str,str,str]]): _description_ + """ + th = utils() + for serie in series: + th.automated(serie) + + +@DeprecationWarning +def update_state(): + database_series = ListCache("mangacache.db").get_all_series() + database_series = [serie for serie in database_series if serie[3] != "ENDED"] + + for serie in database_series: + komga_series = Komga.getSeriesStatus(serie) + if komga_series == "ONGOING": + continue + else: + ListCache("mangacache.db").update_database( + komga_id=serie[2], complete=komga_series + ) + + +def avail_check(): + komga_avail = True + + return (True, komga_avail) + + +def main(): + utils().search_for_new_volumes() + # update_state() + print("Failed series:\n", failed_items) + + +if __name__ == "__main__": + utils().search_for_new_volumes() diff --git a/src/logic/constants.py b/src/logic/constants.py new file mode 100644 index 0000000..8d1780d --- /dev/null +++ b/src/logic/constants.py @@ -0,0 +1,231 @@ +LINK_TRANSFORM = {"al":"https://anilist.co/manga/", + "ap":"https://www.anime-planet.com/manga/", + "bw":"https://bookwalker.jp/", + "kt":"https://kitsu.io/manga/", + "mu":"https://www.mangaupdates.com/series.html?id=", + "mal":"https://myanimelist.net/manga/"} + + +LANG_CODES = [ + "ab", + "aa", + "af", + "ak", + "sq", + "am", + "ar", + "an", + "hy", + "as", + "av", + "ae", + "ay", + "az", + "bm", + "ba", + "eu", + "be", + "bn", + "bi", + "bs", + "br", + "bg", + "my", + "ca", + "ch", + "ce", + "ny", + "zh", + "cu", + "cv", + "kw", + "co", + "cr", + "hr", + "cs", + "da", + "dv", + "nl", + "dz", + "en", + "eo", + "et", + "ee", + "fo", + "fj", + "fi", + "fr", + "fy", + "ff", + "gd", + "gl", + "lg", + "ka", + "de", + "el", + "kl", + "gn", + "gu", + "ht", + "ha", + "he", + "hz", + "hi", + "ho", + "hu", + "is", + "io", + "ig", + "id", + "ia", + "ie", + "iu", + "ik", + "ga", + "it", + "ja", + "jv", + "kn", + "kr", + "ks", + "kk", + "km", + "ki", + "rw", + "ky", + "kv", + "kg", + "ko", + "kj", + "ku", + "lo", + "la", + "lv", + "li", + "ln", + "lt", + "lu", + "lb", + "mk", + "mg", + "ms", + "ml", + "mt", + "gv", + "mi", + "mr", + "mh", + "mn", + "na", + "nv", + "nd", + "nr", + "ng", + "ne", + "no", + "nb", + "nn", + "ii", + "oc", + "oj", + "or", + "om", + "os", + "pi", + "ps", + "fa", + "pl", + "pt", + "pa", + "qu", + "ro", + "rm", + "rn", + "ru", + "se", + "sm", + "sg", + "sa", + "sc", + "sr", + "sn", + "sd", + "si", + "sk", + "sl", + "so", + "st", + "es", + "su", + "sw", + "ss", + "sv", + "tl", + "ty", + "tg", + "ta", + "tt", + "te", + "th", + "bo", + "ti", + "to", + "ts", + "tn", + "tr", + "tk", + "tw", + "ug", + "uk", + "ur", + "uz", + "ve", + "vi", + "vo", + "wa", + "cy", + "wo", + "xh", + "yi", + "yo", + "za", + "zu", +] +READING_DIRECTIONS = ["Left to Right", "Right to Left", "Vertical", "Webtoon"] +READING_DIRECTONS_KOMGA = ["LEFT_TO_RIGHT", "RIGHT_TO_LEFT", "VERTICAL", "WEBTOON"] +READING_DIR_TRANSLATION = { + READING_DIRECTIONS[0]: READING_DIRECTONS_KOMGA[0], + READING_DIRECTIONS[1]: READING_DIRECTONS_KOMGA[1], + READING_DIRECTIONS[2]: READING_DIRECTONS_KOMGA[2], + READING_DIRECTIONS[3]: READING_DIRECTONS_KOMGA[3], +} + + +METADATA_PROVIDERS = ["MangaDex", "ComicVine", "AniList", "MyAnimeList", "Comics.org"] +SERIES_STATUS = ["---", "Ongoing", "Ended", "Hiatus", "Abandoned"] +SERIES_STATUS_KOMGA = ["UNKNOWN", "ONGOING", "ENDED", "HIATUS", "ABANDONED"] +SERIES_STATUS_TRANSLATION = { + SERIES_STATUS[0]: SERIES_STATUS_KOMGA[0], + SERIES_STATUS[1]: SERIES_STATUS_KOMGA[1], + SERIES_STATUS[2]: SERIES_STATUS_KOMGA[2], + SERIES_STATUS[3]: SERIES_STATUS_KOMGA[3], + SERIES_STATUS[4]: SERIES_STATUS_KOMGA[4], +} + +def translate_series_status(status: str) -> str: + if status in SERIES_STATUS_TRANSLATION.keys(): + return SERIES_STATUS_TRANSLATION[status] + else: + #get the key from the value + for key, value in SERIES_STATUS_TRANSLATION.items(): + if value == status: + return key + +def translate_reading_direction(direction: str) -> str: + if direction in READING_DIR_TRANSLATION.keys(): + return READING_DIR_TRANSLATION[direction] + else: + #get the key from the value + for key, value in READING_DIR_TRANSLATION.items(): + if value == direction: + return key \ No newline at end of file diff --git a/src/logic/data.py b/src/logic/data.py new file mode 100644 index 0000000..e69de29 diff --git a/src/logic/detect_chapters.py b/src/logic/detect_chapters.py new file mode 100644 index 0000000..7154e47 --- /dev/null +++ b/src/logic/detect_chapters.py @@ -0,0 +1,16 @@ +import os +import re + + +def detect_chapters(src: str = "/home/alexander/Downloads/torrents/manga/"): + for folder in os.listdir(src): + if os.path.isdir(f"{src}/{folder}"): + files = os.listdir(f"{src}/{folder}") + for file in files: + # check for regex "v(d) #(d)" in the file name + regex = re.compile(r"^.* v(\d+) #(\d+(?:-\d+)?)\.cbz$") + if regex.search(file): + print(f"File {file} is a Volume") + else: + print(f"Deleting chapter {file}") + os.remove(f"{src}/{folder}/{file}") diff --git a/src/logic/download.py b/src/logic/download.py new file mode 100644 index 0000000..b91da2e --- /dev/null +++ b/src/logic/download.py @@ -0,0 +1,99 @@ +import sys +import os +import time +import bencodepy +from .rename import rename +from aria2p import Client + +from aria2p import API + +class Download: + """ Download a file from a url and start the download using aria2""" + def __init__(self, download_location) -> None: + self.download_location=download_location + self.filename=None + self.torrent_file=None + self.progress=0 + self.canceled=False + self.aria2_running=self.check_aria2() + self.api = API( + client=Client( + host="http://localhost", + port=6800, + secret="", + timeout=60, + ) + ) + self.api.set_global_options({"dir": self.download_location}) + if not self.aria2_running: + print("Aria2 is not running") + sys.exit() + def check_aria2(self): + #check if aria2 is running + if os.system("ps -A | grep aria2c") == 0: + return True + else: + return False + + + + def check_progress(self): + try: + current_progress=self.api.get_downloads()[0].progress + except: + return self.progress+0.01 + if current_progress > self.progress: + self.progress=current_progress + return current_progress + + def get_file(self, url, series_name=None): + #get the file name from the url + #use wget to download the file to the download location + name=url.split('/')[-1] + dl_url=f'{self.download_location}{name}' + while self.get_filename(dl_url) is None: + if not os.path.exists(dl_url): + os.system(f'wget -P {self.download_location} {url}') + filename = self.get_filename(dl_url) + self.torrent_file=url.split('/')[-1] + self.filename=filename + return filename + + + + def remove_torrents(self): + tr_files=[file for file in os.listdir(self.download_location) if ".torrent" in file] + for file in tr_files: + os.remove(f'{self.download_location}{file}') + + def add_torrent(self, torr_name): + try: + self.api.add_torrent(f'{self.download_location}{torr_name}') + print("Torrent added") + except Exception as e: + print(f"Error adding torrent: {e}") + return False + + + + def rename_download(self): + filename=self.filename.replace(".aria2", "") + foldername=filename.replace(".cbz", "") if ".cbz" in filename else filename + print(f'Filename: {filename}') + print(f'Foldername: {foldername}') + if not os.path.exists(f'{self.download_location}{foldername}'): + os.mkdir(f'{self.download_location}{foldername}') + os.rename(f'{self.download_location}{filename}', f'{self.download_location}{foldername}/{filename}') + #rename the file + rename(f'{self.download_location}{foldername}') + + def get_filename(self, torrent_file): + try: + with open(torrent_file, 'rb') as f: + torrent = bencodepy.decode(f.read()) + #self.filename=torrent[b'info'][b'name'].decode('utf-8') + return torrent[b'info'][b'name'].decode('utf-8') + except FileNotFoundError: + return None + + \ No newline at end of file diff --git a/src/logic/manual.py b/src/logic/manual.py new file mode 100644 index 0000000..05d82b9 --- /dev/null +++ b/src/logic/manual.py @@ -0,0 +1,53 @@ +import os +import re + + +def _vol_list() -> list[int]: + path = "/home/alexander/Downloads/torrents/Manga_test/" + # get all files in the dir and subdirs + files = os.listdir(path) + + for f in files: + print(f) + if os.path.isdir(f"{path}/{f}"): + print("is dir") + files.extend([f"{path}/{f}/{file}" for file in os.listdir(f"{path}/{f}")]) + + return files + + +def isdircheck(path: str) -> bool: + if os.path.isdir(path): + return True + else: + return False + + +def __chapter_check(title: str) -> bool: + if title.endswith(".cbz") or title.endswith(".cbr"): + if not re.search(r"(v\d{1,3}(-\d{1,3})?)|(Vol\. \d{1,3})", title): + return True + else: + return False + + +def check_folder(folder): + files = os.listdir(folder) + for file in files: + if os.path.isdir(f"{folder}/{file}"): + print(f"{file} is a dir") + check_folder(f"{folder}/{file}") + else: + print(f"{file} is a file") + if __chapter_check(file): + print(f"{file} is a chapter") + os.remove(f"{folder}/{file}") + else: + print(f"{file} is a volume") + + +if __name__ == "__main__": + # # print(__chapter_check("Even Given the Worthless 'Appraiser' Class, I'm Actually the Strongest v01-09+073 (2023) (Digital) (danke-Empire).cbz")) + # __vol_list() + # # print(isdircheck("/home/alexander/Downloads/torrents/Manga_test/Peter Grill and the Philosopher's Time (Digital)/")) + check_folder("/home/alexander/Downloads/torrents/Manga_test/") diff --git a/src/logic/move.py b/src/logic/move.py new file mode 100644 index 0000000..95681af --- /dev/null +++ b/src/logic/move.py @@ -0,0 +1,42 @@ +import os +import shutil + + +def move(src, dest: str = "/mnt/Media/Manga"): + """Move the files in a folder to another folder. + Args: + ---- + - dest (str): the string to the destination folder + """ + # Get the files in the folder + # +move the folders from src to disc, if folder already exists, only move new files + folders = os.listdir(src) + for folder in folders: + if not os.path.exists(f"{dest}/{folder}"): + print(f"Moving {folder} to {dest}") + shutil.move(f"{src}/{folder}", dest) + else: + files = os.listdir(f"{src}/{folder}") + for file in files: + if not os.path.exists(f"{dest}/{folder}/{file}"): + print(f"Moving {file} to {dest}/{folder}") + shutil.move(f"{src}/{folder}/{file}", f"{dest}/{folder}") + # Remove empty folders + remove_empty_folders(src) + + +def remove_empty_folders(src): + """Remove empty folders from a directory. + Args: + ---- + - src (str): the string to the source folder + """ + folders = os.listdir(src) + for folder in folders: + if os.path.isfile(f"{src}/{folder}"): + continue + if not os.listdir(f"{src}/{folder}"): + print(f"Removing {folder}") + os.rmdir(f"{src}/{folder}") + else: + remove_empty_folders(f"{src}/{folder}") diff --git a/src/logic/move_test.py b/src/logic/move_test.py new file mode 100644 index 0000000..a3c46c7 --- /dev/null +++ b/src/logic/move_test.py @@ -0,0 +1,45 @@ +import os +import re + +folder_path = "/home/alexander/Downloads/torrents/Manga_test/" + + +def rename(folder): + """Rename the files in a folder according to the template. + Template: [Name] v[nr] #[nr].ext (e.g. "The Flash v1 #1.cbz"). + + Args: + ---- + - folder (str): the string to the folder + """ + # Get the files in the folder + files = os.listdir(folder) + for file in files: + if not file.endswith(".cbz"): + print(f"Skipping {file}, not a cbz file") + continue + ext = file.split(".")[-1] + + match = re.search(r"v\d{2,4} ", file) + if match: + print(match) + split_start = match.start() + split_end = match.end() + # Split the filename between split_start and split_end + volume = file[split_start:split_end] + # Split the filename at the split index, but keep the "v" and digits in the title + title = file[:split_start].strip() + # add the volume number to the title as a suffix #nr + title = f"{title} {volume} #{volume.replace('v','')}" + print(title) + # rename the file + os.rename(f"{folder}/{file}", f"{folder}/{title}.{ext}") + + +for folder in os.listdir(folder_path): + if os.path.isdir(f"{folder_path}/{folder}"): + rename(f"{folder_path}/{folder}") + print(f"Renamed {folder}") + else: + print(f"{folder} is not a folder") + continue diff --git a/src/logic/pickles.py b/src/logic/pickles.py new file mode 100644 index 0000000..fcfd777 --- /dev/null +++ b/src/logic/pickles.py @@ -0,0 +1,7 @@ +import pickle + +def make_pickle(obj): + return pickle.dumps(obj) + +def load_pickle(pickled_obj): + return pickle.loads(pickled_obj) \ No newline at end of file diff --git a/src/logic/rename.py b/src/logic/rename.py new file mode 100644 index 0000000..7f0fcc8 --- /dev/null +++ b/src/logic/rename.py @@ -0,0 +1,51 @@ +# Rename the downloaded files according to the template +# Template: [Name] v[nr] #[nr].ext (e.g. "The Flash v1 #1.cbz") + +import os +import re + + +def rename(folder: str = "/home/alexander/Downloads/torrents/manga/") -> None: + """Rename the files in a folder according to the template. + Template: [Name] v[nr] #[nr].ext (e.g. "The Flash v1 #1.cbz"). + + Args: + ---- + - folder (str): the string to the folder + """ + # Get the files in the folder + files = os.listdir(folder) + print(files) + for file in files: + if os.path.isdir(f"{folder}/{file}"): + rename(f"{folder}/{file}") + if not file.endswith(".cbz"): + print(f"Skipping {file}, not a cbz file") + continue + ext = file.split(".")[-1] + + match = re.search(r"v\d{2,4}", file) + if match: + split_start = match.start() + split_end = match.end() + # Split the filename between split_start and split_end + volume = file[split_start:split_end] + # Split the filename at the split index, but keep the "v" and digits in the title + title = file[:split_start].strip() + # add the volume number to the title as a suffix #nr + title = f"{title} {volume} #{volume.replace('v', '')}" + print(title) + # rename the file + os.rename(f"{folder}/{file}", f"{folder}/{title}.{ext}") + + +# rename the folder +def rename_recursive(folder: str) -> None: + # get all directories in the folder and apply the rename function to them + for root, dirs, _files in os.walk(folder): + for dir in dirs: + rename(f"{root}/{dir}") + + +if __name__ == "__main__": + rename_recursive("/home/alexander/Downloads/torrents/manga/") diff --git a/src/logic/tag.py b/src/logic/tag.py new file mode 100644 index 0000000..58adebb --- /dev/null +++ b/src/logic/tag.py @@ -0,0 +1,27 @@ +import os +from pathlib import Path +import subprocess + + +def tag_folder( + folder: Path = Path("/home/alexander/Downloads/torrents/manga/"), +) -> None: + """Tag the files in a folder according to the template. + Template: [Name] v[nr] #[nr].ext (e.g. "The Flash v1 #1.cbz"). + + Args: + ---- + - folder (Path): the string to the folder + """ + # Get the files in the folder + files = os.listdir(folder) + for file in files: + if os.path.isdir(f"{folder}/{file}"): + tag_folder(f"{folder}/{file}") + if not file.endswith(".cbz"): + continue + print("Trying to tag file", file) + subprocess.call( + f'comictagger -s -t cr -f -o "{folder}/{file}" --nosummary --overwrite -i', + shell=True, + ) diff --git a/src/logic/testing.py b/src/logic/testing.py new file mode 100644 index 0000000..e0f8410 --- /dev/null +++ b/src/logic/testing.py @@ -0,0 +1,190 @@ +import json +import os +import re + +# import a library to open zip files +import zipfile + +from jellyfish import jaro_similarity + +from APIs import KomgaAPI, MangadexAPI, NyaaFeed +from APIs.cache import ListCache + +Komga = KomgaAPI() + +config = json.load(open("config.json")) + + +cat = NyaaFeed() + + +# with open("compare1.json") as f: +# data = json.load(f) + +# with open("compare2.json") as f: +# data2 = json.load(f) + + +def compare(data1, data2): + # compare the two data sets and return a list of differences + differences = [] + for key in data1: + if key in data2: + if data1[key] != data2[key]: + differences.append(key) + else: + differences.append(key) + + return differences + + +# diffs=compare(data, data2) + +# #get the differences from the first data set +# for diff in diffs: +# print(diff, data[diff]) + +# #get the differences from the second data set +# for diff in diffs: +# print(diff, data2[diff]) + + +def check_presence_of_xml_file(filename: str): + with zipfile.ZipFile(filename, "r") as zip_ref: + return "ComicInfo.xml" in zip_ref.namelist() + + +def create_xml_file(filename: str): + with zipfile.ZipFile(filename, "r") as zip_ref: + return zip_ref.read("ComicInfo.xml") + + +def rename_files(komga_data: str): + """Rename the files in the folder to the komga name with the volume number. + + Args: + ---- + file (str): pth to the folder + komga_data (str): series name + """ + # rename the folder to the komga name + new_folder = f'{config["download_location"]}/{komga_data}' + try: + files = os.listdir(new_folder) + except FileNotFoundError: + return + for file in files: + if not (file.endswith(".cbz") or file.endswith(".cbr")): + print(f"Skipping {file}, not a cbz file") + continue + ext = file.split(".")[-1] + + match = re.search(r"v\d{2,4}(-\d{2,4})*", file) + if match: + print(match.group(0)) + vol = match.group(0).replace("v", "") + title = file.split(match.group(0))[0] + title = title.lstrip().rstrip() + new_filename = f"{title} v{vol} #{vol}.{ext}" + print(new_filename) + os.rename(f"{new_folder}/{file}", f"{new_folder}/{new_filename}") + # try: + # os.rename(f"{new_folder}/{file}", f"{new_folder}/{filename} v{vol} #{vol}.{ext}") + # except FileNotFoundError: + # print(f"File not found: {file}") + # split_index = match.start() + # #split the title after the split_index + # title=f"{file[:split_index]}{file[:split_index+len(match.group(0)):]}" + # print(title) + # volumes = match.group(0).split("-") + # volumes = [volume.replace("v", "") for volume in volumes] + # volume_data="-".join(volumes) + + # # print(volume) + # # volumes.append(int(volume)) + # # #add the volume number to the title as a suffix #nr + # title=f"{title} #{volume_data}" + # #rename the file + # os.rename(f"{new_folder}/{file}", f"{new_folder}/{title}.{ext}") + + +def __chapter_check(title: str) -> bool: + if title.endswith(".cbz") or title.endswith(".cbr"): + if not re.search(r"(v\d{1,3}(-\d{1,3})?)|(Vol\. \d{1,3})", title): + return True + else: + return False + + +def check_folder(folder): + files = os.listdir(folder) + for file in files: + if os.path.isdir(f"{folder}/{file}"): + print(f"{file} is a dir") + check_folder(f"{folder}/{file}") + else: + print(f"{file} is a file") + if __chapter_check(file): + print(f"{file} is a chapter") + os.remove(f"{folder}/{file}") + else: + print(f"{file} is a volume") + + +def add_ids(): + def __determine_similarity(search_string: str, given_string: str) -> float: + return jaro_similarity(search_string, given_string) + + database = ListCache("mangacache.db") + Ma = MangadexAPI() + result = database.query_all_missing_id_type("mangadex") + print(len(result)) + max_sim = 0 + manga_id = None + for series in result: + title = series[1] + mangadex_id = Ma.get_manga_id(title) + if type(mangadex_id) == tuple: + print("result is a tuple") + similarity = __determine_similarity(mangadex_id["title"], title) + if similarity > max_sim: + max_sim = similarity + manga_id = mangadex_id["id"] + for alt_title in mangadex_id["alternate_titles"]: + similarity = __determine_similarity(alt_title, title) + if similarity > max_sim: + max_sim = similarity + manga_id = mangadex_id["id"] + # print(mangadex_id) + elif type(mangadex_id) == list: + print("result is a list") + # print(mangadex_id) + for res_title in mangadex_id: + similarity = __determine_similarity(res_title["title"], title) + if similarity > max_sim: + max_sim = similarity + manga_id = res_title["id"] + for alt_title in res_title["alternate_titles"]: + similarity = __determine_similarity(alt_title, title) + if similarity > max_sim: + max_sim = similarity + manga_id = res_title["id"] + else: + print(mangadex_id) + print(manga_id) + + +if __name__ == "__main__": + # series_names=Komga.get_all_series() + # for series in series_names: + # print(series[0]) + # rename_files(series[0]) + folders = os.listdir(config["download_location"]) + for folder in folders: + print(folder) + check_folder(f'{config["download_location"]}/{folder}') + rename_files(f'{config["download_location"]}/{folder}') + + # rename_files(komga_data="Hell's Paradise - Jigokuraku") + + # add_ids() diff --git a/src/logic/threads.py b/src/logic/threads.py new file mode 100644 index 0000000..e6851e7 --- /dev/null +++ b/src/logic/threads.py @@ -0,0 +1,28 @@ +from gui import SeriesSelectDialog +from PySide6 import QtWidgets, QtCore, QtGui +#import thread capabilties +from PySide6.QtCore import QThread, Signal + + + +class SeriesThread(QThread): + """Thread to get the series from the api. + """ + #signal to send the series data to the main thread + series = Signal(list) + def __init__(self, api, series_name) -> None: + super().__init__() + self.api = api + self.series_name = series_name + + def run(self): + #display the SeriesSelectDialog + print("running thread") + dialog = QtWidgets.QDialog() + ui = SeriesSelectDialog(self.series_name, self.api) + ui.setupUi(dialog) + dialog.show() + dialog.exec() + + #send the data back to the main thread + self.series.emit(ui.data) \ No newline at end of file diff --git a/src/logs/__init__.py b/src/logs/__init__.py new file mode 100644 index 0000000..b3ed271 --- /dev/null +++ b/src/logs/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["Log"] + +from .log import Log diff --git a/src/logs/debug.py b/src/logs/debug.py new file mode 100644 index 0000000..3f81d71 --- /dev/null +++ b/src/logs/debug.py @@ -0,0 +1,23 @@ +import logging +from icecream import ic +from .log import Log + +log = Log("debug") + + +def debugMessage(message, debugLevel, *args, **kwargs): + ic(message) + if debugLevel == logging.DEBUG: + log.log_debug(message) + elif debugLevel == logging.INFO: + log.log_info(message) + elif debugLevel == logging.WARNING: + log.log_warning(message) + elif debugLevel == logging.ERROR: + log.log_error(message) + elif debugLevel == logging.CRITICAL: + log.log_critical(message) + else: + log.log_info(message) + ic("Invalid debug level, defaulting to INFO") + log.log_warning("Invalid debug level, defaulting to INFO") diff --git a/src/logs/log.py b/src/logs/log.py new file mode 100644 index 0000000..1e2b31c --- /dev/null +++ b/src/logs/log.py @@ -0,0 +1,54 @@ +import inspect +import logging +import os + +if not os.path.exists("logs"): + os.mkdir("logs") + +# Create a common file handler for all loggers +common_file_handler = logging.FileHandler("logs/application.log") +common_file_handler.setLevel(logging.DEBUG) + +# Include function name in the formatter +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +common_file_handler.setFormatter(formatter) + + +class Log: + def __init__(self, logger_name): + self.logger = logging.getLogger(logger_name) + self.logger.setLevel(logging.DEBUG) + self.logger.addHandler(common_file_handler) + + def log_info(self, message): + caller = inspect.stack()[1][3] + self.logger.info(f"{caller} - {message}") + + def log_debug(self, message): + caller = inspect.stack()[1][3] + self.logger.debug(f"{caller} - {message}") + + def log_warning(self, message): + caller = inspect.stack()[1][3] + self.logger.warning(f"{caller} - {message}") + + def log_error(self, message): + caller = inspect.stack()[1][3] + self.logger.error(f"{caller} - {message}") + + def log_critical(self, message): + caller = inspect.stack()[1][3] + self.logger.critical(f"{caller} - {message}") + + def log_exception(self, message): + caller = inspect.stack()[1][3] + self.logger.exception(f"{caller} - {message}") + + +# Usage example: +if __name__ == "__main__": + logger1 = Log("Logger1") + logger2 = Log("Logger2") + + logger1.log_info("This is an info message from Logger1") + logger1.log_debug("This is a debug message from Logger1") diff --git a/src/schema/__init__.py b/src/schema/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/schema/brand.py b/src/schema/brand.py new file mode 100644 index 0000000..4b9b3ab --- /dev/null +++ b/src/schema/brand.py @@ -0,0 +1,4 @@ +from dataclasses import dataclass +@dataclass +class BrandMetadata: + pass diff --git a/src/schema/comicdata.py b/src/schema/comicdata.py new file mode 100644 index 0000000..d30eec8 --- /dev/null +++ b/src/schema/comicdata.py @@ -0,0 +1,71 @@ +import copy +from dataclasses import dataclass +from typing import Any +from .issue import IssueMetadata +from .publisher import PublisherMetadata +from .country import CountryMetadata +from .language import LanguageMetadata +from .publicationData import PublicationTypeMetadata +@dataclass +class ComicsORGdata: + """Metadata for a series retrieved from the comics.org database. + """ + id: int | None = None + name: str | None = None + sort_name: str | None = None + format: str | None = None + year_began: int | None = None + year_began_uncertain: bool | None = None + year_ended: int | None = None + year_ended_uncertain: bool | None = None + publication_dates: str | None = None + first_issue_id: int | None = None + last_issue_id: int | None = None + is_current: bool | None = None + publisher_id: int | None = None # based on id request from table + country_id: int | None = None # based on id request from table + language_id: int | None = None # based on id request from table + tracking_notes: str | None = None + notes: str | None = None + has_gallery: bool | None = None + issue_count: int | None = None + created: str | None = None + modified: str | None = None + deleted: str | None = None + has_indicia_frequency: bool | None = None + has_isbn: bool | None = None + has_barcode: bool | None = None + has_issue_title: bool | None = None + has_volume: bool | None = None + is_comics_publication: bool | None = None + color: bool | None = None + dimensions: str | None = None + paper_stock: str | None = None + binding: str | None = None + publishing_format: str | None = None + has_rating: bool | None = None + publication_type_id: int | None = None # based on id request from table + is_singleton: bool | None = None + has_about_comics: bool | None = None + has_indicia_printer: bool | None = None + has_publisher_code_number: bool | None = None + first_issue: IssueMetadata | None =None # based on id request from table + last_issue: IssueMetadata | None =None # based on id request from table + publisher: PublisherMetadata | None =None + country: CountryMetadata | None =None + language: LanguageMetadata | None =None + publication_type: PublicationTypeMetadata | None =None + + def copy(self)->"ComicsORGdata": + return copy.deepcopy(self) + def replace(self, **kwargs:Any) -> "ComicsORGdata": + """Return a new ComicsORGdata object replacing specified fields with new values. + """ + tmp = self.copy() + tmp.__dict__.update(kwargs) + return tmp + def assign(self, **kwargs:Any) -> None: + """Assign new values to specified fields. + """ + self.__dict__.update(kwargs) + return self \ No newline at end of file diff --git a/src/schema/country.py b/src/schema/country.py new file mode 100644 index 0000000..395201f --- /dev/null +++ b/src/schema/country.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + +@dataclass +class CountryMetadata: + id: int | None = None + code: str | None = None + name: str | None = None diff --git a/src/schema/issue.py b/src/schema/issue.py new file mode 100644 index 0000000..ee37705 --- /dev/null +++ b/src/schema/issue.py @@ -0,0 +1,47 @@ +from dataclasses import dataclass + + + +@dataclass +class IssueMetadata: + id: int | None = None + number: int | None = None + volume: int | None = None + no_volume: int | None = None + display_volume_with_number: bool | None = None + series_id: int | None = None + indicia_publisher_id: int | None = None + indicia_pub_not_printed: bool | None = None + brand_id: int | None = None + no_brand: bool | None = None + publication_date: str | None = None + key_date: str | None = None + sort_code: str | None = None + price: str | None = None + page_count: int | None = None + page_count_uncertain: bool | None = None + indicia_frequency: str | None = None + no_indicia_frequency: bool | None = None + editing: str | None = None + no_editing: bool | None = None + notes: str | None = None + created: str | None = None + modified: str | None = None + deleted: str | None = None + is_indexed: bool | None = None + isbn: str | None = None + valid_isbn: bool | None = None + no_isbn: bool | None = None + variant_of_id: int | None = None + variant_name: str | None = None + barcode: str | None = None + no_barcode: bool | None = None + title: str | None = None + no_title: bool | None = None + on_sale_date: str | None = None + on_sale_date_uncertain: bool | None = None + rating: str | None = None + no_rating: bool | None = None + volume_not_printed: bool | None = None + no_indicia_printer: bool | None = None + variant_cover_status: str | None = None \ No newline at end of file diff --git a/src/schema/language.py b/src/schema/language.py new file mode 100644 index 0000000..309e620 --- /dev/null +++ b/src/schema/language.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass + + +@dataclass +class LanguageMetadata: + id: int | None = None + code: str | None = None + name: str | None = None + native_name: str | None = None diff --git a/src/schema/person.py b/src/schema/person.py new file mode 100644 index 0000000..c4ae237 --- /dev/null +++ b/src/schema/person.py @@ -0,0 +1,14 @@ +from dataclasses import dataclass + +@dataclass +class PersonData: + """Metadata for a person. + """ + name: str | None = None + role: str | None = None + + + @property + def __dict__(self): + return {"name": self.name, "role": self.role} + \ No newline at end of file diff --git a/src/schema/publicationData.py b/src/schema/publicationData.py new file mode 100644 index 0000000..fadf95a --- /dev/null +++ b/src/schema/publicationData.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + +@dataclass +class PublicationTypeMetadata: + id: int | None = None + name: str | None = None + notes: str | None = None diff --git a/src/schema/publisher.py b/src/schema/publisher.py new file mode 100644 index 0000000..edbc88a --- /dev/null +++ b/src/schema/publisher.py @@ -0,0 +1,23 @@ +from dataclasses import dataclass +@dataclass +class PublisherMetadata: + id: int | None = None + name: str | None = None + country_id: int | None = None + year_began: int | None = None + year_ended: int | None = None + notes: str | None = None + url: str | None = None + brand_count: int | None = None + indicia_publisher_count: int | None = None + series_count: int | None = None + created: str | None = None + modified: str | None = None + issue_count: int | None = None + deleted: str | None = None + year_began_uncertain: bool | None = None + year_ended_uncertain: bool | None = None + year_overall_began: int | None = None + year_overall_uncertain: int | None = None + year_overall_ended: int | None = None + year_overall_ended_uncertain: bool | None = None diff --git a/src/schema/series.py b/src/schema/series.py new file mode 100644 index 0000000..30a41a4 --- /dev/null +++ b/src/schema/series.py @@ -0,0 +1,132 @@ +from dataclasses import dataclass +import dataclasses +from src.schema.person import PersonData +from komgapi.schemas import Metadata +from typing import Any + +import copy + + +@dataclass +class GenericSeries: + series_id: int | None = None + provider: str | None = None + name: str | None = None + alternate_names: list[dict[str, str]] = dataclasses.field(default_factory=list) + sort_name: str | None = None + releaseDate: str | None = None + publisher: str | None = None + people: list[PersonData] | None = None + description: str | None = None + cover: bytes | None = None + language: str | None = None + issues: str | None = None + links: list[dict[str, str]] = dataclasses.field(default_factory=list) + tags: list[str] | None = None + genres: list[str] | None = None + rating: str | None = None + + @property + def copy(self) -> "GenericSeries": + return copy.deepcopy(self) + + def replace(self, **kwargs: Any) -> "GenericSeries": + """Return a new GenericSeries object replacing specified fields with new values.""" + tmp = self.copy + tmp.__dict__.update(kwargs) + return tmp + + +@dataclass +class SeriesMetadata: + """Metadata for a series.""" + + is_empty: bool = True + series_name: str | None = None + series_name_lock: bool = False + series_name_sort: str | None = None + series_name_sort_lock: bool = False + series_type: str | None = None + alternate_names: list[str] | None = None + alternate_names_lock: bool = False + publisher: str | None = None + publisher_lock: bool = False + description: str | None = None + description_lock: bool = False + tags: list[str] | None = None + tags_lock: bool = False + genres: list[str] | None = None + genres_lock: bool = False + links: list[dict[str, str]] = dataclasses.field(default_factory=list) + links_lock: bool = False + current_volumes: int | None = None + status: str | None = None + total_volumes: int | None = None + total_volumes_lock: bool = False + releaseDate: str | None = None + ageRating: str | None = None + ageRating_lock: bool = False + # authors: list[AuthorData] = dataclasses.field(default_factory=list) + authors: list[dict[str, str]] | None = None + language: str | None = None + language_lock: bool = False + reading_direction: str | None = None + reading_direction_lock: bool = False + cover: str | None = None + + @property + def copy(self) -> "SeriesMetadata": + return copy.deepcopy(self) + + def replace(self, **kwargs: Any) -> "SeriesMetadata": + """Return a new SeriesMetadata object replacing specified fields with new values.""" + tmp = self.copy + tmp.__dict__.update(kwargs) + return tmp + + def overwrite(self, changed_metadata: "SeriesMetadata") -> None: + raise NotImplementedError + + def add_data(metadata: "SeriesMetadata", field_name: str, data: str): + # Check if the field name is valid + field_names = [field.name for field in dataclasses.fields(metadata)] + if field_name not in field_names: + print(f"Error: {field_name} is not a valid field") + return + + # Set the value of the field to the data + setattr(metadata, field_name, data) + + def from_Metadata(self, metadata: Metadata): + self.is_empty + self.series_name + self.series_name_lock + self.series_name_sort + self.series_name_sort_lock + self.series_type + self.alternate_names + self.alternate_names_lock + self.publisher + self.publisher_lock + self.description + self.description_lock + self.tags + self.tags_lock + self.genres + self.genres_lock + self.links + self.links_lock + self.current_volumes + self.status + self.total_volumes + self.total_volumes_lock + self.releaseDate + self.ageRating + self.ageRating_lock + # authors: list[AuthorData] = dataclasses.field(default_factory=list) + self.authors + self.language + self.language_lock + self.reading_direction + self.reading_direction_lock + self.cover diff --git a/src/schema/tmp b/src/schema/tmp new file mode 100644 index 0000000..5ef1999 --- /dev/null +++ b/src/schema/tmp @@ -0,0 +1,260 @@ +import copy +import dataclasses +from dataclasses import dataclass +from typing import Any, TypedDict +import ast + + + +@dataclass +class GenericSeries: + series_id: int | None = None + provider: str | None = None + name: str | None = None + alternate_names: list = dataclasses.field(default_factory=list) + sort_name: str | None = None + releaseDate: str | None = None + publisher: str | None = None + people : list[PersonData] | None = None + description: str | None = None + cover: bytes | None = None + language: str | None = None + issues : str | None = None + links: list[dict[str, str]] = dataclasses.field(default_factory=list) + tags: list[str] | None = None + genres : list[str] | None = None + rating: str | None = None + + + + def copy(self)->"GenericSeries": + return copy.deepcopy(self) + + + def replace(self, **kwargs:Any) -> "GenericSeries": + """Return a new GenericSeries object replacing specified fields with new values. + """ + tmp = self.copy() + tmp.__dict__.update(kwargs) + return tmp + +@dataclass +class SeriesMetadata: + """Metadata for a series. + """ + is_empty: bool = True + series_name: str | None = None + series_name_lock: bool = False + series_name_sort: str | None = None + series_name_sort_lock: bool = False + series_type: str | None = None + alternate_names: list[str] | None = None + alternate_names_lock: bool = False + publisher: str | None = None + publisher_lock: bool = False + description: str | None = None + description_lock: bool = False + tags: list[str] | None = None + tags_lock: bool = False + genres: list[str] | None = None + genres_lock: bool = False + links: list[dict[str, str]] = dataclasses.field(default_factory=list) + links_lock: bool = False + current_volumes: int | None = None + status: str | None = None + total_volumes: int | None = None + total_volumes_lock: bool = False + releaseDate: str | None = None + ageRating: str | None = None + ageRating_lock: bool = False + #authors: list[AuthorData] = dataclasses.field(default_factory=list) + authors: list[dict[str, str]] | None = None + language: str | None = None + language_lock: bool = False + reading_direction: str | None = None + reading_direction_lock: bool = False + cover: str | None = None + + + + + + def copy(self)->"SeriesMetadata": + return copy.deepcopy(self) + def replace(self, **kwargs:Any) -> "SeriesMetadata": + """Return a new SeriesMetadata object replacing specified fields with new values. + """ + tmp = self.copy() + tmp.__dict__.update(kwargs) + return tmp + + def overwrite(self, changed_metadata: "SeriesMetadata") -> None: + raise NotImplementedError + + def add_data(metadata: "SeriesMetadata", field_name: str, data: str): + # Check if the field name is valid + field_names = [field.name for field in dataclasses.fields(metadata)] + if field_name not in field_names: + print(f'Error: {field_name} is not a valid field') + return + + # Set the value of the field to the data + setattr(metadata, field_name, data) + + + +@dataclass +class IssueMetadata: + id: int | None = None + number: int | None = None + volume: int | None = None + no_volume: int | None = None + display_volume_with_number: bool | None = None + series_id: int | None = None + indicia_publisher_id: int | None = None + indicia_pub_not_printed: bool | None = None + brand_id: int | None = None + no_brand: bool | None = None + publication_date: str | None = None + key_date: str | None = None + sort_code: str | None = None + price: str | None = None + page_count: int | None = None + page_count_uncertain: bool | None = None + indicia_frequency: str | None = None + no_indicia_frequency: bool | None = None + editing: str | None = None + no_editing: bool | None = None + notes: str | None = None + created: str | None = None + modified: str | None = None + deleted: str | None = None + is_indexed: bool | None = None + isbn: str | None = None + valid_isbn: bool | None = None + no_isbn: bool | None = None + variant_of_id: int | None = None + variant_name: str | None = None + barcode: str | None = None + no_barcode: bool | None = None + title: str | None = None + no_title: bool | None = None + on_sale_date: str | None = None + on_sale_date_uncertain: bool | None = None + rating: str | None = None + no_rating: bool | None = None + volume_not_printed: bool | None = None + no_indicia_printer: bool | None = None + variant_cover_status: str | None = None + + # def return_ + +#TODO: add the rest of the fields +@dataclass +class BrandMetadata: + pass + +@dataclass +class PublisherMetadata: + id: int | None = None + name: str | None = None + country_id: int | None = None + year_began: int | None = None + year_ended: int | None = None + notes: str | None = None + url: str | None = None + brand_count: int | None = None + indicia_publisher_count: int | None = None + series_count: int | None = None + created: str | None = None + modified: str | None = None + issue_count: int | None = None + deleted: str | None = None + year_began_uncertain: bool | None = None + year_ended_uncertain: bool | None = None + year_overall_began: int | None = None + year_overall_uncertain: int | None = None + year_overall_ended: int | None = None + year_overall_ended_uncertain: bool | None = None + +@dataclass +class CountryMetadata: + id: int | None = None + code: str | None = None + name: str | None = None + +@dataclass +class LanguageMetadata: + id: int | None = None + code: str | None = None + name: str | None = None + native_name: str | None = None +@dataclass +class PublicationTypeMetadata: + id: int | None = None + name: str | None = None + notes: str | None = None + +@dataclass +class ComicsORGdata: + """Metadata for a series retrieved from the comics.org database. + """ + id: int | None = None + name: str | None = None + sort_name: str | None = None + format: str | None = None + year_began: int | None = None + year_began_uncertain: bool | None = None + year_ended: int | None = None + year_ended_uncertain: bool | None = None + publication_dates: str | None = None + first_issue_id: int | None = None + last_issue_id: int | None = None + is_current: bool | None = None + publisher_id: int | None = None # based on id request from table + country_id: int | None = None # based on id request from table + language_id: int | None = None # based on id request from table + tracking_notes: str | None = None + notes: str | None = None + has_gallery: bool | None = None + issue_count: int | None = None + created: str | None = None + modified: str | None = None + deleted: str | None = None + has_indicia_frequency: bool | None = None + has_isbn: bool | None = None + has_barcode: bool | None = None + has_issue_title: bool | None = None + has_volume: bool | None = None + is_comics_publication: bool | None = None + color: bool | None = None + dimensions: str | None = None + paper_stock: str | None = None + binding: str | None = None + publishing_format: str | None = None + has_rating: bool | None = None + publication_type_id: int | None = None # based on id request from table + is_singleton: bool | None = None + has_about_comics: bool | None = None + has_indicia_printer: bool | None = None + has_publisher_code_number: bool | None = None + first_issue: IssueMetadata | None =None # based on id request from table + last_issue: IssueMetadata | None =None # based on id request from table + publisher: PublisherMetadata | None =None + country: CountryMetadata | None =None + language: LanguageMetadata | None =None + publication_type: PublicationTypeMetadata | None =None + + def copy(self)->"ComicsORGdata": + return copy.deepcopy(self) + def replace(self, **kwargs:Any) -> "ComicsORGdata": + """Return a new ComicsORGdata object replacing specified fields with new values. + """ + tmp = self.copy() + tmp.__dict__.update(kwargs) + return tmp + def assign(self, **kwargs:Any) -> None: + """Assign new values to specified fields. + """ + self.__dict__.update(kwargs) + return self \ No newline at end of file diff --git a/src/test.ipynb b/src/test.ipynb new file mode 100644 index 0000000..81373c5 --- /dev/null +++ b/src/test.ipynb @@ -0,0 +1,56 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "numba = \"01-02\"\n", + "if \"-\" in numba:\n", + " numba = numba.split(\"-\")\n", + " m_numba = max(numba)\n", + " numba = m_numba\n", + "\n", + "print(int(float(numba)))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/test.py b/src/test.py new file mode 100644 index 0000000..cf69b56 --- /dev/null +++ b/src/test.py @@ -0,0 +1,66 @@ +# import json +# import os +# import re + +# from APIs import KomgaAPI, MangadexAPI, NyaaFeed +# from logs import Log + +# config = json.load(open("config.json")) + +# Nyaa = NyaaFeed() +# Komga = KomgaAPI() +# md = MangadexAPI() + + +# def remove_if_alr_in_db( +# self, present_volumes: list, downloaded_volumes: list, folder: str +# ): +# """Delete any file from the folder that is already in the database, or does not conform to the naming convention. + +# Args: +# ---- +# present_volumes (list): a list of volumes that are already in the database, retrieved from komga api +# downloaded_volumes (list): the list of volumes that are downloaded from the corresponding feed/api +# folder (str): relative path to the folder containing the downloaded files +# """ +# # print(f'present_volumes: {present_volumes}') +# # print(f'downloaded_volumes: {downloaded_volumes}') +# # content_folder=f'{config["download_location"]}{folder}' +# # content_files=[file for file in os.listdir(content_folder)] +# # print(f'content_files: {content_files}') +# # print(f'dupe_files: {dupe_files}') +# # get all files that are in both lists +# dupe_files = [file for file in downloaded_volumes if file in present_volumes] +# folder_files = [file for file in os.listdir(folder)] +# for file in folder_files: +# n = re.search(r"#\d{1,4}", file) +# if n: +# vol_num = int(n.group()[1:]) +# if vol_num in dupe_files: +# os.remove(f"{folder}/{file}") +# Log.info( +# f"Deleted {file} from {folder} as it is already in the database" +# ) +# dupe_files.remove(vol_num) +# return dupe_files + + +# present_volumes = Komga.get_volumes("095S763VH28SQ") +# downloaded_volumes = [i for i in range(1, 104)] + +# print(remove_if_alr_in_db(None, present_volumes, downloaded_volumes, "")) + +# from PySide6 import QtCore, QtGui, QtWidgets +# from gui import SeriesSelectDialog +# from threads import SeriesThread +# app = QtWidgets.QApplication([]) +# title = "86" +# api = "mangadex" +# dialog = SeriesSelectDialog(title, api) +# dialog.show() +# app.exec() +# #launch seriesthread + +from APIs import ComicVineAPI +cv = ComicVineAPI() +print(cv.issue("4000-951282")) \ No newline at end of file diff --git a/src/testcode.ipynb b/src/testcode.ipynb new file mode 100644 index 0000000..38b5206 --- /dev/null +++ b/src/testcode.ipynb @@ -0,0 +1,178 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'en': 'Doukutsuou kara Hajimeru Rakuen Life ~Bannou no Saikutsu Skill de Saikyou Ni'}\n", + "{'title': 'Doukutsuou kara Hajimeru Rakuen Life ~Bannou no Saikutsu Skill de Saikyou Ni', 'alternate_titles': ['A Cave King’s Road to Paradise: Climbing to the Top with My Almighty Mining Skills!', 'The Cave King Will Live a Paradise Life -Becoming the Strongest With the Mining Skill?-', 'The King of Cave Will Live a Paradise Life'], 'id': '65af3243-8a16-4545-b53a-ed1a79e367ac'}\n" + ] + }, + { + "data": { + "text/plain": [ + "[{'title': 'Doukutsuou kara Hajimeru Rakuen Life ~Bannou no Saikutsu Skill de Saikyou Ni',\n", + " 'alternate_titles': ['A Cave King’s Road to Paradise: Climbing to the Top with My Almighty Mining Skills!',\n", + " 'The Cave King Will Live a Paradise Life -Becoming the Strongest With the Mining Skill?-',\n", + " 'The King of Cave Will Live a Paradise Life'],\n", + " 'id': '65af3243-8a16-4545-b53a-ed1a79e367ac'}]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from api import MangadexAPI\n", + "\n", + "m_api = MangadexAPI()\n", + "\n", + "m_api.get_manga_id(\n", + " \"A Cave King’s Road to Paradise: Climbing to the Top with My Almighty Mining Skills!\",\n", + " options={\"includes\": \"cover_art\"},\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " \n" + ] + } + ], + "source": [ + "from data import SeriesMetadata\n", + "\n", + "data_1 = SeriesMetadata(\n", + " is_empty=False,\n", + " series_name=\"7th Garden\",\n", + " series_name_lock=False,\n", + " series_name_sort=\"7th Garden\",\n", + " series_name_sort_lock=False,\n", + " series_type=None,\n", + " alternate_names=None,\n", + " alternate_names_lock=False,\n", + " publisher=\"Viz\",\n", + " publisher_lock=False,\n", + " description=\"As a gardener served in a rural manor, Avin wished nothing more than peaceful days along with his lord's daughter, Marie. One day, he accidentally woke up a demon sleeping in a nearby mountain. What she wished was to have him as a servant before felling the heaven and turn this world into her garden. Avin of course declined the offer. However, not long after that, the town Avin staying was suddenly raided by Knights Templar who supposed to protect the country. Avin was then presented with choices: Will he perish along with the garden and his dear ones, or become demon's servant and have this world perish instead…\",\n", + " description_lock=False,\n", + " tags=[\"suggestive\", \"supernatural\", \"shounen\"],\n", + " tags_lock=False,\n", + " genres=[\n", + " \"drama\",\n", + " \"romance\",\n", + " \"fantasy\",\n", + " \"mystery\",\n", + " \"tragedy\",\n", + " \"comdey\",\n", + " \"action\",\n", + " \"comedy\",\n", + " ],\n", + " genres_lock=False,\n", + " links=[],\n", + " links_lock=False,\n", + " current_volumes=8,\n", + " status=None,\n", + " total_volumes=None,\n", + " total_volumes_lock=False,\n", + " releaseDate=\"2016-07-31\",\n", + " ageRating=\"16\",\n", + " authors=[\n", + " {\"name\": \"Annette Roman\", \"role\": \"editor\"},\n", + " {\"name\": \"Izumi Evers\", \"role\": \"cover\"},\n", + " {\"name\": \"Izumi Mitsu\", \"role\": \"cover\"},\n", + " {\"name\": \"Izumi Mitsu\", \"role\": \"inker\"},\n", + " {\"name\": \"Izumi Mitsu\", \"role\": \"penciller\"},\n", + " {\"name\": \"Izumi Mitsu\", \"role\": \"writer\"},\n", + " {\"name\": \"Susan Daigle-Leach\", \"role\": \"letterer\"},\n", + " ],\n", + " language=\"en\",\n", + " language_lock=False,\n", + " cover=b\"\\xff\\xd8\\xff\\xe0\\x00\\x10JFIF\\x00\\x01\\x02\\x00\\x00\\x01\\x00\\x01\\x00\\x00\\xff\\xdb\\x00C\\x00\\x08\\x06\\x06\\x07\\x06\\x05\\x08\\x07\\x07\\x07\\t\\t\\x08\\n\\x0c\\x14\\r\\x0c\\x0b\\x0b\\x0c\\x19\\x12\\x13\\x0f\\x14\\x1d\\x1a\\x1f\\x1e\\x1d\\x1a\\x1c\\x1c $.' \\\",#\\x1c\\x1c(7),01444\\x1f'9=82<.342\\xff\\xdb\\x00C\\x01\\t\\t\\t\\x0c\\x0b\\x0c\\x18\\r\\r\\x182!\\x1c!22222222222222222222222222222222222222222222222222\\xff\\xc0\\x00\\x11\\x08\\x01,\\x00\\xc8\\x03\\x01\\\"\\x00\\x02\\x11\\x01\\x03\\x11\\x01\\xff\\xc4\\x00\\x1f\\x00\\x00\\x01\\x05\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\xff\\xc4\\x00\\xb5\\x10\\x00\\x02\\x01\\x03\\x03\\x02\\x04\\x03\\x05\\x05\\x04\\x04\\x00\\x00\\x01}\\x01\\x02\\x03\\x00\\x04\\x11\\x05\\x12!1A\\x06\\x13Qa\\x07\\\"q\\x142\\x81\\x91\\xa1\\x08#B\\xb1\\xc1\\x15R\\xd1\\xf0$3br\\x82\\t\\n\\x16\\x17\\x18\\x19\\x1a%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xff\\xc4\\x00\\x1f\\x01\\x00\\x03\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\xff\\xc4\\x00\\xb5\\x11\\x00\\x02\\x01\\x02\\x04\\x04\\x03\\x04\\x07\\x05\\x04\\x04\\x00\\x01\\x02w\\x00\\x01\\x02\\x03\\x11\\x04\\x05!1\\x06\\x12AQ\\x07aq\\x13\\\"2\\x81\\x08\\x14B\\x91\\xa1\\xb1\\xc1\\t#3R\\xf0\\x15br\\xd1\\n\\x16$4\\xe1%\\xf1\\x17\\x18\\x19\\x1a&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xff\\xda\\x00\\x0c\\x03\\x01\\x00\\x02\\x11\\x03\\x11\\x00?\\x00\\xf5\\x01\\xf1\\x13J\\x16\\xfb\\xe4\\x86\\xe1f\\x1f\\xf2\\xcc\\x00y\\xf69\\xac\\x87\\xf8\\x9brn\\x87\\x93\\xa4\\xa9\\xb7\\xcf!\\xa4;\\x8f\\xe3\\x8c\\n\\xcc\\xbb\\xf0\\xbb[\\xea\\x93\\xc0\\x14\\xb9F\\xfb\\x87\\xab)\\xe8\\xc3\\xfc\\xf5\\x04WG\\xa2\\xf8^\\xcett\\xba\\x880\\xc7\\x0c\\x063\\xf5\\xf45vKs\\xe8\\x9d\\x1c\\xba\\x94=\\xa5\\xb9\\x93\\xf3:\\xad6\\xfb\\xfbF\\xc9.\\r\\xbc\\xb0\\x16\\x19\\xd9 \\xe7\\xff\\x00\\xafW+.\\x19\\xe3\\xd2\\x8c\\x1a|\\x85\\xca\\xe3\\x11\\xc8zc\\xde\\xb5*\\x0f\\x06\\xacR\\x95\\xd2\\xd1\\xec\\x14QE\\x06aE\\x14P\\x01E\\x15E\\xf5kX\\xefR\\xd1\\x8by\\xce\\xdbU@\\xcf\\xf2\\xe9E\\x86\\x93{\\x17\\xa8\\xa2\\x8a\\x04\\x14R3*!w`\\xaa\\xa3$\\x93\\x80\\x05r\\xba\\xd7\\x8d\\xed4\\xff\\x00\\xdd\\xc0\\xca\\xccFC\\xb0'?\\xee\\xaf\\x19\\xfa\\x92\\x07\\xb9\\xa9\\x94\\x94U\\xd9\\xad*3\\xab.X+\\xb3\\xab\\xe9U\\xcd\\xfd\\xa8\\xce&\\x0f\\x8e\\xbeX/\\x8f\\xae3^=\\xab|F\\x9a\\xe2F\\x85\\x03`\\x13\\x97\\x97\\x0f\\xf9.6\\x8f\\xcb>\\xf5\\x8e|C\\xa8\\xebs\\xac\\x11\\xc5=\\xcc\\xbd\\x00\\x1b\\x9c\\xff\\x00\\xf5\\xab\\x17\\x89\\x85\\xec\\x8f^\\x9eE]\\xc7\\x9a\\xabQG\\xb5\\xcf\\xe2]\\\"\\xdc\\xe2[\\xd5C\\xe8T\\x8f\\xe9L\\x1e*\\xd1Y\\x0b\\x8b\\xcf\\x90us\\x13\\xed\\x1f\\x8e1^k\\xa7x^T\\xb5\\x96\\xe3Ug\\xb7\\x08\\xdbvn\\x19\\x07\\xb7\\xaf'=1\\xf8\\x8a\\xba\\x12\\xc2\\x08e\\x8e\\xce\\x18\\xe0\\x9d\\x81\\x90M7\\xefxNJ\\x90F\\x01#q\\x1dy\\\\V\\x8am\\xee\\x8eZ\\xd8|-=!''\\xe5k\\x1e\\x95o\\xabi\\xd7k\\x9b{\\xfbi@\\xeb\\xb2U8\\xfa\\xf3\\xc5[\\x040\\x04\\x10A\\xe8Eyq\\x96\\xfe\\xca\\xdcI&\\xa9y\\xbd\\x9c:)\\x9fo\\x00r\\x02\\xe0\\x0cr\\xbcs\\xd3\\xebV\\xf4\\xdd`4\\xcc-5Ky[\\x0c\\xff\\x00tn\\xc7^X\\x00}\\x8f4\\xf9\\xd1\\xc7\\xec[\\xd8\\xf4z+\\x9d\\xb7\\xd7\\xaeax\\x9a\\xee%\\x92\\xdaP1$\\x7fyO\\xd3\\xf8\\x94\\xfa\\x8e{`\\xf5\\xae\\x81\\x1dd\\x8ddF\\x0c\\x8c\\x01VS\\x90G\\xa8\\xaaN\\xe6N-n:\\x93r\\x97)\\xb8n\\x00\\x123\\xc8\\x07\\xff\\x00\\xd4ik3S\\xb7\\xba]\\xf7zz\\x03x\\x14\\x05\\xc9\\x18p\\t\\xf9[$q\\xcd48\\xab\\xbb\\x1atS!wxQ\\xe4\\x8c\\xc6\\xe5Ad';OqE\\x04\\x95\\xaf\\xb4\\xd8\\xaf\\x8cr\\x12c\\x9e,\\xec\\x91z\\x80z\\x83\\xea\\x0f\\xa5Q\\xddqc)3 \\x00\\x90\\x03\\xaf*\\xdf\\xe1\\xf4?\\x86kj\\xab^\\xdd\\xdaZ\\xc0\\xc6\\xeeX\\xd2\\xd8\\xa9M3\\x86P\\x94U\\xd8\\xeaBB\\xa9bp\\x00\\xc94\\xb4S \\xe5\\xe4\\xd5\\xafu)\\x9e+(\\xe5XK`8R\\t\\x1e\\xbc\\xf4\\x15\\xa9\\xa4\\xe8\\xe9\\xa7\\x97\\x99\\xf0\\xd3\\xb8\\xc1=v\\x8fL\\xd6\\xa5\\x15M\\xf65\\x95W\\xcb\\xcb\\x15d\\x15\\x14\\xf7\\x11\\xdbDd\\x95\\x82\\xa8\\xfdi\\xf2H\\xb1F\\xce\\xe7\\n\\xa3$\\xd7\\x96\\xf8\\xa7_\\xbe\\xd6uq\\xa5X\\xa34e\\xbc\\xb6\\n~\\xf9\\xfe\\xe8>\\x9e\\xa7\\xfa\\x0eq\\xa9QA\\x1a\\xe10\\xb2\\xc4N\\xcbD\\xb7d\\x9e&\\xf1\\xd9\\xba\\x94\\xdai\\xc4\\x14\\x07\\r \\xe4\\x0fe\\xf5>\\xfd==k\\x81\\xbf7w&{\\xb9\\\"*\\xa0\\xf2\\xeey'\\xde\\xbb\\xe4\\xf0\\xcd\\xbf\\x87\\x83\\xc9r\\x8b$v\\xf1\\x19\\xe6\\x95\\xbf\\xe5\\xa3c\\x0b\\x12\\xfbf\\xb9\\x1dJ\\xf6)t\\xbf\\xb3;\\x86y.\\x01\\x94\\xaf\\x038$\\xfe\\xa7\\x1f\\x85q\\xd4\\x8bz\\xcd\\xea}V\\x03\\xd8\\xc1r\\xd0W]\\xceNx\\x9d$*NN3\\x9a\\xf6/\\x0e[\\xe8\\xfa\\x1f\\x86\\xe2\\xbc\\xb4Y\\x0b_D\\x8c\\xe7v^S\\x8c\\xec\\x1e\\x83\\x9eH\\xc6>\\xb5\\xe5\\xd1\\x08\\xe4\\xb9\\xdapA\\xb7\\x07\\xf1\\xc8\\xafI\\xf0Lp^xb\\xcak\\x953J\\x8ab]\\xfd\\x15\\x03\\x1c\\x00*(5\\x196Fv\\xdc\\xe9E_K\\x8c\\x9c\\xdd]\\xdc\\xad\\xcc\\xc1\\x19\\xd03*\\xe3\\t\\x12\\x01\\x92\\x00\\xf4\\xed\\xef\\x9e\\xf5\\xcb\\xf8\\x8f\\xc4\\x11YJ\\xd6vq\\xee\\xc6w)\\xfb\\xa9\\x91\\xc0nrN\\x0f?\\xd2\\xbd\\x1fT\\xb7W\\xd3\\xae`\\x81@i\\xd8D\\x0fp\\xa7\\x03\\xfa\\x93\\xf5\\xaf)\\xf17\\x87\\xa4\\xd3nd\\x17\\x03t\\x8cKo'!\\xf2z\\xd6\\xb5k8\\xad\\x0f'/\\xc2\\xd2\\xadS\\x96\\xa3\\xd3\\xb7s\\x1a\\xff\\x00\\xc4Z\\x86\\xa2\\xf0\\xcbqq\\xb4\\xc2\\n\\xaf\\x92J\\x0eq\\x9e\\xfe\\xc2\\xa8\\xc52(\\xd8\\xae\\xa63\\xfc9\\xfb\\xbfJh\\x0c\\x9c\\x18\\xd3i\\xee\\xa7\\x15\\x03G R\\xa0\\xa3.~^q\\x8f\\xa7\\xbdrs9=Y\\xf4\\xf0\\xa5\\x1a*\\xd0\\x89\\xd2\\xe8\\xda\\xd5\\xcd\\xa11G9Ul\\x06S\\xca\\xb6\\x0ey\\x07\\xe9\\xd6\\xbd\\xa7\\xc1z\\xb2\\xdd\\xdb4\\x1b\\xf2\\x0edE'\\x95k\\x88_ \\xce#'\\x93\\xb9r\\t#\\xa5u^\\x1d\\xf1u\\xdd\\x94\\xd1\\xb0\\x90\\xc3w\\x1b\\xa3'\\x98G\\x96\\xdd\\xb6\\x96\\x1d\\xfa\\x8f\\xa37#\\x15\\xd1Br\\x84\\xac\\xde\\x87\\x93\\x98\\xe1\\xa1\\x88\\x872\\x8d\\xa5\\xe9\\xf9\\x9fKQU4\\xcdB\\x1dSO\\x86\\xf2\\x03\\xf2\\xca\\x81\\x8a\\xe7\\x95$g\\x07\\xdf\\x9a\\xb7^\\x89\\xf2\\x8d4\\xec\\xc2\\x8a(\\xa0G=w\\xafMqx\\xb6Z\\\\{\\x99\\xb3\\xfb\\xe2\\xa4\\x8f\\xc0z{\\x9f\\xfe\\xbdGm\\xe1A3\\x99\\xf5Y\\xda\\xe2F9(\\x0e\\x07\\xe2\\x7f\\xc3\\xf5\\xad\\xcb+\\x08,!\\xf2\\xe0\\\\g\\xef9\\xfb\\xcc}I\\xab5<\\xb7\\xd5\\x9d_Y\\xe4\\\\\\xb4t\\xf3\\xeaA\\x15\\x9d\\xb4\\x16\\xc6\\xda\\x18#\\x8e\\x12\\x08(\\xab\\x80s\\xd6\\x8b;8,-R\\xda\\xd96D\\x9furO\\xeajz\\xc0o\\x12\\xa5\\xac\\xcd\\r\\xe4-\\xe6\\x03)a\\x16\\x0e\\xd0\\x8a\\x1b\\xa9<\\xe5Nr>\\x98\\xcd6\\xd21\\x8a\\x9c\\xee\\x96\\xa6\\xec\\x91\\xac\\x88Q\\xc6A\\xaa\\xd0~\\xeegC\\xd4u\\xff\\x00hz\\xfe\\xb5\\x15\\xbe\\xaf\\x1d\\xc5\\xc4p\\xfd\\x9a\\xe23\\\"\\xb3#8\\\\\\x15^\\t\\xe1\\x8fC\\x81\\xff\\x00\\x02\\x15@\\xf8\\x85F\\x825\\x07\\x84\\x19wF\\xbeW@K\\x85n\\x0ey\\xc2\\xb6\\x7f\\x0e\\x82\\xa5\\xb5\\xb9Q\\xa7?\\x86\\xc6\\xfd\\x15\\x94u\\x95yf\\x8e\\x18\\x1c\\xaaE$\\x8b+\\x15\\xda\\xc56\\xf4\\xc1\\xce>a\\xe9Ri\\xda\\xbcZ\\x84\\x86$\\x86TuR\\xccX\\x0cp\\xc5{\\x13\\xdd[\\xf25\\\\\\xc8\\x87NI^\\xc5\\xd1!7\\x0f\\x1e8UV\\xcf\\xd4\\x9f\\xf0\\xa9*\\x15\\xff\\x00\\x8f\\xe9\\x7f\\xeb\\x9a\\x7f6\\xa7\\xcd*A\\x0c\\x92\\xc8p\\x88\\xa5\\x98\\xfb\\x01\\x9ad\\x18\\xfa\\xfd\\xe2Gg2\\x17e\\x00m\\x1bN\\x0b1\\x1d\\xbe\\x80\\x8f\\xc4\\x8fJ\\xe4<4,\\xecc\\x96\\xf8,b`\\xdeE\\xbe\\xe6\\xc8\\xcfV?@9\\xff\\x00\\xf5\\xd6]\\xf7\\x88\\x0e\\xaa/\\xe5\\x9fr-\\xb1\\\"\\x05S\\xc0ry$\\xfex\\xf6\\xc5r/\\xacO\\xe4\\x88\\x84\\x8c\\xa8\\xb9\\n\\x07\\x18\\xcf_\\xce\\xb8jWJWG\\xd4a2\\xe9\\xfb\\x17M\\xbb^\\xd7\\xfe\\xbf\\xae\\xa7G\\xe3\\x7f\\x11\\t\\xe2\\x8e\\xde\\t\\x8b\\xc4O\\x9as\\x9c\\xff\\x00\\xb2\\x0f\\xd7\\xef}My\\xf3]3[$y;\\x83\\x16'\\xdf\\xaf\\xf5\\xa7\\xde\\\\<\\xf2\\x96f$f\\xaa\\xa8\\xe8?\\x1a\\xe3\\x9c\\xdc\\x8f{\\x0fB4`\\xa1\\x12h\\xe4o5\\x88<\\x84\\xc0\\xf6\\xafa\\xf8v\\xa1|+n\\xac:\\xe5\\x87\\xe3\\xcf\\xf5\\xaf\\x1e\\xb7\\xc9\\x86w\\nw0\\n\\xbe\\xf9\\xe7\\xf9W\\xa9h\\xfa\\xd4zE\\x94:]\\xac_j\\xbbT\\x00\\xa2\\xb6\\xd5\\x8c\\x00\\x06]\\xbf\\x84q\\xf5\\xf6\\xab\\xa7\\xa6\\xe7\\x97\\x9b'R\\x11\\x8c<\\xd9\\xd6\\xf4\\xb8#\\xa8\\x1c\\xd6g\\x88\\xf4\\xd8\\xf5\\xad9\\xa3\\xc9YT\\x13\\x19\\xf7\\xf45\\x93\\xaax\\x8e-4\\xabj:\\xc5\\xb5\\xbb\\xb0\\xfb\\x8a\\x02\\x0f\\xc3y%\\xbe\\xa0\\n\\xdc\\xd3\\xddn\\xad!\\x966.\\x8c2\\x18\\xf7\\x15\\xa5\\xae\\xb5<(\\xb7NJI\\xea\\x8f\\x0c\\xd4,\\x8d\\xbd\\xc3#\\xc6\\xe9\\\"\\x9ev\\x9cV|\\xa9\\xc2\\x92d\\x05{\\xe3\\x07\\xf2\\xef^\\x95\\xf1\\x03G\\x16\\xd7\\x82\\xe2$\\xc2J7c\\x19\\xf9\\xbb\\xd7\\tm\\xa4\\xdcj\\xb7igm\\x17\\x9b3\\xe4\\x85\\xe0`\\x0e\\xa4\\x92p\\x00\\xeeM`\\x93R\\xe5>\\x9e\\x15\\xa3R\\x87\\xb5\\xe9\\xd4\\xcct_0\\x91<\\x88\\xec\\xa3;[$\\x8fR=}\\xe8+9\\x03\\x0c$S\\x9e\\x18`\\xaf\\xb7\\xb9\\xae\\xd6\\xc7\\xc0\\xdaL\\xaa\\x9fi\\xd5\\xa2\\x9eA\\x9c%\\x94~`\\x07\\xbe$b\\x01\\xfa\\x81Q\\xdc\\xe9:\\x1e\\x9a\\xb2\\xcbmou,p\\x8c3K8\\x08\\x0ep\\x00T\\x03\\x93\\xf5\\xad\\x94\\x19\\xc6\\xf1\\xb4\\x9b\\xd2\\xee\\xfd\\xaf\\xfa\\xd8\\xed~\\x11\\xea\\xd2}\\x9d\\xec\\x9awX\\x90\\x80!\\x97\\x92\\xa4\\xf6\\xcfn\\xff\\x00\\x95z\\xd5|\\xfb\\xe0\\x1dA\\xa2\\xd6\\x162\\xaa\\x03\\xe0\\xe0\\x12\\xbd\\x0fl\\xf5\\xfds\\xf5\\xaf\\xa0T\\x86P\\xc3\\xa1\\x19\\x15\\xe8\\xd3\\x92qM\\x1e.qG\\x92\\xbf2\\xfbB\\xd1E\\x15g\\x92\\x15\\xca\\xea~(\\xb9\\xb1\\xd4\\xee\\xacV(K-\\xdd\\xac0\\xb3\\x03\\xca\\xca@ry\\xe4\\x8c\\xfbu\\x15\\xd3\\xf9\\xb1\\x8f\\xf9h\\xbf\\x9da]\\xd9\\xf8~\\xf7P\\x12Mu\\x1b\\\\\\xb4\\x81\\x94\\xac\\xdd\\x18\\x18\\xc8\\xc7\\xe3\\x12~^\\xe6\\xa6JM{\\xa6\\xd4\\x1c\\x14\\xaf5t@5\\xadVCm\\xb1\\xac\\x94O\\xa9Oe\\xf3B\\xc7\\x01<\\xdc7\\xdf\\xff\\x00\\xa6c\\xf34\\x8f\\xac\\xddG\\x03y\\xa9i\\x1d\\xd0\\xbc\\x82&\\xb6h\\x182,\\x93l\\xdd\\x9d\\xdf6A\\x040\\xe3 \\xfe\\x1a\\x89\\xa4\\xd8'\\x93\\x87o\\xdc\\xdd=\\xdafO\\xf9h\\xfb\\xb7\\x1f\\xa7\\xce\\xdc{\\xd1>\\x8f\\xa7\\\\\\xbc\\xb2NY\\xe4\\x93g\\xcef9M\\x8d\\xbdv\\xf3\\xc6\\x1b\\x9a\\x9eY\\x1a{JW\\xdbO\\xf8?\\xe4T\\xbb\\xd4n-t[\\x8b\\xe8\\xa3\\xb7\\xf3\\xa2\\xb90 1\\x9d\\xa1<\\xe0\\x9d3\\xd7\\x1c\\xf6\\xe6\\xaa\\xddj\\xb7\\xb6\\xe7Q1%\\x8b\\xc3i4\\x11\\x06\\xf2\\x18~\\xf1\\xdc\\x06\\x1f{\\x9d\\xa8\\xeb\\xcf\\x1c\\x9fj\\xd8\\x97L\\xb1\\x97Nk\\x17v0\\xb4\\x9ec\\x1f3\\xe6-\\xbf~s\\xfe\\xf75\\x17\\xf6&\\x9c`\\x9e\\x06y\\x1a)\\xdd\\xa4t3\\x1cng\\xdeXw\\xce\\xe0\\x08=\\xa8jA\\x1a\\x94\\xd6\\xeb\\xaf\\xe1\\xa7\\xfc\\x1f\\xbc\\xce\\xbb\\xd7d\\xd3\\xaf\\x92) \\x80\\xda\\x19\\xe6\\x8d\\xf6\\xa1\\x05UcR\\xbd\\xf1\\x92N\\xde\\x9d\\xc5;\\xc3\\x9a\\xbd\\xce\\xa35\\xb8\\x9e+h\\xfc\\xed:+\\xa6\\x11!\\x18ff\\x18\\x19'\\x81\\x8f\\xd4\\xd5\\xf9t]6eU\\x95\\x99\\xf0\\xe6BZL\\x96m\\xca\\xd9?\\x8a/\\xe5\\x8a~\\x9f\\xa4\\xd8i\\x92F\\xf6\\xcc\\xc0\\xc7\\x02\\xdb\\xae\\xe93\\x84RH\\x1f\\xa9\\xe6\\x84\\xa5\\x7f u){;%\\xa9u\\x7f\\xe3\\xfa_\\xfa\\xe6\\x9f\\xcd\\xaa\\x87\\x89e0\\xf8v\\xf5\\xc7M\\x98?B@?\\xa15qdO\\xb6\\xcb\\xf3\\xaf\\xfa\\xb4\\xef\\xee\\xd5\\x0e\\xafl5\\x1d\\x1e\\xee\\xd5\\x08gx\\x88P\\x0f\\xf1u\\x1f\\xae+C\\nm)\\xa6\\xfb\\x9e7q\\xa6\\xc9\\x17\\x86\\xf4\\xed\\x80\\xf9\\xb7\\xec\\xf36{\\xe5\\x88_\\xd0\\x03\\xf8\\xd77sg*D\\x18\\xa9.\\xe3\\xe4_\\xefq\\x92~\\x82\\xbd\\x9bR\\xd1\\x91\\xb4\\xcd\\x03\\xcb\\x07m\\xbc&\\x0cm\\xec\\xd0\\x90\\x0f\\xe0\\xc0~\\xb5\\xc7\\xdeiF\\xe1\\xac\\xa6\\x852\\xabcp\\xe8\\x07\\xfb%\\xd7\\x1f]\\xa3?RMy\\xd50\\xfa\\xdf\\xfa\\xe8}>\\x173\\xbbq\\xf3\\x7f\\xab\\xff\\x00#\\xcd\\xe4\\x84\\xbc\\xe5\\x10n\\nON\\xf8\\xabVz[]\\xca\\x15\\xb2\\xaaFX\\xfa(\\xea\\x7f\\xcfz\\xd1\\xd2\\xb4\\xe3t\\xf3\\xa3K\\x141\\xc4\\x0bK,\\x8e\\x14*\\xe4\\x03\\xf9\\x9c}s]>\\x8b\\x1e\\x99,2\\xc3\\x0c\\xf1\\xc9$\\x8aW\\x03\\xa9\\x1d\\xf1\\xfc\\xbf\\xfdu\\x84a\\xd5\\x9e\\x86/\\x19\\xc9\\x17\\x18o\\xf9\\x1c\\x9cvr\\xbc\\x88\\\"\\x8c,\\x8e\\xc6O\\x9b\\x85\\x88u\\xc9\\xf6Q\\x8f\\xc7\\x8a\\xce\\xd5\\xf5\\xbb\\xfbm.\\xe0h$\\xc3ko(\\x8a\\xf3Qo\\xbe\\xd2\\x9e\\xaa\\x9e\\xe3<\\xb7\\xbf\\x15\\xea\\xf6\\xfaB\\x98\\xda8\\x90nn\\xa7\\x1f\\x8di\\xe8^\\x08\\xb1\\xb4\\xd2\\xee\\xad'\\x8b\\xe4\\x9d\\x9d\\xb6'\\x01Kw\\xfa\\xf4\\xe6\\xba)\\xa5s\\xc1\\xc4\\xe2\\\\\\x92Rz\\x7fV>}\\xf0\\xa2]\\\\jRI\\x1aen\\x89\\xb4\\xb8\\x9ev,X\\xb8;NNNz\\x1e>\\x95\\xf4>\\x95l\\xb6V0Z+g\\xca\\x8c.j\\x95\\x8f\\x82\\xa2\\xd2U%\\x99\\xd6y\\xd4\\xfc\\xad\\xb0\\x00\\xb8\\xe0}N\\x0f_\\xe5ZJ\\x8c\\x8d\\xbb$\\x92y\\xcd96\\xd6\\xa6\\x13\\xf6o\\xf8l\\xce\\xf1~\\x9d\\xfd\\xa7\\xa0\\xbe\\xd5\\x06H\\xb2\\xeb\\xf4\\xef\\x8a\\xe0\\xf4\\xed)\\xf4\\xef\\rMt!Pf\\r%\\xc38\\xff\\x00\\x96k\\xd11\\xdcq\\x9cw\\xafW8d\\x00\\xf4\\xefX\\xf7\\xd6\\xa8\\x96\\xad#F\\xa6\\xda \\\\\\xa9 \\x06\\xc0\\xce\\x0f\\xb5gmn\\\\1\\rQt^\\xd7\\xb9\\xc8i\\x13I5\\x8b\\xb3,p\\xa1M\\xe5\\xf6\\x04X\\xd7\\xb9'\\xd8s\\\\n\\xb9\\xad\\x7fj^G\\x15\\xb2\\x18\\xb4\\xd88\\x81\\x08\\xc1s\\xd0\\xc8\\xde\\xe7\\xb7\\xa0\\xad\\x8f\\x1a\\xf8\\x96K\\xd5\\x1ae\\xbbD\\x90\\x07\\\"Q\\x0ep\\xd8\\xe8\\t\\xf4\\xe3?\\x97\\xbex\\xf0N\\xc5~\\xd9\\xa9\\xa8\\xedtz\\x99e\\x05+V\\x97\\xcb\\xfc\\xcd\\xdd\\x10\\xe3U\\xb3\\x03\\xef\\x16\\xc7\\xe3\\xbb\\x8a\\xfae~\\xe8\\xc0\\xc0\\xc7J\\xf9\\x87G\\x90\\xa6\\xb3fGi\\x97\\x1f\\x9d}\\x1d\\xa0\\xeai\\xachVw\\xe8G\\xefc\\x05\\x87\\xa3\\x0e\\x18~\\x04\\x1a\\xea\\xc2;\\xc0\\xc7\\x88\\xe0\\xefN]54h\\xa2\\x8a\\xeb>d\\xa0R&\\xbbd1DT\\x0c,a\\x07'\\x00\\x92}\\xb9\\x15\\x1a\\xe8\\x1ag\\x9ae\\x92\\xd2)d'9t\\x18\\x1fA\\xd2\\xb4\\x04Q\\xac\\xad(@\\x1d\\xc0\\x0c\\xdd\\xc8\\x1d?\\x9d>\\x9d\\xfb\\x0e\\xed\\x11\\x0bku\\x00\\x08#\\x00p\\x06\\xd1A\\xb7\\x80\\x0c\\x98c\\xff\\x00\\xbeEKQ\\xcf\\x047PI\\x04\\xf1$\\xb0\\xc8\\xa5]\\x1ceX\\x1e\\xa0\\x8e\\xf4\\x85\\xeas\\xdaw\\x8a\\xb4-W\\xc4w\\x1a%\\x9ay\\x970+3H#S\\x19\\xc6\\x01\\xc3g\\x9eO\\xa5t?g\\x83\\xfex\\xc7\\xff\\x00|\\x8a\\xf3\\r\\x02\\x18\\xad\\xfe8j\\xf0\\xc1\\x12E\\x12Z\\xe1Q\\x14*\\xa8\\xdb\\x1f\\x00\\x0e\\x95\\xeau\\x9d99'~\\xe7V.\\x94)J*\\x1b4\\x9f\\xdeG\\xf6x?\\xe7\\x8c\\x7f\\xf7\\xc8\\xa3\\xec\\xf0\\x7f\\xcf\\x18\\xff\\x00\\xef\\x91Y:\\xf6\\xa9}\\xa3\\xf9W1[\\xc1=\\xa1`\\x92)b\\xb2\\x02OQ\\xd8\\x8a\\xd5\\xb6\\xb8K\\xabh\\xe7\\x8f!]r\\x01\\xea=\\x8dkm.s\\xb85\\x15.\\x84+o\\x07\\xdbe\\xfd\\xcc\\x7f\\xea\\xd3\\xf8G\\xabU\\x94\\x8a8\\xf3\\xb1\\x15s\\xe81K\\xb4n-\\x81\\xb8\\x8c\\x13\\xfe~\\xb4\\xb4\\x89\\x1b\\xe5\\xaf\\xcb\\xc7\\xdd9\\x1f\\xaf\\xf8\\xd5\\x15\\xd1\\xac\\xe2\\xfb \\x82?)m\\x8b\\xecQ\\xc8!\\xf3\\xb8\\x1c\\xf69\\xcdh\\x12\\x00\\xc98\\x02\\xb2\\xf5[\\x98\\x9e\\xc5\\xc4n$\\xdd\\x132\\xec9\\xcf\\x1c\\x10\\x7f:\\x994\\x95\\xd9q\\xe6\\xe8a\\x9f\\x04\\xd8i\\x12M\\xa8\\xd8@\\xd2\\xca\\xb2\\x99V\\x12\\x01\\xc2\\xed \\x85\\xcfq\\xb8\\x91\\xf8\\x0fz\\xf2\\x9dy\\xfcg$q\\xeaZu\\xf4\\x91\\x03<\\x90I\\x1c!@WS\\xf2\\x00\\xec\\x0b>\\xe5\\x04\\xe7\\xa7#\\x81\\xd2\\xbd\\xefN\\xd4 \\xd4`w\\x81\\xf7yo\\xe5\\xbf\\xb3`\\x1f\\xe4A\\xfck6\\xfbN\\xfbB\\xdc\\xc0\\x80ae\\x13\\x08\\xb6\\x8c7\\x00\\x82s\\xe8\\xc1\\x88\\xfaTJ\\n\\xd7\\x89\\xb4k7;\\xd5\\xd4\\x9fM\\xb7\\x86;\\x0by.\\x161rbS.\\xde\\x06\\xfcs\\xfa\\xe6\\xa7{\\xc8\\xd3\\x81\\x8a\\xe6\\xc5\\xc4\\x88|\\xa6\\x05J\\xf0sR\\xac\\xc1\\x87'\\x9a\\xe6s\\xec\\x8btz\\xb7r\\xed\\xd5\\xe7\\x99\\xc6x\\xaa[\\xf7\\xb6\\x051\\x9b4D\\x0e\\xfc\\xf6\\xac\\xdb\\xb9\\xa2\\x8aH\\x95\\x89gX\\x97\\xf8\\x8e\\x0f\\xd2\\xb8/\\x8a\\xd3L`\\xb2\\xb7\\x89\\xb1m\\x1c\\xb9\\x95\\x07s\\xb0\\xed\\xcf\\xb0\\xe7\\xf3\\x15\\xde\\xcd\\xa9\\xefX\\x9a?\\xc3\\xad\\x07R\\x83\\xed\\x11\\xdd^,\\x9dJ\\x07_\\x94\\xff\\x00\\xdf<\\xd6\\x86\\x9d\\x1cz\\x16\\xad\\x1cA\\x1d\\xc4i\\xf6k\\x8c\\x1f\\xbc\\x99\\xc8a\\xee\\x08\\xcf\\xe0k\\xbe\\x8d\\t\\xd3\\xd5\\x9e.a\\x88\\xa5\\x8b\\xa2\\xe8\\xc7\\xe2G\\xa4\\xd1U\\xed\\xe7\\xdd\\x88\\xa4`_\\x19V\\x1d$_Q\\xfd}?\\x11Eu\\x9f$X\\xa2\\x8a(\\x00\\xa2\\x8aC\\x9c\\x1cc=\\xb3@\\x1ec\\xa3\\x7f\\xc9v\\xd6\\x7f\\xeb\\xdb\\xff\\x00e\\x8e\\xbd>\\xb8{\\x0f\\x06k\\x16~2\\x97\\xc4\\x8f\\xaa\\xd9<\\xf7\\x03d\\xd1\\x0bV\\nS\\xe5\\x04/\\xcf\\x90p\\xa3\\x9ek\\xa7\\xd6\\xe1\\xd4nt\\xe7\\x83Lx\\xe3\\x9eO\\x94\\xc9#\\x11\\xb1{\\xe3\\x00\\xf3Y\\xd2\\x8bWO\\xb9\\xdb\\x8b\\x94*J\\x1c\\xb2\\xbd\\xa2\\x97\\xdc:\\xe2\\xe2\\xdeu\\x91\\x01\\x8eG^\\x06FB\\xfb\\x9f\\xc7\\xf9Uo\\r\\xb4\\xa7M\\x91dR\\xa1'q\\x1a\\x9e\\xa1z\\x8c\\xfeu\\x8b\\xa4\\xf8:\\xfa\\xda\\xe1d\\xbe\\xd4VH\\xd0\\xeeX\\xa3\\x07\\x19\\xf59\\xc6\\x7f\\x97\\xb5u\\xd0A\\x1d\\xbc+\\x14c\\n=\\xf2I<\\x92}\\xebyYh\\xb50\\x9b\\x8a\\\\\\xa9\\xdc\\x92\\x90\\x90\\xa0\\x92p\\x05) \\x02I\\xc0\\x1dM`j\\x9a\\x84D)\\x9a\\xe6KxT\\xee\\xc2m\\x1b\\xbd\\t-\\xd3\\xd7\\x18\\xac\\xa5%\\x15\\xa9\\x9cb\\xe4\\xec\\x8ek\\xc7\\x9a\\xae\\xa5\\xe4,\\x10\\x99b\\xb5\\x9d\\xb6o\\x8c\\xe0\\x93\\xfd\\xd0}\\xfd\\xfd8\\xac\\x9f\\x0e^.\\x93\\xa7\\x8bi\\xb6\\x8b6\\x94\\xb4\\x87o\\xefc\\xfe\\xf0#\\x1dA\\xf5\\xe4t\\xf4\\xadk\\xfdB9\\xaf-R\\x036\\xc3\\x91\\xber\\xfb%\\xfap\\x10\\xe3\\x1d\\xb3\\xd3=\\xab\\x9a\\xf1>\\x8b\\xa9i\\xca/mS>a\\x1c\\x01\\xbe9\\x06:g\\xfa\\x1f\\xc3=+\\x95+\\xce\\xed\\x9e\\xb5\\x19R\\x95%NJ\\xc7\\xb0\\xd8\\xc3k\\r\\x9ckf\\x13\\xc8a\\xb9J\\x1c\\x86\\xcf9\\xcf|\\xfa\\xd47o\\xf6K\\x98\\xee\\xdb\\xfdK\\x0f*c\\xfd\\xd1\\x9f\\x95\\x8f\\xb0$\\x83\\xfe\\xf6z\\n\\xf1\\xbf\\x87\\xdf\\x10\\xc6\\x95\\xab\\x7fej.\\xd1\\xe9\\xb7\\r\\x85\\x126~\\xc9!\\xf4?\\xf3\\xcc\\xfe\\x87\\xd3&\\xbd\\xc5\\x95]J\\xb0\\x0c\\xac0A\\xe4\\x11]KTyU\\\"\\xe3&\\x8e\\x13\\xe26\\xa5w\\xa0h\\xad\\xa8Z\\xd8\\xb5\\xd6>@\\x10\\xe0\\xab1\\x01K\\x1f\\xee\\xe7\\x83\\x8erG\\\"\\xb9}+U\\xd7\\xec\\xb5\\x84\\xd35\\xc4\\xb7\\x9eY\\x94\\xca\\x1a\\xd5O\\xee\\x14\\xf6b~\\xf0\\x1d3\\xfc\\xeb\\xd3.\\xac\\xcc\\x16\\xafn\\xf0\\xb5\\xd5\\x83\\x02\\xad\\x19\\x1b\\xde5=F:\\xba\\xfbu\\x1d\\xb3\\xdb\\x98\\x8b@\\xd3t\\xd9d\\xd4-d7&\\xe8mY\\x9d\\xcb\\xe1A\\xce\\x01\\xcf\\xa8\\x1e\\xfcs\\xde\\xb9\\xeaB\\xc7^\\x1a\\xa4l\\xd4\\xb5};z\\x96\\x94\\xe6\\xa57\\x11[\\xa3K+*E\\x1a\\xeewc\\xc2\\x8a\\xaf$\\xd1\\xc1\\x03\\xcd,\\x8b\\x1cH2\\xce\\xc7\\x01G\\xa9\\xae.\\xefZm\\x7fQKx\\x83.\\x9f\\x13n\\x08z\\xca\\xc3\\xa37\\xf4\\x1d\\xbe\\xb5\\x8a\\x89\\xaf-\\xdd\\x8d\\x99\\xef&\\xd7oVR\\x1a;e\\xe2\\x18\\xcfU_\\xef\\x1f\\xf6\\x8f\\xe9\\xd3\\xd6\\xacOi\\x1d\\xf5\\x9c\\xd6 \\x05\\x89\\xe2d\\x1ct\\xc8\\xc6\\x7fZ\\xc6\\xb8\\xf1&\\x8d\\xa5\\x82\\xb7:\\x95\\xb4Ex*\\x1fs~C&\\xb3\\x7f\\xe1h\\xf8f\\xdc\\xb4\\x90\\xdcMq\\xb3\\xef\\x18\\xe3\\xda1\\xff\\x00\\x02\\\"\\x8bI\\xf45s\\x84\\x15\\x93\\xd8\\xe3\\xa5\\x84\\xc2f\\x86e\\xdb L2\\xe7\\xa3\\x06 \\x8f\\xccUh\\xc3\\x06#\\xb8\\xe4}*\\xe5\\xfd\\xdc:\\xb4\\xd2j\\xb6\\x81\\xd6\\xda\\xe8\\xbc\\x88\\x1f\\x19\\x07\\xcen8\\xc8\\xe8Eh\\x9b\\x01>\\x8fm}\\x02\\xf2\\xbb\\x92P;\\x15\\x1f0\\xff\\x00\\xbe6\\xb7\\xe0\\xd5\\xcc\\xe3\\xabG\\xd4P\\xad\\xcdN5\\x1fS\\xb0\\xf0O\\x89\\r\\xbc\\xb6\\xf1J\\x0e\\xc5\\x18-\\xed\\x8c\\x7f\\x85]\\x1a\\xa1\\xfe\\xd9\\xb8\\xd4\\xa4\\x8c\\xb5\\x94\\x92yr{\\x03\\xe9\\xee0\\x0f\\xe5\\xeb\\\\\\x96\\x8b\\x11\\x8aU\\xc1\\xc0_\\x9b#\\xfb\\xbd\\x1c~\\x1d~\\x95\\xd3\\x1b\\x80t\\xeb\\x8d\\x1eX\\xd43\\xa9de\\xf5\\x07\\xaf\\xe6\\x0f\\xe9^\\x95\\x1a\\xad\\xd3\\xb3\\xdc\\xe3\\xafB\\n\\xab\\x94V\\xfb\\xfau;\\x8d?V\\xb5\\xb8&\\xc5\\xe4\\x05\\xe3\\x1b\\xe2\\x99\\x1b\\xef\\x8cp\\xcb\\xef\\xea;\\xfe4W\\x8fY\\xdf\\\\\\xe9\\xf7\\nZFP\\x8f\\xc3g\\xfd[\\x7f\\x81\\xa2\\x85T\\xe0\\xad\\x91\\xbek\\xc1\\xe8}\\x08\\x8e\\xb2\\\"\\xba0ea\\x90A\\xc8\\\"\\x9d\\\\\\x9d\\x8e\\xbbg\\xa1Yy\\x1a\\x94\\xf1\\xc1\\\"g\\xf7*\\xdb\\xc7\\xe0{T\\xd6\\x9e5\\xb2\\xbfp--\\xe6\\x95{\\x95\\x03\\x8f\\xe9\\xfa\\xd6\\x8aj\\xd7z\\x1e$\\xb0\\x95uqW]\\xce\\x9a\\x8a\\xaa.\\xdaD\\xccPH\\xc7\\xb7L~})\\xb0=\\xf9?\\xbd\\x8e ?#\\xfc\\xcd54\\xf69\\xac\\\\\\xa2\\xa9Kyq\\x04\\x8a\\x1e\\xc9\\xde2q\\xbe'S\\xb7\\xdc\\x83\\x8f\\xd35m\\x1d\\\\eNE;\\xa0i\\xa1\\xd4QX>)\\xd6-\\xb4\\xcb(\\xe2\\xb8\\x9d\\\"\\x17\\r\\x86g`\\xaa\\x10\\x0c\\xb6I\\xe9\\x9cc\\xf1>\\x94\\xde\\x80\\x95\\xdd\\x8b\\xb7\\x13Or\\xa8m\\xa3/ny,\\x08\\x1eg\\xa62~\\xef\\xbf\\x7f\\xa7_;\\xf1N\\x91\\xe3+\\x8b\\xc9\\xf5\\x08\\xeet\\x9b+8\\xe3\\xdb\\x143\\xb3\\xc8\\xf9\\xcf\\xde8\\x18\\x0cx\\x1d\\xc5r^1\\xf8\\xc7g\\xa7\\xc3-\\xaf\\x87\\x9c\\xdc\\xdft\\xfbS\\x8c\\xa2}3\\xf7\\xbf\\x95yu\\xdf\\xc4\\xdf\\x19^\\x9f\\xdfk\\xb7\\x00g%c\\n\\x8a~\\xa0\\x01\\x91\\xeck\\x1b9\\xebc[\\xa8=\\x19\\xed\\xba\\x17\\xdb\\x9fN:F\\xbdl\\xa2E`\\xb0J\\xc7tRn \\x0ezg<\\xf3\\x83\\xf9W\\xa9Zx\\x7fO\\xb3\\x08\\x129\\x1fj\\xe3\\x12L\\xee\\xa7\\x8c\\x13\\xb4\\x923\\x8e\\xf8\\xaf\\x0c\\xf8{\\xf1\\x12\\xfbZ\\x1f\\xd9:\\xe5\\xb4LY>[\\xc4\\x01\\x08\\xef\\x87\\x1d9\\xe9\\x91\\x8f\\xa1\\xafU\\xb0\\xd6>\\xc9`\\xe4jv\\xf2\\xdb\\xaa\\xe1cw\\xc4\\x8a{\\x05=\\xfd1\\xd4v\\xf4\\xa5M(\\xbb2\\xaa\\xc9\\xce)\\x9c\\xdf\\x8f\\xfe\\x1eBc}[O\\xb7\\x0e\\x88\\t\\x9a\\x15\\xfb\\xc0z\\xaf\\xaf\\xd3\\xadh|:\\xf1Qm=4\\x9dF`\\xdeP\\x02\\xdav?y;!'\\xb8\\xec{\\x8cg\\x9e\\xba\\x1a\\x97\\x8b\\xafm\\xa3\\xf2\\xb4\\xcd&\\xe6\\xf3?zRG\\xcb\\xef\\xb7\\x96?\\x95r\\xabg\\x7fs\\xbbS\\xba\\x8e(\\xecn\\xb0\\xb1\\x1f'k\\xbb\\x93\\xfc)\\xd5\\xf3\\xf4\\xf7\\xaa\\xeb\\xee\\x9a\\xc1*\\x90~\\xd1\\xaf\\xd4\\xf5\\xb5\\xb8\\x85\\xe5\\xf2\\x96T2c;3\\xce>\\x95\\x93\\xad\\xe9\\xd6\\xabo-\\xd2\\xb1\\x82f#\\x94\\x8c\\xb8\\x91\\xba\\x0c\\xa0#q\\xf7\\x04\\x1e98\\x15\\xc4\\xda\\xf8W\\xc5\\x17\\x13%\\xccS\\xa5\\x92'\\xdc\\x13\\xb6\\x18\\x0fP\\x06H\\xfa\\x13[\\x9en\\xb3o*\\xad\\xee\\xa1\\xa6^\\x18\\xb7yk\\xe7\\x18\\xd9I\\xe3'\\xe5 \\x902:\\x8e\\xa6\\x9f?I\\x18\\xca\\x11\\x8e\\xb4\\xe5w\\xe8r\\x1e,\\xb0\\x92\\xd7A\\x9fY\\xd5\\xae\\xee\\xd6\\xca&\\t\\x1c!W&A\\xbb$*\\x9d\\xaa;d\\x97?/\\\\\\x1a\\xf0\\x1dC\\xc57\\xd7RH\\xb0\\xc8\\xd1BO\\n[vG\\xb8\\xe9\\xfaW\\xb8\\xf8\\xf2\\xff\\x00\\xc4\\xff\\x00`\\xba\\xb7\\x9e\\xd5\\xbf\\xb1\\xe5\\x8c E\\x0b$k\\x81\\x80w.@'\\xdc\\xd7\\xce\\x92\\xc6\\xd1J\\xc8\\xeaU\\x81\\xc1\\x06\\xad(\\xf42\\xf6\\x93z6\\x12K$\\xa72;9\\xf5c\\x9ar*\\xf9e\\xa4b\\x17\\xb2\\x8e\\xa6\\x99\\x1co#\\x85Dg>\\x8a2jv\\xb1\\xb9\\r\\x81o>\\x7f\\xbac9\\xa6I\\xd9\\xe82=\\xcf\\xc3\\xbdAb'\\xce\\xb2\\x98\\xb7\\xd1\\x18)\\xfe`\\x9f\\xc0\\xd7s\\xf0\\xc7Q\\x8fT\\x92].r\\xaan\\x94\\x01\\xbb\\xa4W\\x0b\\xca\\x9f\\xa1\\x04\\x8fpq\\\\\\x0f\\xc3\\xbb\\x93e\\xaeOa{\\x0c\\x82\\xdbP\\x81\\xa1`\\xca@-\\x8e?B\\xc3\\xf1\\xa6\\xab\\xcf\\xa1k\\xf2[F\\xce\\x93\\xc1&\\xdc\\x83\\x82\\xeb\\x9e\\x08>\\xa0\\xd7\\x1dJ~\\xf3\\x92\\xf5=\\xfc\\x1dy{(\\xa6\\xfd\\xd7\\xee\\xfa5\\xaag\\xa6\\xdd[\\xcf\\xe1\\xedWc\\xa1X\\xd2L\\xaa\\xb1\\xce\\xdfc\\xfc\\xbd\\xf0\\x0fz\\xd0\\x9f\\x17\\xb0\\x9b\\x8bg%c\\xf9\\xd0\\xf7\\x03\\x002\\xfe\\x03c\\x0fl\\xf7\\xa8!\\xd5\\xa1\\xf1\\xbe\\x8e\\\"\\xb8`5\\xc8#\\xf9\\x1b\\xa7\\xda\\xd4\\x0f\\xfd\\x0cc\\xf1\\xc7\\xb5f\\xf8OW\\xfe\\xc7\\xd6\\x847\\x8b\\xba\\xd6S\\xe5\\xca\\xac>\\xefP\\x1b\\xea2\\x7f\\x02Ec\\xcdi'\\x1d\\x99\\xed\\xc5\\xcePm\\xaf~?\\x8f\\xa7\\xa9\\xa84\\xff\\x00\\xb7 \\xb8D\\xdeq\\x89cQ\\xd7\\xe9Ew\\x96z4:.\\xac\\x85q%\\x9c\\xe3tn\\x0e@\\xff\\x00\\xeb\\x7f\\xf5\\xa8\\xae\\x8b\\x1euL\\xd1\\xc5\\xfb\\x8a\\xe8\\xf1\\xef\\x07\\xfc<\\xf1?\\x8e$\\xfe\\xd2\\xd5'\\x9a\\xce\\xc5\\xbee\\x96`s'\\xfb\\xab\\xdc{\\xf4\\xf7\\xafS\\xb2\\xd3n\\xbc-4\\x16\\xc8\\xd1@\\xaa\\x00\\xf3<\\xb2\\xcb'\\xb9?\\xe4\\xd7\\xa2TW\\x16\\xf0\\xddB\\xd0\\xcf\\x1a\\xc9\\x1buV\\x15\\xa5JNK\\xddvg\\xcf\\xd1\\xc4:m\\xdd]=\\xcckO\\x16\\xe9r\\xde\\x0b+\\x8b\\x98\\xe0\\xba\\xe87\\x1c#\\xff\\x00\\xba\\x7f\\xa1\\xad\\xea\\xe1{D\\x95\\x0b\\xce\\xdb#w\\xc0\\x10G\\xa7H-54\\x16\\xf2\\x94\\xcd\\xb48\\xda\\xb1\\x9f\\xe2\\x00z\\x91\\x8eO'\\x07\\xf1\\xef\\xe06\\xf3\\x9f&\\xd6'\\xb89?\\\"1(\\x0f\\xbfa\\xf8\\xd6V\\x9f6\\x91\\xa2\\xda\\xed\\xbd\\x99\\xf5[\\xb6\\x18r\\xa8\\x02c\\xfb\\xb98\\xdc>\\xb9\\x1e\\xd5\\xb3\\x16\\xab\\xa8j\\x89\\x8bU[x\\x86\\x00\\x8e\\x11\\xb9\\xb1\\xdb-\\xd0\\x0f\\xc0}k(\\xc5=\\xd9\\xd3R-\\xea\\xa3e\\xdd\\x96\\xa6\\xd1\\xe4\\xc6\\xdc[F\\x08\\xfb\\xc5\\xd8\\x91\\xf4\\x1cg\\xf3\\xa94[%\\x97\\x1a\\x94\\xcd\\xe6\\xb1\\x04[3\\x0cmBrX\\x0e\\xc5\\xcf?L\\x0e\\xd5V\\xfe\\xde\\xea\\xcbK\\x9eW\\x91#2\\xed\\x85C1v/#\\x04\\\\\\x93\\xee\\xc3\\xb9\\xab:\\xd6\\xa0\\x96\\x1aq\\x8e\\x06U)\\xb56\\x83\\xd0v\\xfeUm\\xa8\\xad\\x8eu\\x079Y;\\x90kZ\\xd8\\x8841\\x9e\\x0f\\x19\\x06\\xb99&\\x12\\x02\\xdcUy$yX\\xb3\\xb1$\\xf5\\xcd0\\xf01\\\\\\x92nN\\xec\\xf5)\\xd0PV-\\xdb\\xdfMn\\xd9I\\x08\\x07\\x83\\xee*\\x03\\xa4xn\\xeaS,\\x9aU\\xa5\\xad\\xc1\\xe4\\xcb\\x1d\\xb22\\x93\\xee\\xbf\\xe0E0t\\xe9R\\xace\\x90\\x90\\x0f\\x1di\\xc6N;\\x0eta=\\xca\\x9a\\x8e\\xfd\\x1e0\\xf6Zc\\xdf\\xc3\\x8c\\x93d\\x17\\xe5\\xfa\\xa9!\\xbfB=\\xeaK-OR\\x95\\x15\\xe1\\xd0\\xe4`\\xc3 \\x1b\\x84\\xe7\\xf2\\xcd<\\x8aU@\\xbc\\x8e\\x0f\\xb5[\\xad'\\xb9\\x8a\\xc2E;\\xdc\\x8fU\\xd4n.t\\xf9\\xed.\\xb4\\xcd\\x82E\\xc0\\\"l\\x94=\\x9b\\x05GC\\x83\\xf8W\\ts(6w\\xeduj\\xb2I%\\xbbq\\xb4\\x12\\xb2(;X\\x7f\\xc0\\x878\\xf7\\xf4\\xafAvy\\x93d\\x923\\x8e\\x98c\\x9a\\xe55;3\\r\\xd1\\xdb\\x9d\\xd9\\xca\\x9f_o\\xc7\\xf9\\x8fzp\\x9bn\\xcc\\xf4pq\\x86\\xb4\\xa7\\xb4\\xbf\\x07\\xd1\\x9c&\\x9fv\\xf6\\xb3,\\xd1\\xbb\\x01\\x90\\xeaP\\xe0\\x82\\x0fP}s\\x8a\\xec.v\\xea\\xf0\\xff\\x00iB\\x17\\xed*\\xbb\\xaeQ?\\x8c\\x7f\\xcfE\\x1f\\xccv<\\xf4\\xe6]\\xbc\\xb3\\xbb\\x06E\\xfa\\xfd\\xd1N\\xbb\\xf8\\xa3\\xa1Z\\xdb\\xf9\\x1a\\x1d\\x8d\\xe6\\xb1p\\xbc-\\xae\\x99\\x07\\x98\\x01\\xf4,\\xb9Q^#\\xae\\xea\\x91i2\\xed\\xd4\\xaf\\x13_\\xd5\\x07\\xcc\\xc0\\x9c\\xd9\\xc0\\xc7\\xb2'G\\xc7\\xa9\\x18\\xf4\\x1cf\\xa9i><\\xf1\\x0c\\x1a\\xa5\\xbd\\xdd\\xbd\\xf1\\x8d\\xa1?,`~\\xec\\x0fM\\xbd1\\xed]\\x11\\xf7Q\\xc3Z\\xa2\\xa8\\xf6;}w\\xc5_\\x105\\xdd\\x7fF\\x93P\\xf0\\xc5\\xf6\\x99\\xa2\\xdbj\\x10\\\\I\\x12\\xc2\\xc7\\x85pwH\\xd8\\xe8:\\xf4\\x02\\xbb\\xcdi\\xe4:\\x95\\xcad\\x94f\\r\\xf9\\n\\xf2\\x9b\\xcf\\x18j\\x9a\\xbd\\xfc\\x97W\\xf3\\x82\\xf2\\x8d\\xb8A\\x85\\x03\\x18\\xc0\\xafQ\\x9eG\\xba\\xb0\\x82\\xf8\\xaf\\xef\\x1a\\x152\\x8fF\\xc7?\\xaek\\x1a\\xd2\\xb9\\xd1\\x84\\x87,\\x8a\\xd0C\\xbd\\xd4\\x13\\xd6\\xa7\\xb8\\xb5@\\xd8^\\xd4Y\\x95YT\\x93\\x9c\\x0c\\xd3g\\xbcV\\x9fj\\xf3\\xcf5\\xcd\\xccv\\xb5'!\\xb1\\xc3\\x96\\x02\\xb4\\xa0\\x81bC\\x91\\x9c\\xd5D\\x99K\\x0c\\x0cSn\\xaf\\xccJ\\x0ex\\x00\\xb1>\\xb8\\xff\\x00\\xeb\\xe2\\x85\\\"$\\xa4\\xf4*7\\x0c@\\xf5\\xa1T\\xf6\\xa6\\xa0\\xca\\x82jT\\x1c\\xe0U\\x16\\xc5\\x95|\\xb7\\x8c\\xf6`\\x7f:\\xc5\\xbd\\x8c\\\\\\x16\\xcf>\\x95\\xab})\\xf3\\xa0\\x84u\\x08\\xcd\\xf4\\xe4\\x7f\\x81\\xaa\\x13\\xa9R\\x00\\xed@\\xd2kS\\x9c\\xb9\\xb6Y\\x84\\x88\\xc8\\x19_!\\x90\\xff\\x00\\x17\\xd3\\xdf\\xbdb\\\\\\xda\\xf96\\xc8\\x9b\\xb7\\x85c\\xb5\\x88\\xea\\xa4\\xf4>\\xe2\\xbaMR\\x19`\\xf0\\xcc\\xfa\\x84g\\x0e\\xac]r:s\\x90\\x7f.+\\x16\\xda\\xfa\\xdfX\\xb5bP$\\xbf\\xf2\\xd2?\\x7f\\xef\\x03\\xfc\\x8d[^\\xd1y\\x9e\\xde\\x17\\x10\\xaa;?\\x89~$\\xba\\x1e\\xa6\\xb6w\\t$\\xcb\\xe6\\xc5\\xfe\\xa6\\xe6\\\"\\x7f\\xd6F\\x7f\\xaf\\x1d}@4T\\xda\\x0f\\x86\\xdfV\\xd5|\\x8f\\xb5\\xc3\\x04j7\\x17s\\xf30\\x1d\\x80\\xee\\x7fN\\xfe\\xd4TF\\x85I+\\xd8\\x8cEL4gi\\xb6\\x9f\\x95\\xd7\\xe4}\\x0fa{\\x16\\xa3e\\x15\\xd4@\\x85q\\x9d\\xa7\\xaa\\x9fCSJ]bfA\\x96\\x1c\\x81\\xeb\\xed^Y\\xa2\\xf8\\x9c\\xe9\\xd3\\xc6\\x16\\xee6\\xb7\\xec\\x8a\\xdb\\x86;\\xf1\\xfe\\x7f\\xa5w\\x16z\\xe5\\xd6\\xa4\\x8el\\xec\\x98\\xe0\\xe3q*\\x14~9\\xe7\\xea\\x05wS\\xab\\x19\\xa3\\xe5\\xf18\\t\\xd2\\x95\\xd7\\xc2mG2\\xc9\\xc7!\\xba\\xe0\\xf7\\xa9+84\\xf0\\xc2\\x1e\\xe6%\\x010Wd\\x99?O\\xba*\\xf8pFI\\x18\\xecsZ\\\\\\xe1\\x94lEum\\x05\\xc4dL\\x06\\x00?6pG\\xe3\\xfeEpZ\\xdf\\x88$\\xb2\\xb8\\x92\\xd2\\xcc\\x1b\\x8beR\\xad,\\xcf\\xb7\\xe6\\xf4\\xc6\\x0eG\\xe0?.\\xba\\x1e!\\xf1l[\\x1e\\xd2\\xc6X\\xdb\\xfb\\xf3\\x03\\xd0\\x7f\\xb3\\xeb\\xf5\\xfc\\xab\\xc7\\xb5\\xfb\\xdb\\xbd>V\\xb8\\xb7u\\x96\\xd0\\x9d\\xd3\\xc4I%\\x0f\\xf7\\xc7\\xb7\\xa8\\xfc}j^\\xbb\\n\\xf6\\xd0\\xe8\\x9f\\xc5\\x97Q\\xc8\\xfbt\\xb8\\xa5\\xe3\\x1b\\xa3\\t\\x8f\\xe4\\xa4\\xd6\\r\\xfe\\xb7\\xaa\\xea\\x10Lm!Kl\\x02Y\\xe1O\\x99FpO\\xde8\\xfa\\x8a\\xc4]~\\x01\\x13\\x9b\\x9b\\xf9P\\x9e\\x89\\x14Ls\\xf8\\x9c\\x01\\xf9U\\x8bk\\xe3\\x1d\\xaaOm)\\x8cJ\\x01\\x85\\x93\\xa8\\xe3\\x04\\xe0\\xff\\x00#\\xd6\\xb3\\x94V\\xe6\\xb0\\x93\\xb5\\x8c\\t\\xfc3qz\\x1a\\xea\\xe2\\xe2{\\x96<\\xee\\x92A\\x82~\\x80\\x92kn\\xe2\\x18\\xfc)\\xa4\\x7feY*\\xad\\xfc\\xe8\\x1a\\xfet\\xea;\\x88\\x81\\xfe\\xe8\\xef\\xeay\\xf4\\xad\\xff\\x00\\x0ei\\xafq\\x04w\\x12yP\\xa5\\xb4\\xdb\\x9b\\x00\\x90_\\xaa\\xec^\\xa4g\\x0c\\x07lb\\xa9\\xebRiVw\\xcd\\x15\\xc3[@\\xee7y\\x97\\xb2\\x02\\xcc3\\x8c\\xec\\x1c\\x0e\\xf5\\x9f=\\xdd\\x91\\xd4\\xa9(\\xc7\\x99\\x9eo,\\x12]Np\\t\\xabpY\\x18\\x06X\\x15\\xf7#\\x15\\xbf4\\xde\\x19\\x005\\xc6\\xbf\\x0b\\x13\\xfc(\\x8e\\xc0~KP\\xff\\x00j\\xf8:\\x01\\xff\\x00\\x1fs\\xccG\\xfc\\xf3\\xb7<\\xfex\\xa6\\xf9\\xdfBb\\xe9\\xc5\\xeeR\\x84)u\\xfd\\xe0\\xc0>\\xb5\\xed3\\xdc\\xcb\\x1d\\xac\\x01\\t\\xc3G\\x83\\xf8\\xff\\x00\\xfa\\xeb\\xc9\\x13\\xc5\\xbe\\x10\\x81\\x1c\\x0b\\rBg<)h\\xd0\\x01\\xef\\xf7\\xba\\xd6\\xdc\\xbf\\x18t\\x83\\x1ch\\x9a5\\xe1\\x08\\xa0s*\\xae\\x7fCX\\xce\\x8dIluQ\\xc5Q\\x86\\xb2;u\\xb8\\x91T\\x85\\xcfN\\xb4\\xeb}\\xd8,s\\xb8\\x9e\\xf5\\xc0\\x0f\\x8c\\x9az\\xe7\\x1e\\x1d\\x9f\\xdb\\xfd4s\\xff\\x00\\x90\\xe9\\x87\\xe3Z\\xaf\\xfa\\xaf\\rF\\x07\\xfbwd\\xff\\x00$\\x15\\x9f\\xd5j\\x9b\\xbc\\xc2\\x87C\\xd2\\xfc\\xc6\\x08z\\xf4\\xaa\\xd7s4\\x97I\\x17\\x1eZ\\xa2\\xbf\\xeap?L\\xfe\\x15\\xcb\\xf8W\\xc7:\\xa7\\x8a\\xef\\\\\\x9d&\\xd6\\xcfL\\x87\\xfd}\\xc9fl\\x1cp\\xa0\\xf4\\xc9\\xfd\\x07\\xe1[\\xd7\\x13'\\xf6\\x8d\\xba\\xa3\\x02$\\xb7c\\x90s\\x90\\xac1\\xff\\x00\\xa1\\x1a\\x97\\tA\\xd9\\x97\\n\\x90\\xaa\\xb9\\xa2jDAE>\\xd50q\\x1f8\\xc9\\xec*\\x94.\\xc1v\\x8a\\xb8L\\x16v\\xcdqu\\\"\\xae\\x06B\\x93\\xf37\\xd0U-E%\\xad\\x8a\\xe66\\x12\\xb5\\xc4\\xa72?\\x00z\\nMB=\\xb1\\x04^\\x1eN\\x07\\xb7\\xa9\\xac\\xc95\\xad\\xf3\\x17X\\xcc\\x84c\\xe5\\x1ft\\x0f\\xadW\\x9fV3J\\xd2\\xdd\\\\\\x8d\\xc7\\xa4P\\x00q\\xed\\xb8\\xf0?\\x0c\\xd5\\xa8\\xdfs\\xa68J\\xd3{X\\xd0\\xf1\\x1d\\xb7\\xda|<\\xda]\\xa4\\x91\\xac\\x8e\\x02\\x96s\\xc2\\x8e\\xe7\\x8e\\xbfAX\\xfag\\x86\\xb4\\x8d2#\\xf6\\xf6\\x96I\\xb6mY7ye=\\xc2\\x8f\\xfd\\x9b#\\xda\\xa5\\x8a[\\x8b\\x96\\x06\\x04\\xf2#=e\\xee\\x7f\\xe0G\\xfaV\\xad\\xa5\\x95\\x97!\\x8b\\\\>2\\xc7\\x1c\\x0f~\\x7f\\xc2\\xb6\\x84R\\xd1jn\\xb0\\xca\\x8anM\\xfc\\xbf\\xad\\x0cI-\\x96\\xc2\\xf1|\\xbb\\x85\\x96&\\xe69\\xd0`\\x1f\\xc0\\xd1R\\xea\\x1a\\x95\\xac1\\xcb\\x1d\\x9cL\\x89\\xb7/,\\xcb\\xfc\\x81\\xfe\\xbf\\x95\\x15>\\xd1#\\xae\\xcavu\\x12~\\xb6\\xbf\\xe4z&\\xbd\\xe0\\x0b6O\\xb4iQ\\x886\\xaf\\xcf\\x02\\xf48\\xfe%\\xe7\\xefz\\xfa\\xfdz\\xe5hz\\x84\\x9a\\x0b2\\xc9#m\\xe9\\xf3\\xf1\\xb7\\x1dx\\xe3\\x8fn\\xb5\\xdc\\xa5\\xf3\\xdd\\xb1X\\x95\\xd5H\\xc8 d\\xb7\\xd3\\xb0\\x1e\\xe6\\xb1\\xf5\\xdf\\x06\\xae\\xafn\\xf2E\\\"\\xdb\\xdd\\xfd\\xe5\\xc9$9\\xff\\x00l\\xff\\x00P8\\xf7\\xe9Z:i>zkS\\xe6\\xe8\\xe2\\x9a\\x8f\\xb2\\xc4\\xbb\\xa7\\xf7\\x97\\xf4\\xadv=V\\xe9\\xa2\\x1b\\x98\\x85\\r\\xc0\\x1bH=\\xc7\\xb7\\xd7\\xd3\\xa05\\x97\\xe2\\x99uY\\xdakHa\\x8a+b\\xb8i\\x1eM\\xa5\\x97\\xd0{\\x1e\\xff\\x00\\x80\\xfa\\xf2\\x0bqu\\xa1\\xdf\\x0biC\\xda]\\xc01\\x1eN2O|\\xf2\\x0eq\\xee\\x0e=\\xb8\\xed4\\xedb\\xdf\\xc4\\xf6b\\xce\\xf4\\x0b]D}\\xdfG=\\xf6\\xf3\\xd0\\x81\\xca\\xe7>\\x84\\xe34A\\xcaJ\\xcd\\xeae\\x89\\xc2(Z\\xa4u\\x83\\xea\\x8f\\x9f\\xfcM\\xe2\\xf9\\xb4\\xfd^]=\\x93\\r\\x01\\xda\\xdc\\xfa\\x7fZ\\xe4\\xe6\\xf15\\xe0\\xbd\\x12\\x87\\xca\\x9eA\\xcf\\x07\\xf0\\xafQ\\xf8\\xc5\\xf0\\xe6yb\\xfe\\xdf\\xd3af\\xba\\xb6\\x8fm\\xf4\\x0b\\xcb4c\\xee\\xca\\xbf\\xde\\x00p{\\xe0\\x0c\\xf7\\xaf\\x0bL}\\xd7\\xe1OC\\xe8kh\\xc7C\\xce\\x92I\\xd9;\\xa3^\\xf2\\xefy\\xd9\\x12b6\\xfb\\x80v\\xf6\\xab\\xf6\\x1a\\xa1\\ro\\x01c\\xe5\\xc4\\xa12:{\\xd6\\x00\\x9bh1\\xb8\\xfdjt\\x91\\xe0\\xdaI\\x0c\\x85I\\x8d\\x87C\\xebJI\\xb4\\x10\\xd1\\x9fDxb\\xdf\\xed\\x1e\\x1d\\x82\\xe9\\x14\\xacS\\xc8H\\xc62\\x14\\x1c\\x0c\\xfdq^\\t\\xe3-P\\xeb\\x1e-\\xd4.T\\x93\\x18\\x94\\xc5\\x17\\xfb\\x89\\xf2\\x8f\\xcf\\x19\\xfa\\x9a\\xf5\\xef\\x04k/{\\xe0{F\\xb79\\x92\\xd2G\\x82U\\xdd\\x802w\\x02}z\\xff\\x00\\xf5\\xea\\x1bH\\xf4\\xad\\x1fG\\xbc\\xbc\\xd3\\xb4\\xebx\\xae!}\\xe6}\\x99v\\x18\\x04\\x90\\xc7'\\x19\\xdd\\xdf\\x15\\xcdNJ\\x12wG\\xa5Z\\x0e\\xac#fy\\x1d\\x97\\x84|A~\\xaa\\xf0i7>[}\\xd7\\x91|\\xb5?Fl\\n\\xd8\\x87\\xe1\\xae\\xae\\xd8\\xfbM\\xde\\x9fm\\xea\\x1eb\\xc7\\xff\\x00\\x1d\\x04~\\xb5\\xd6\\xea\\xfe#\\x96[\\x18\\xa5\\xfbAf\\x0c\\xd9\\x19\\xe9\\x82x\\xfd+\\x96:\\xdc\\xf2\\xb1%\\xc9'\\xde\\xad\\xd6\\x93\\xd9\\x18\\xac,\\x17\\xc4\\xcd}3\\xe1$W\\xee\\xc9'\\x89\\\"\\x8c\\xa8\\xc9\\xd9l_\\xf9\\xb0\\xab\\x8d\\xf0\\x7fN\\x13\\x98\\x7f\\xe1&\\x93 \\xe0\\xb7\\xd8\\x87\\x07\\xfe\\xfeT~\\x17\\xd4.\\x17U\\x85\\xf1#F\\xff\\x00+\\x10\\t\\xc0\\xf5\\xae\\x8b\\xc4:\\xc7\\xfc#\\x1aK\\xea\\r\\x18\\x9ai\\xe7\\xdbo\\x0b67\\x93\\xc98\\xeb\\x801\\xfa\\x0e\\xf5\\x8f\\xb6\\xaa\\xe7\\xca\\x8e\\xb7\\x83\\xa1\\x1a\\\\\\xec\\xf2\\xef\\x1b\\xf8Hx;W\\xb7\\xb1[\\xf1z\\x93[\\x89\\xd6O+\\xcb\\xc6Y\\x97\\x18\\xc9\\xfe\\xef\\xafz\\xa5\\xe1\\x9f\\r_\\xf8\\xa3U[+(\\x9c\\xaa\\x8d\\xf3J\\xa8XD\\x9d\\xce\\x07S\\xe8;\\x9a\\xf6\\x7f\\nh:\\xc6\\xab\\xe2+\\x7f\\x14x\\xc3L\\x96)\\x00X,\\xad\\x92\\x12\\xa2$$\\xe5\\xf0s\\xfd\\xe3\\x8c\\xfb\\x9fJ\\xef\\xadc\\xf2|q5\\x8e\\x99i,\\x16\\xf2[2\\x99\\xca\\x92\\xa4\\x94\\xdc>lt\\x04\\x8f\\xca\\xba][i\\xd7c\\x8a8^{\\xcbef\\xfeH\\xe5t\\xeb\\xdd\\x07D\\xd1!\\xd3t\\xc61[[\\xfc\\xa42\\x1d\\xee\\xdd\\xd9\\xb8\\xe4\\x9f^\\x9d\\xbbW7\\xae]\\xe9Wn\\xb2\\xd9C4\\x17hr'\\x8d\\xf6}x\\x1ds\\xf8V\\x8d\\xef\\x87\\xe2\\x9e\\xdbS\\x92\\xd7W\\xf3\\xee\\xf4\\xe5/=\\xb4\\x96\\xcd\\x11\\xda\\x0e\\tRI\\xce=\\xc0\\xae8\\xc8O\\x03'\\xe9^t\\xa7$\\xee\\xcf\\xad\\xc2\\xe0p\\xf2\\x85\\x9e\\xb6\\xf5_\\xf0MS\\xad_\\x98V6\\xbb~\\x06\\x0b\\x0c)?\\x95D/\\xb6\\x92\\xd8.\\xfd\\xdaC\\x9f\\xd3\\xfcsY\\xccv\\xa9g`\\x8a:\\x92i\\xb3N\\x96\\xc9n\\xf2\\xeeH\\xa7l$\\xce\\x0e\\xcf\\xa9>\\x9c\\x8eiFS\\x7f\\t\\xdd'\\x87\\xc3\\xab\\xbbG\\xfa\\xfb\\xcd7\\xbb\\x9a\\xe3\\x01\\xa4;GA\\xd1G\\xe1S\\xda\\x94\\x0e\\x00\\xcc\\x8f\\xd7\\x01r\\x7f*e\\xbd\\x82J\\xd8YL\\xb8\\xea\\xcb\\xf2\\xa0\\xfa\\x1e\\xad\\xf5\\xe0}k\\xa6\\xd0\\xb4ine\\xfb.\\x9bn\\x1d\\xd7\\xe6\\x91\\xcf\\n\\x9f\\xed;v\\xfe|p\\ri\\x14\\xef\\xdd\\x98T\\xc5\\xc5E\\xcbh\\xf7z\\x11Ems2\\xef\\x99\\xfc\\x94\\xc6q\\xf7\\x9c\\x81\\xfa\\x0f\\xd6\\xae\\xf8oP\\xb7\\xd3o\\xeeZ\\xe5w\\xad\\xd4F1\\xb8\\xe7\\xcb\\x1dG\\xe2O_\\xaf\\xb5G\\xaa^[[\\x07\\xb2\\xb2\\x97\\xcf\\xed5\\xd60$>\\x88;&\\x7f3\\xcf@+\\rw\\xdcL\\\"\\x8c\\xed\\x18\\xdc\\xef\\xfd\\xc5\\xf5\\xff\\x00\\x01\\xdc\\xd6\\xf1\\x93\\x8bL\\xe4P\\xf6\\xf0s\\xab\\xa4^\\xcb\\xf5\\xff\\x00#C\\\\\\x82+\\xab\\xf0\\xf6\\xf1\\x05\\x8d\\xc2\\xfc\\x80\\xe7\\xcc\\x93\\xa6q\\xd8\\x0e\\x0f\\xd4\\x8fz*\\xe5\\xba\\xf9q\\xc7:\\xc2\\xed+\\xfc\\x96\\xf1\\xe0\\xbb1\\x1f\\xc4{\\x90=h\\xaa\\x94T\\xe4\\xe4\\x86\\xb1\\n\\x97\\xb9\\xbd\\xbb\\xb4Y\\xd1\\xd5\\x9c_@\\x16\\x85\\xee\\xe2\\xb0\\xb3\\x93%@\\x9a%\\x01\\xbdU\\x94\\x80r\\x0f\\xd0\\xfb\\x8a\\xb9K\\x13\\x0f\\x8eIz\\x9c\\x8a\\x9e\\n\\xa6\\xb4\\xa3'\\xe5u\\x7f\\xba\\xc7\\xceg\\xc1W\\\\\\x86\\xb9\\xb6\\x18\\xe8|\\xd0\\x7f\\x95`_\\xda\\xcd\\xa6^Oa1\\x04\\xc6\\xe5X\\x03\\x91\\x91\\xc6E{\\xdc\\xbaW\\x87\\x1bT\\x13\\x9d^\\xd6\\xde%;\\xb6E\\x97\\r\\xe9\\x81\\x81\\x8f\\xe5L\\xb3\\xf0\\xc7\\x82\\xde\\xf5\\x9a\\xce(\\xf5+\\xe6\\xcb\\x97\\xbb-'\\xd4\\xed\\xc0_\\xcf4P\\xc6\\xdeO\\xda\\xc9\\x0f\\x13\\x96F\\xd1xu/>n\\x9f\\x81\\xe7\\x9f\\x0bo\\xee\\\"\\xd5.t\\xb1os5\\xae\\xa1\\x17\\x97#E\\x19q\\x13\\x83\\x95b\\x00\\xe9\\xd4\\x1fc\\xed^\\x9f\\xa9ir\\xc8\\xc4\\ta\\x8a)\\xa2\\xd9\\\"\\xca\\xc0c\\xdbh\\xc9\\xfd*\\xde\\xa1t\\x9a5\\x9cKzd\\x86\\t2#\\x82\\x08\\xc2\\xaf\\x1e\\x8a0\\xb5\\x05\\xbc\\x93_\\xda-\\xcd\\x9e\\x90\\xcd\\x03gk\\xcdr\\xb1\\xee\\xc7\\x1c\\x0c\\x13\\xfa\\xd1W\\x13MN\\xfa\\xdc\\xea\\xc3`%\\x1a^\\xf3\\xbc~K\\xf1g\\x1c\\xde\\x10\\xd3 \\x81\\xa3\\xbb\\xd4.'R\\xfb\\xca\\xc2\\x81\\x07A\\xfcG>\\x9e\\x83\\xad\\x11\\xe9\\xda-\\xa6\\x05\\xa6\\x98\\x8e\\xfd\\x9aRd?\\xaf\\x15\\xbfwuom2\\xc7\\xa9\\xe9s\\xda\\x16\\xfb\\xb2\\t\\x04\\x8a\\x7f\\x11\\x8f\\xebQ\\\\\\xda(\\x08bux\\xa4\\x1b\\x95\\x90pEf\\xb11\\x92\\xdc\\xf5(`\\xe8S\\xb3q\\xf9\\xbd\\x7f\\xe0\\x0b\\xa4\\xdb\\xcdu:\\xa0\\x01W?uF\\x07\\xe4+\\x9d\\x97K\\xba\\xf1\\xcf\\xc4\\x14b\\xd2A\\xa3\\xe9\\xa7\\x0b m\\xbf*\\x9eJ\\x9fVn\\x87\\xae1\\xe9[\\x1e!\\xd6\\xc7\\x85t\\x18\\xfc\\x82>\\xdfz\\xde\\\\#\\xba\\xaf\\xf17\\xf2\\x1fSP\\\\\\xd8L5\\xabK{\\xd6`\\x92\\xaaJ\\xcb\\xb8\\x9d\\x80\\x8c\\xb0\\x1fL0\\xfc*=\\xa4\\xa8\\xc7\\x9d-\\xeerV\\x841\\xb5\\xdd\\x17+(\\xab\\xbd7=\\x02K\\xcdWQ\\xd4\\xeda\\x87P\\x91\\x97\\xccU\\xf2\\xe3\\x9f\\xa8\\xc8\\xec\\x0f?\\x05\\x195\\x8bb\\xb7\\x96z\\x8d\\xb3Z\\xc8\\xaf\\x10ddnJ\\x91\\xb8\\x10~_\\xa7Z\\xa7\\xa6iz\\x05\\x84?h\\xb6\\xd1\\x9c\\x82\\x7f\\xd6\\xcd2\\x8f\\xcb?\\x8dR\\xc4a\\xd4SW\\x93-\\xbc\\xc2\\xa5\\xe5\\xa58\\xbf5\\xd3O\\xebc\\x82\\xd1\\xf4\\xdd_Q\\xd4!\\xbb\\xbd\\x8aI-\\xd4\\xe7\\x13\\x1c\\x03\\xf4\\x1f\\xfdj\\xeb\\xed\\xb4X,\\xed\\x92k\\xe7>U\\xbad\\xeeb@\\x00}\\xecz\\xe2\\xba\\x98\\x99\\xe7\\\\\\xda\\xe8\\xef'\\xc9\\xbf)r\\x84\\x95\\xce28y\\xdb\\xfd\\xb3\\xd9Ga\\xd3\\xb9\\xed\\x8bo\\xa7\\x95e\\x17\\x01\\xcfq\\x0cC\\xf9\\xb1\\x18\\xcf\\xd0\\x11\\xef]\\xb6_\\r2hS\\x95Y\\xaa\\xd8\\xa7w\\xd2=\\xbd\\x7f\\xe0\\x98\\x9f<\\xb3$1+I,\\x87\\n\\xaa\\t,~\\x83\\x9a\\xdc\\xba\\xb5\\xfe\\xc0\\xd1\\xa3\\xb8\\xb9\\xb6\\xdf\\xe6J\\x15\\xd0J\\x03\\xe7\\x07\\x93\\xc1\\x1d\\xb0\\x07oJ\\xb3g\\xf21X|\\xbbD~\\x1b\\xcb\\x19v\\xfa\\xb7$\\xfd3\\x8f\\xa5[\\xd5\\xac\\x86\\xab\\x15\\xb6\\x83e\\x19\\xf3\\xe5q4\\xd2\\xb1\\xc9\\x8d\\x06yo\\xafa\\\\\\xf8\\xa8\\xaat\\xf7\\xd7C\\xbeU%:\\xb1\\xe7\\xd2?\\xa7{\\x92h:\\xc4z\\xbd\\xb4\\xd25\\x81\\xb4\\xb2\\x88mgY\\xb2\\xd2\\x1f\\xee\\x83\\x81\\xc7\\xe3\\x81EjE\\xa4[Z[\\xc3\\xa7\\xdb\\xa6\\xf4\\x8f\\x80:\\xe4\\xf78\\xeeM\\x14\\xa8\\xa9(\\xfb\\xda\\xbfS\\x86s\\xa3\\xcc\\xdc4]5=\\x19I\\x07c\\x1c\\x9cpq\\xd6\\xbc3\\xe2\\x1a\\xc0\\xbe:[D\\x85!\\xb6\\x8f\\xcb\\xca\\\"\\xe1r\\xdc\\xb1\\xc7\\xbe\\x7fJ\\xf5{\\xbb\\xbd/\\xc3\\x90D\\xb7Z\\x85\\xc3H\\x9c\\xc7\\x1bJd\\x91\\xc7N\\x9e\\x9d\\xb3\\xc0\\xf7\\xaf'\\xf8\\x85\\\"\\xea\\xd7\\x91k\\x90Bc\\x8d\\xc0\\x89\\xd4\\x9c\\x90G\\xdd'\\x1d28\\xfc:\\xd6\\xb9\\x82\\xbc\\x15\\xbb\\xfe\\x86\\x19\\x0cyqN_e\\xa6\\x93\\xf3.\\xf8\\xb6\\xc3Q\\xd2fW\\xbaTH\\x9c\\xfe\\xeeP\\xf9C\\xfdG\\xe2\\x07\\xe3W\\xfc0\\xb6W\\xc9\\xf6{\\xb7)\\x93\\xbd\\x1dH\\xc6}\\xb3\\xdc\\x1a\\xafay\\x0e\\xb5\\xa5%\\xd1\\x8c\\xc9(\\x8fl\\xe7\\xabo\\x1f\\xa9\\xf5\\x02\\xb1a\\xd5\\xb4\\xdby\\x19,\\xcd\\xf1br\\xf0\\xc7\\x08*~\\xaaO\\xf8\\x1fz\\xe4\\xf6\\xb4\\xa3\\xcb$\\xfdQ\\xdf\\xec\\xebJ\\x93\\xa4\\xfe%\\xd5\\x1d\\xef\\x884\\xbdg\\xec\\xe8l\\xb5{\\x8b\\xbb5\\x00\\x8bW\\xa6\\xf6oC\\x0bZ\\xbc\\xfe\\xd4\\xb3[+@&H\\xe4\\xdf%\\xc7H\\xd3\\x821\\x93\\xf5\\xff\\x00\\xf5\\xd5kh\\xae\\xe4\\x868`2%\\x95\\xb2\\x16y\\xca\\xe1q\\xcb1$\\xf4\\x1dkwA+\\xa6\\xea\\x97\\xbe\\x1f\\xb9h\\xf0\\x8ce\\xb7\\x92E\\x1c\\xaf^\\xfe\\xdc\\xfeu_\\xc6W\\xf6w\\xfao\\xf65\\xa5\\xf3Jf?\\xe9\\x1fg\\x05\\xd8\\x81\\xd1\\x07lg\\xaf=\\xb1\\xebUFP\\xbf5G\\xa9\\x18\\xb7Y\\xafcGm\\xd5\\xb7w\\xea\\xde\\x89\\x1c\\x17\\x86\\xad\\xe5\\xf1\\xaf\\x8dn\\xb5\\x99\\xd9\\x8d\\x86\\x9c\\x07\\x91\\xbf=s\\xfb\\xb1\\x8f\\xc0\\xb1\\xf7\\xae\\xd6\\xee\\x05]{N\\xf3$\\xde\\x1a\\x192\\xc4c\\x8c5C\\xa5\\xe9\\xff\\x00\\xd8\\x9e\\x16\\xfb\\x16\\x9d\\x0c\\xf0J\\xce\\xd2Hn!\\xd8\\xd27\\xb7n\\x14t\\xf6&\\xab\\xd9\\xddK\\xfd\\xb1\\xa64\\xec\\xd2K\\xb2@3\\xdc\\x9d\\xc0\\x0f\\xce\\xb5\\xc5UUcx=\\x17\\xf93\\x93/\\xa7\\xec\\xa5%5\\xef\\xb5+\\xfd\\xc6=\\xf5\\xe5\\xb6\\x9dr\\xfeZ\\xca\\xce\\xdf1\\xda\\x8c\\xe4\\x8e\\xc7?\\xd6\\xadY\\xea\\xd7W\\xd0\\xcdj\\xb6RIo$d<\\xcc\\xdc!\\xed\\x9f|\\xe2\\xa9\\xc7\\xfd\\xa3\\x14W\\xf2Cd\\xf3\\xea\\x13\\xb1U\\xbb\\x9d\\x80H\\xf8\\xc1+\\x9e\\x8cz\\x02:\\x0cs[\\xf6S\\xcd\\xa7xf\\xe1\\xae\\x961#\\xc4\\xa9\\xc3\\x13\\x99J\\x85b;u\\x05\\xabj\\x94\\xa9F\\x9bs\\x95\\xdf\\xea\\x10\\xc4b\\xaa\\xce1\\xa3\\x05\\x18\\xddl\\xbc\\xfb\\x94\\xac\\xa4\\x9e\\xe3\\xc3\\xd7V\\xd9c\\x0cD\\xb9\\x1d\\x97\\x8c\\x8f\\xfd\\x04\\xfeu\\x1f\\xf6o\\xf6\\x8e\\x9f\\x04F9\\xf2T`+&\\x0e\\t<\\x02\\xde\\xf5\\xab\\xa4Z\\x9b\\x7f\\n_\\xcc\\xfbA\\xb8\\x8d\\xd8+u\\xda\\x14\\x80G\\xe3\\x9f\\xc2\\xb2\\xaf5\\xa9\\xf4\\x8d?M\\r\\x03\\xb5\\xbc\\x91n\\x06>\\xad\\x869\\xe0\\xff\\x00\\x9f\\xadqQSu-M\\xd9\\x9d\\xf8\\xf7I\\xc6j\\xa2\\xbcy\\xd7\\x7f\\xe5\\xf2k\\xa9\\xd0K-\\xf5\\x9bA-\\x86\\x914~L\\x02\\xddB\\xc8\\x8f\\xf2\\xe4\\x1c\\x90\\x01\\xe7<\\xf4\\xefO\\xb8\\xb76\\x0b}\\xa83\\xac\\x97\\xc60\\xf23\\xb6\\xe2[\\x00c#\\x1c{q\\xf4\\xae\\x7f\\xfe\\x12\\xdd*i7C\\x7fw\\x04G\\x00$\\x88\\x0e\\x0f\\xb9\\x04~\\xb8\\xfcj\\xf6\\xa7}j\\xbe\\x1f?g\\x9d\\xa5k\\x97\\xd8\\t@\\xbf( \\x93\\xc1>\\xc2\\xb7\\xab\\n\\xd0M\\xcaW\\xe9\\xd8\\xe7\\xc3G\\x0bR\\xa4cN*\\xf7\\xf3\\xfd[3\\xa4\\xd7uYQ\\t\\xb8h f*\\x0cJ\\x10\\x0e\\x99\\xc69\\xee+\\xaf\\x92\\xdeiZ+\\x0by$d\\x03\\xfdc\\xb9b\\xfcd\\xb1?L\\x9a\\xb3\\xa9xf\\xc6\\xcb\\xe1\\xd5\\x9c7\\xd2%\\xb5\\xd0\\x1fh\\x127]\\xed\\xfc$zc\\x03\\xf0\\xaa\\x1e\\x18\\xf1\\x04p[\\xb6\\x97\\xa9K\\x1d\\xbc\\xd0.c\\xb8(\\x19\\x9a>\\xbbA'\\x1d:\\x1e\\xe2\\x95\\x14\\xa9T\\x8c\\xea\\xab&\\xbf\\xaf\\xf8'eLE:\\xb0o\\x0e\\x97\\xba\\xde\\x9f\\x93\\xf35m\\xacc\\xd1\\xac\\xc4\\xf3D'\\xbb\\x95\\xb6A\\x19<3\\x9e\\xdfA\\xd4\\x93\\xd8V\\x95\\xa0\\x87I\\xb3b\\xf2\\x87\\xba\\xb8;\\xe7\\xb8#\\x06F\\xf4Q\\xd4\\x81\\xd0c\\x81\\xdc\\x8a\\xe6\\xac5G\\xd55\\x1b\\xadS\\xcce\\xb7\\x80y\\x16\\x9ef;\\xf2\\xccs\\xc08\\xc7\\xe7P\\xc9x\\x97W\\x0c\\x91\\xdc,\\xb2\\xbf\\xde;\\xf2O\\xe7\\xce=\\xff\\x00\\xa7^\\x9a1\\xf6\\xf3ue\\xb2\\xd1/\\xd4\\xe4\\xadNr\\x97$\\x9e\\xaf\\x7f\\xf2\\xf9~}\\xf47%\\xd5e\\xbaqkd\\xcd\\x08s\\xb5\\x9d\\x0f\\xce\\xc3\\xb8\\xdc>\\xe8\\xf5\\xc7\\xd3'\\xb1Y\\xba\\\\\\xd0\\xc9\\xa8\\x9b\\x18.#\\x13\\x04/)\\xcf*\\xa3\\x1c\\x01EvA\\xdd{\\xabC\\x9eT)E\\xda\\xd7\\xf3j\\xe6-\\xd6\\xab\\xe6\\xcd#\\xc2K3\\x9d\\xcf+\\x92r}rz\\xfdM\\x16\\xb7\\xb1H\\x8f\\x04\\xeaf\\x8eQ\\xb5\\xc1\\xee*\\x80\\xb63\\xe4\\xb3,q\\xaf_\\xee\\xaf\\xd4\\xf74\\xd3\\\"\\xc5\\xf2[\\xe7\\x93\\x8d\\xe7\\xef7\\xd3\\xd3\\xf9\\xd7=k\\xcdZG\\xbf\\xec\\xa0\\xa3\\xca\\x87f\\xfb\\xc2\\x17\\xdfk\\x885\\xce\\x9b!\\x01\\xf1\\xd8z7\\xf7Xv?\\xfe\\xaa\\xeam'\\xb6\\xd4\\x0f\\xf6\\x86\\x91\\x1a\\xc9-\\xc8\\n\\xcf\\x12\\x93!?\\xdd s\\x9f_Z\\xd2\\xf0\\xaf\\x82\\xb5[\\xc8\\xd6}D\\xb5\\x95\\xa3\\x0f\\xf5L\\xb9\\x91\\xc7\\xfb\\xa7\\x85\\x1f^}\\xaa}k\\xc1\\x1a7\\x87n\\xc6\\xa3\\xa1\\xebw\\x1a\\x15\\xf9\\x1f\\xea\\xe1\\\"D\\x90\\x7f\\xb5\\x19\\xe3\\x1f\\x88\\x15\\xcb\\xf5Y\\xafy\\xaf\\xeb\\xfa\\xff\\x00\\x86<\\x1a\\xf8\\xe8*\\xbc\\x90|\\xcf\\xfa\\xfb\\xcc\\x1f\\x1cx{Q\\x83\\xc2CT\\xbb\\x84#[\\xca\\xbc\\x16\\xcb\\x84n\\x0eq\\xd0goz\\xcc\\xf1?\\x89\\xf4\\xb7\\xf0F\\x8f\\x05\\x92\\xa1\\xbf\\xbb\\x84\\x1b\\x99:\\xb2*\\xf0W\\xdb,;v\\x15\\xa7\\xe2\\x1dg\\xc5Z\\xdf\\x87\\xee4y/\\xb4;\\x88\\xa6P\\x8d>\\xd9\\\"c\\xc8=0Fx\\xac\\xaf\\x06\\xfc1\\xd7\\xe1\\xd4\\x03j\\xbaF\\x9fwa(\\xe5\\xe6\\x91\\x95\\xa3=\\x88\\x05r~\\x98\\xc5E\\xa2\\xdbt\\xd3\\xf4\\xfe\\xbc\\xcc~\\xb1R<\\xbe\\xdfK;\\xae\\xc7M\\xa3h\\xd0i\\xbe\\x1f\\xb6\\x16\\xf2\\xa8\\xb8\\x9e%\\x92bW;\\xc9\\x19\\xc6F6\\x81\\x9f\\xf6\\xbe\\x82\\xa9\\xeb\\x96WZ\\x86\\x8b%\\x84\\x16\\xad-\\xd3\\xc8\\x865G\\x0c\\x17\\x07\\x96\\xf5\\xe9\\x91\\xd3\\xbdv\\xf2i\\xba\\x1e\\x94\\xaa\\xba\\x9e\\xa2\\xa7\\xcbP\\x05\\xbc'hP:|\\xab\\x96\\xfdqX\\x97\\xff\\x00\\x12\\xb4\\x9d\\x19Z\\xd7G\\xd2\\x1b=\\xd9\\x80\\x89I\\xf5\\xe3$\\xfe8\\xae\\xb7\\x86\\xe5\\xa5i\\xbb\\n\\x95j\\xf5gz\\x11r}\\xfa\\x1c\\xdd\\xf1\\xbc\\xd2\\xfc\\x07yi}{\\x05\\xcb$k\\x12$Hw'#\\x00\\x9e\\xa7\\xf2\\x1d*\\xbf\\x84\\xae\\xd2\\xe7@\\x8by\\x969m\\xa5)\\xc7\\x1b\\x94\\xfc\\xc3\\xf0\\xe4\\x8f\\xc2\\xa3\\xd4|w\\xaaj\\xd2~\\xfb\\xc8D\\xec\\xb1\\xc48\\xfcNH\\xfc\\rI\\xa7]__\\xcc\\xa9\\xe7;)=\\x1b\\xe6\\xfeu\\xc1e\\t\\xfb\\xae\\xe7\\xa6\\xb0\\xf5\\xd4/U%\\xd4\\x9f[\\xb7\\xd3t\\xebmC\\xc4\\x9a\\xd4\\x8d\\x7f\\x14q\\xaa\\xdb\\xc1!\\xdb\\x86'\\x01x\\xc6FO\\xe5\\x9a\\xcd\\xf8y\\xa9\\x99\\xec5]wP\\x1fg\\xb0\\x85Dq\\xf9Q\\xe1s\\xd5\\x88\\x00r@\\xda?\\x1a\\xf3\\xcf\\x89~*\\xfe\\xda\\xd5\\xd7L\\xb4\\x94\\x1d>\\xc0\\x95\\x05>\\xec\\xb2\\xf4f\\xf7\\x03\\xa0\\xfcOz\\xf5\\xd6\\xd44\\xaf\\x07\\xf8r\\xd29\\x9c[\\xd8[\\xc4\\x91\\xfd\\xc2\\xdb\\xd8\\x8c\\x9e\\x06rI\\xc9\\xae\\xc7B4im\\xef3\\xc6u^\\\"\\xb3N^\\xe4~\\xe2Ak.\\xb5\\nO\\x1a\\\\A`]d\\xf3g\\xc0\\x92P\\x0eF\\xd5\\xfe\\x11\\xeey\\xf6\\xae/\\xc4\\xd7\\x8f\\x1f\\x8a\\t\\xb1\\xb7p\\xb6\\x85Uv\\xa1\\xc6\\xe0w\\x1f\\xd4\\x9a\\xe8t\\xff\\x00\\x1a\\xc6\\xc8\\x1bA\\xd0\\xf5[\\xdb\\x01\\x96d0\\x84D\\x1dI\\x8d\\x89\\xe7\\xfd\\xdc}1\\xd2\\xa0\\xb0\\xf8\\x95/\\x89$[}&=\\\"\\xc6Wm\\xaau\\x1b\\xa3\\xbc\\x9e\\xc0 Q\\x93\\xf8\\x9a\\xe0I\\xd9\\xceK^\\xa7El\\x81\\x9e\\xe2\\xb2\\x01h\\xa5\\xf3c\\x1f'\\x1eb\\x81\\xd3\\xde\\xb4\\xa3\\x17\\x18Y\\x8a\\xa5I:\\x8ew\\xdc\\xed\\xe5\\xf1T\\xa5#2YZ\\xcf\\x02\\x8e\\x0c\\x882\\xa7\\xd8\\x8eE\\x15\\xc7\\xad\\xd8\\x84\\x8c\\x03\\xf3s\\x83\\xd1\\x85\\x15m3U]\\xf7\\xfc.z\\xe5\\x8e\\x9d\\x7f\\xe2\\x0b\\xc1kg\\x06\\xed\\xbf\\xc2\\xbcG\\x18\\xf5'\\xb7\\xf3>\\xf5\\xea\\xfe\\x15\\xf0F\\x9d\\xa0\\xc5\\x1d\\xd4\\xaa.5\\x0cd\\xcc\\xe3\\x88\\xcfp\\x83\\xb7\\xd7\\xaf\\xf2\\xadk]&\\xdbH\\xb5\\x82\\xcfM\\x80E\\x12\\xe7\\x81\\xceO\\x19f=\\xcf\\xb9\\xaf4\\xf8\\x85\\xe3\\xc6\\xb8y\\xb4M&S\\xf6t\\xca\\\\K\\x19\\xe6S\\xddA\\xec\\xbe\\xbe\\xbfN\\xba5\\x1aQ\\xe6\\x96\\xac\\xdex\\x9a\\xf9\\x95EF\\x8f\\xbb\\x1f\\xd3\\xcf\\xfc\\x8d_\\x18|N\\x8a\\xc9\\xa4\\xb1\\xd1\\x1dd\\x94p\\xf7\\\\\\x15_\\xf7{\\x1f\\xafO\\xafQ\\xcai\\xde\\x1f\\xd4\\xf5\\x89\\x05\\xee\\xb5|l`\\x97\\xe7\\xdd6^i\\x87\\xaa\\xc7\\xf7\\x8f\\xd4\\xfe\\xb5\\xc7Y\\\\\\xdcY\\xcen\\x14\\xc6\\xb2\\x83\\x94b\\xb9)\\xee\\t\\xef\\xef\\xd4v\\xab\\xd1]\\xdejS2<\\xf73n9p\\xad\\x8c\\xfb\\xb1<~'5\\x8d8\\xcb\\x11/{n\\xdd\\x0f^\\x9e^\\xb0\\xd0\\xe5\\xa6\\xd4{\\xc9\\xeb'\\xe8\\xba\\x1d\\xc3\\xf8\\xa3D\\xf0\\xa9\\xf2\\xb4=/\\xed\\x17\\x8b\\xc1\\xbb\\xbdp\\xcc\\x0f\\xb0^\\x9f\\x81_\\xa5s\\xba\\xa7\\x8d\\xb5\\xfd_p\\xb8\\xd4$H\\x8fX\\xa1\\xfd\\xdac\\xd3\\x8eH\\xfa\\x93X\\x176\\xe6)X\\tcU\\xf4V\\xdeG\\xb1=\\x0f\\xe1Ic\\xa7>\\xa1t!\\x8fsaK3\\x1ev\\x81]5\\xa9F\\x9cRk~\\x8bCj\\x18L$S\\xa9nf\\xb7\\x94\\x8bI\\xac\\\\\\xfd\\x9f\\xca\\x81\\xc2\\xa8\\xee\\xab\\xfdzU\\x06/#\\x96\\x92B\\xccz\\x92sVD\\x0e\\xb7\\rl-\\xf3*\\x9c\\x1c\\x02\\xe7\\xfc)&\\xb3h\\x01\\xf3\\xa6\\x8e&\\xfe\\xe1;\\xdf\\xf2\\x1d+\\x82\\xab\\x94\\xd6\\xdbz\\x9d\\xf1\\x94#\\xb5\\xb5\\xec>\\xd2%g\\x00\\x02MZ\\xf1n\\xbd\\x1f\\x86<.\\xf0C ]N\\xf9\\x0cq\\x05\\xea\\x88xg\\xf6\\xe3 {\\x9fj\\x87NYW2*\\x96\\xc7B\\xff\\x00*\\x93\\xeei-\\xfc;\\xa6I\\xa8\\xbe\\xad\\xae\\xcb\\xfd\\xa7z\\xe7\\\"26\\xc3\\x18\\xec\\x02\\xf7\\x03\\xdf\\x8fj\\xc6\\x97*\\x974\\xf6G\\x99\\x99\\xfbj\\xb1\\xf6t\\x96\\xfd{\\x1e{\\xe1\\x9f\\x07j^!\\x9e9V\\x06\\x8bN\\x0e<\\xdb\\x99>U\\xc6y\\n\\x7f\\x88\\xfd?\\x1cW\\xb1_\\xea\\xd2$\\xc4[\\x8d\\xb1\\x81\\xb4\\x06\\xe9\\x81\\xd3\\xadV\\xbd\\xd7\\x1d\\xe3\\x11\\xc4\\x15#Q\\xb5UF\\x00\\x1e\\x80V\\x04\\xf3<\\xacK=:\\xf5\\x1dm\\xd6\\x86yvS\\xec\\x13r\\xd5\\xb3\\xa3\\x87Z\\x9eD\\x95&\\xbdt.\\x8c\\xa1\\xa2\\x03(H\\xc6F{\\x8a\\xcc\\xd3\\xadtO\\x0f\\xc5\\xb7I\\xb3>y\\xebs#n\\x95\\xbf\\x1e\\xdfA\\x8a\\xcbVU\\xfb\\xc4\\xd4\\xdf\\xdaI\\x02eQ\\x06:\\xb3\\x9c\\n\\xc7\\x97\\xa6\\xc7l\\xf0\\x14y\\xb9\\xda\\xbd\\x8d\\x02\\xfa\\x85\\xd4\\x99We\\x07\\xbb\\xf3\\xfc\\xe9\\xcfo$+\\xba{\\xb8\\x87\\xd4b\\xb9\\xf5\\xf1\\x0cW\\x97\\xf0X\\xc7|\\xa6i\\xe4X\\x91#8\\x1b\\x89\\xc0\\xe7\\xa0\\xfc\\xe9\\x9a\\x85\\xdc\\xba|j\\xff\\x00eV\\x95\\xc9\\x19\\x98\\x96\\xdaA\\xc7#\\x8e\\xe0\\xd6\\xca\\x9c\\xbb\\x19T\\xc5\\xe1\\xa9-f\\xb4\\xe8\\xb55\\x92\\xeev\\x94\\xa4Q\\xf9\\xe0wL\\x8ak\\xf8\\x86\\x1b\\t\\xc2M,p\\xcc9R\\xd2\\x83\\x83\\xef\\x8c\\xd6t\\\"\\xe7X\\xf0\\xce\\xa2g\\x92Cp\\x90\\x87\\x8f\\xcb;\\x15N\\x0e@\\x00\\x81\\xd5H\\xe8My\\xa1'\\xc8~\\xa5\\x8b\\r\\xe4\\xfe\\x83\\xf9\\xfeB\\xbaa\\x84oV\\xcf#\\x13\\x9d\\xc3\\xe1\\xa7\\x0b\\xfa\\x9e\\xc3>\\xaf\\xf6\\x19_\\xca%-.G\\x99\\t\\xceU\\x1b\\xd3>\\x98?\\x96+\\x9b\\xd4\\x9fz\\xd6\\xd3|\\xc0\\x0c$\\xc3\\xa3\\xafjqW\\xd1\\x9c\\x18\\x88\\xc5Zkf\\x97\\xc8\\xbfk\\xae\\xea~qC?\\x98\\x8d\\xf3l~A\\x1f\\xce\\xa1\\xb9\\x88\\xb3\\xbb,j\\xf6\\x92\\x9c\\xb2\\xa1\\xdc\\x10\\xfa\\x8fJ\\xcbY\\xe5\\x85\\x93\\x8c:\\x10T\\x8fJ\\xd0\\xfbl2N\\xee\\xc0\\xfc\\xc0|\\xdc\\xf1\\xfa\\xff\\x00\\x8diklc\\x16\\xadf\\xca2\\xda\\\\[\\xab\\x04r\\xf17A\\xd8\\xff\\x00\\x81\\xa1\\x1d%Vx\\xb7\\x07_\\xbc\\x87\\x82+v\\xd9<\\xb8\\xc9\\x8b3@\\xd9\\xdc\\x8f\\xce}H5\\x8f\\xadi\\xafh\\xd1\\xde[\\x0c\\xc0N3\\xddO\\xa3S\\x8b\\xe6vc\\xa9I\\xc2<\\xc8\\xa1+\\x90\\xa5\\x1b\\xb3\\x1c{\\x1f\\xf04S\\xae\\nKm\\x1d\\xcc`p\\x02H3\\xc8\\xf44V\\x91\\xd8\\xe6\\x93\\xb3=\\xf7\\xc4\\x7f\\x145-T<\\x16\\x01\\xac-O\\x1f#~\\xf5\\xc7\\xbb\\x0e\\x9fE\\xfc\\xcdp\\xbb\\xcbp\\xaa\\x14\\x0f\\xc0Pb\\xdb\\x92O\\xe2i\\x87\\xdc\\xf1^d\\xeaNN\\xf2>\\xff\\x00\\r\\x85\\xa3\\x87\\x8f-%o\\xcf\\xe6\\xc5!s\\xf3\\x1d\\xe6\\xac\\xc5\\\"\\x05\\xfd\\xfb\\xb8\\x8f\\xb4q`\\x13\\xf8\\xf4\\x1f\\x91\\xaay$\\xe1E\\\\\\xb6\\x86\\x15p\\xf77\\x1b=\\x90no\\xfe\\xb7\\xf3\\xf6\\xae\\x9a8\\x89\\xad#\\xa26\\x95\\x9a\\xb5\\x87\\xdc\\\\\\xed\\x8fl6\\xf1\\xc2\\xa7\\xfe\\x04\\xe4{\\x93\\xcf\\xe5\\xc5v?\\x0fl\\x84\\xb6:\\xb4\\xb2\\x02$dTRGnI\\xff\\x00>\\xd5\\xcd6\\xa7em\\x19[\\x0b%W\\xef<\\xc7{\\xfdFx\\x1f\\x80\\x15\\xa1\\xe1-}\\xb4\\xedRD\\xb8-\\xe5\\\\\\xe037\\x1c\\x8e\\x9dk\\xa21\\x8b\\x9a\\xa9)\\\\\\xe3\\xc5\\xd3\\xa9,<\\x94U\\xbf=\\xc3\\xc46\\x970\\xcc\\x0ce\\xd1\\xb1\\xf3\\xaa\\x1co\\x1d\\x8f\\xbd`-\\xd0A\\xb6(cC\\xfd\\xed\\xbb\\x9b\\xf5\\xaf}\\xbf\\xf0\\xbd\\xa6\\xa9\\xa6 ]\\xa2@\\x03\\xc5 \\xed\\xff\\x00\\xd65\\xe5\\xbe*\\xf0\\x8d\\xd4z\\xbd\\xbcze\\x8d\\xc3\\xc9p6\\xc9o\\x1a\\xe4\\xac\\x83\\xa9\\x07\\xa6\\xd3\\xd7=:\\xd4b\\xa9\\xc9\\xbex\\x7f^\\x87\\x16\\x032\\xa18\\xfb9\\xbb5\\xdc\\xe4\\x1e\\xe6F}\\xce\\xec\\xc7\\xd5\\x9a\\xacF\\xb7R\\xa6\\xe5\\x85\\xca\\xe3;\\x88\\xc0\\xfc\\xcdw\\xd6\\x1f\\x0eg\\xd3\\xec\\xfe\\xd9\\xacOga\\x1a\\xe38\\x06yI=\\x87@\\x18\\x9e\\x80n\\xae;\\xc4\\x96\\x90Mr\\xc29oL\\x11\\x9d\\xbeSK\\x82\\xc7\\xfd\\xa2\\xb8\\x00\\xfb\\x0e\\x9e\\xa6\\xb0Xkk'\\xa9Us\\x9a\\x11mS\\xd6\\xc6\\r\\xe6\\xa7\\r\\xa9\\\"i\\xe3R\\x06H\\x07q\\xc5f\\xff\\x00m\\xb4\\xe8^\\xd6\\xdei\\x94\\x1c\\x16\\xc0\\x02\\xbam\\x07^\\x97@\\x17\\xb62Cn\\x9a}\\xfayS\\xab\\xc6\\x18\\xa0<\\x16\\xc9\\xeb\\xc7\\x07?^\\xa2\\xb9MKK\\x7f\\x0ej\\xf2\\xc5\\x03\\x13l\\xdf:\\xa9\\xe4\\xf9g\\xbf\\xe0x\\xf6\\xe3\\xb1\\xad^\\x1e)\\x1eU\\\\\\xf6\\xbc\\xe5\\xcb\\x0fu~?\\xd7\\xc8W\\xd5\\xa1\\xba\\x84E\\x0c\\x97\\x91\\xdc\\xb3\\xf9yxTF\\x1b\\xd0\\x9d\\xd9\\x15\\xcd\\xdf\\x7fhC\\xa8H\\xb2\\xdd\\x91p\\x84\\xab)vB\\xbe\\xdf6+\\xb1\\xfb\\x0c\\x00Ez\\x80\\xcd\\x0c\\xc3e\\xc4C\\xf8\\x97\\xb3\\x0fF\\x1d\\xbf\\xfdu'\\x894km_M\\x8eHdO\\xb6\\xc2\\xbbc\\x97\\xa7\\x9c\\xbd\\x94\\xfb\\xfa~UT\\xdcb\\xf6<\\xfcD\\xebVM\\xcem\\x9eu'\\x9a\\xae\\x1d\\xd4\\xabg \\x81\\x8f\\xcb\\x15\\xed\\x97\\xfa\\x85\\xbf\\x88<5\\xa4j\\xado\\xfe\\x91%\\xb2\\x89\\x9f\\xcb\\xc0yFC\\xb7Nrr\\x7f\\x1a\\xf0\\xf6VG(\\xc0\\xab\\x03\\x82\\x0f\\x04\\x1a\\xf5]\\x1b\\\\\\x17\\xff\\x00\\x0f,m\\xb0\\x82m>F\\x83\\x00|\\xcf\\xb8\\x96\\x07\\xf5#\\xf0\\xad+h\\x939\\xb0\\xd1r\\x93\\x82\\xeaV\\xd1o\\xe1\\xd3\\xfc@\\xb1\\xb4\\xab\\x1cl\\xa4\\xbeH\\xe0\\x10p\\x01 \\xe3\\x95\\x07\\xf1\\xac\\xe84;X\\xf5;\\xb9\\xd9U\\xe0y\\x8b\\xc3\\x11\\x19\\xc2\\xe4\\xe0\\x9f\\xcf\\xa5M\\x15\\x8c_m\\x92\\xe8 \\xf3\\xdb\\x82s\\x95Oa\\xefW\\x86\\x14`~$\\xd7\\x15\\\\C\\xb7,\\x0f\\xa6\\xcb\\xf2\\x84\\xadW\\x10\\xae\\xfa/\\xeb\\x7f\\xc8\\xd1\\x81\\xa5kI\\xa6I\\x91d\\x81\\xd2@\\xaexa\\xc8 ~b\\xb9=rX\\xae\\xe0A dU}\\xae\\x0fT=\\x8duz2A=\\xf3[\\xdc\\x12\\x12h\\x99A\\xcf~\\x1b?\\xf8\\xeds\\xbe \\xb2\\x134\\xa2\\\"\\xc6H\\xc9\\x00\\x95\\xc0\\x91G\\xf5\\xefN\\x84\\xee\\x94H\\xcdh\\xdaNH\\xe6%\\x8eHeh% \\x95\\xfb\\xae9\\xe3\\xfc*\\x19_\\x18o\\x98\\x13\\xc1\\xc7@}*\\xd4q\\t0\\x0b\\x1d\\xf1\\x8c\\x8fu\\xf4\\xa8\\xe7\\x8b\\x7f\\xcd\\x12\\xff\\x00\\xbc=}\\xeb\\xa55s\\xc1k\\xb1>\\x9dz\\xf6\\xac\\x08b\\xca\\xfcq\\xfe\\x7f\\x9dt\\r%\\xbc\\xf1m\\x93r\\x87\\xfb\\xca\\xcb\\xc1\\xac-/I\\xbb\\xbfy\\x16\\xd2\\xd9\\xe5eP\\xdb\\x15I\\x0e?\\xc6\\xb4\\x90=\\xb4\\xa2'\\x0f\\x11\\xc6Lr/#\\xe9\\x9a\\x99\\xae\\xa8\\xe8\\xa3&\\x97+\\xd8\\xc7\\xd4t\\xc1f\\xc5\\xd1\\xb7[K\\xd1\\x94\\xfd\\xd3\\xfd\\xd3EhL\\xfb\\x19\\x95\\xc0x\\x1c|\\xfb\\x061\\xeeG\\xff\\x00\\xaa\\x8a\\xb8\\xcd\\xd8\\xc6tb\\xde\\x96G[#\\x03\\xd0g\\xdc\\xf4\\xa8H,y\\xe6\\xac\\x04P\\x83y\\xa4a\\x95\\xe0m_S^kM\\xea}\\xfa \\xe1{\\xd1\\xc9\\xe9\\xc7\\xd6\\x9b$\\x91\\xc6z\\xf2z\\x0e\\xa4\\xd3?}'\\x7f)\\x7f6\\xff\\x00\\x01\\xfa\\xd4\\xd8\\x1c\\xba\\x12\\x19V\\x0c1|\\x1e\\xc4\\xf5\\xfc*\\x1f:Y\\xdc,1\\xb33\\x10\\x01a\\x92I\\xe9\\x85\\x1c\\x9a\\xb3e\\xa5\\xcf\\x7f}\\x15\\x9d\\x8d\\xbb\\xcfu1\\xda\\x8a\\xbc\\xb3~'\\xa0\\x1e\\xa7\\x81^\\xed\\xe0\\xaf\\x87\\xb6~\\x19\\x8d/.\\xc2\\\\\\xea\\xa4\\x7f\\xac\\xc7\\xc9\\x0ez\\x84\\xcf\\xfe\\x85\\xd4\\xfb\\x0e+\\xa2\\x8d9T\\xf4<\\xac\\xc31\\x8e\\x15Y\\xfc]\\x97\\xea\\xc7|8\\xb3\\xf1-\\x8e\\x82\\xb0\\xeb\\xc5\\x04`\\x7f\\xa3\\xc6\\xff\\x00\\xeb\\x95}\\x1b\\xb0\\x1e\\x83\\xa8\\xef]5\\xf0\\x84\\x04\\xb8\\x966V\\x80\\xeeI@\\xce\\xdf\\\\\\xe3\\xb7\\xadG\\xa8\\xeb\\x96:`e\\x9aM\\xf3(\\xcf\\x93\\x17\\xcc\\xf8\\xf5=\\x94{\\xb1\\x03\\xde\\xbc\\x93\\xc5\\xdf\\x10u\\x7f\\x13\\x1b\\xbd\\x17\\xc3v\\x8am`\\no\\xa7I\\x03\\x1c\\x1c\\xe22\\xc7\\n3\\x82\\x08\\x19\\xe0\\x1c\\x1e\\xb5\\xe8\\xa6\\xa0\\xads\\xe3e9U\\xa8\\xea[s\\xa7\\xd6\\xb5{{\\x9dov\\xa5s\\xe4C\\x13yp\\xc6\\x8c\\x1b\\xcb\\x07\\xac\\x9f\\xef\\xb78\\xfe\\xea\\xfb\\x93\\x8ek\\xc6\\xfe!\\xf0\\x9f\\xf6|Vz\\xf5\\xe6\\x16v\\xd3^\\xdc\\xc7m\\x00\\xcb9\\xfc\\x07\\xb9\\xaf^\\xb5Xm\\xbc+\\x0c\\x1b\\x9ei\\xadXC#9\\xce\\xe4a\\x95\\xc8\\xfe\\xefP>\\x95\\xd3Z1\\x85\\xb9O\\x03\\t:\\xd8\\x95)\\xd5\\xd57\\xbf\\x9fc\\xce\\xe6\\xb7\\xdd!\\x90(V\\x03-\\x8e?Jd^`\\x0f\\xb1\\x19\\xb2\\xa0\\x10\\xa35\\xb1\\xac\\xdaD\\xd7(\\x9ayb%P]\\x0f\\xf0\\x9fJ\\xec<-\\xe1\\xcf\\xec\\xebU\\x92\\xe1w\\xdd\\xbfS\\xd7g\\xb0\\xf7\\xad\\xa8\\xd3uv9\\xdd6\\xa6\\xe2cx;\\xc2\\xba\\xdc\\xfa\\x84R\\xf9\\xadc\\x16C\\x9d\\xc4\\x83\\x80y\\xe0v#=i\\xbe4\\xb8D\\xf1t\\xd6\\xdbH\\x82(\\xd1\\x10\\x9e\\xa4\\x7f{\\xf1\\xc9\\xafR\\xb4\\xb6\\x95Q\\xe3D*\\xb8\\xcc\\x8e}\\x05x\\xa7\\x8a.\\xa5\\xbd\\xf1E\\xe4\\xb7\\x00.\\xc9<\\xa5\\nz\\x058\\x1f\\xe7\\xde\\xba+B0\\xa7\\xca\\x89\\x95\\xe0\\xf43\\xaee\\x8a&\\xda\\xec\\xdbs\\xf2\\x9c\\xe0\\xfe\\x07\\xfa\\x1a*\\xbc\\xb1\\x19<\\xb8\\xdd\\x81l\\xe0\\xafq\\xefEr+[S6\\xe6\\xde\\x88\\xef\\x03md]\\xac\\xf29\\n\\x8a\\x01,\\xc4\\xf4\\x00\\x0e\\xa6\\xadk\\x1ae\\xee\\x99r\\xb6\\xd7\\x8c\\x91O\\xb04\\x90\\xa9\\xdc\\xd1\\xe7\\x90\\x1b\\xb08\\xe7\\x1c\\xf5\\x1f\\x87m\\xe0\\x9d\\x11\\xf4(\\xe2\\xd7\\xa7\\xb2[\\xcb\\xdb\\x91\\x9bQ#\\xff\\x00\\xabS\\xd1\\xb1\\x8e\\xa7\\xb7L\\x0f\\xadU\\xd643,o$\\xbb^\\xeeY\\x0bM+\\xf5c\\xc985\\x9cp\\x92t\\x9c\\x8f\\xa8\\xfe\\xd1\\xe6\\xc4\\xaa{G\\xf3\\x7f\\xe4\\xbf\\x1fC\\x84HR1\\xbb\\x1dzg\\x92}\\xcd[\\xb0\\xd3\\xeeu+\\xb8\\xadmai\\xae&m\\xb1\\xc6\\xbdX\\xff\\x00@:\\x93\\xda\\xa6\\xbe\\xb0{i#\\xf38\\xde7/\\xfb\\xbe\\xb5\\xd1\\xe9\\x1a\\xee\\x9b\\xe0\\x93\\xe6\\x1b\\xe4\\xba\\xd4\\xa5\\x03u\\xbd\\x94a\\x8ck\\xd7c\\xca\\xd9\\x03\\xdc(\\xce{\\xf0+\\x9e\\x14\\xbd\\xef{c\\xa3\\x1f\\x8e\\x8e\\x16\\x95\\xe1\\xac\\x9e\\xc8\\xf4\\xef\\x08\\xf8J\\xc7\\xc1\\xfa~\\xf9\\x99$\\xd4g\\x00M>:\\xff\\x00\\xb0\\x9d\\xf6\\x8f\\xd7\\xa9\\xf4\\x0f\\xf1\\x17\\x88#\\xb1\\xb3\\x91\\xa7\\xbe\\x82\\xc21\\xff\\x00=\\xa4\\xda\\xc7\\xfe\\xf9\\xcb\\x0f\\xa0\\xc7\\xfb\\xc2\\xbc\\xc7S\\xf8\\x87\\xaf\\xeb\\x92\\x8b[8\\x1e6\\x91r#\\xb6\\xc88\\xf7n\\xb8\\xf5\\xed^W\\xe2X\\xe4\\xb4\\xbc\\x90Oz\\x93\\xdf0-/\\x97&\\xe5\\x88z\\x13\\xd3w\\xd0\\xd7zzr\\xc7C\\xe2*Js\\x93\\xa9SW\\xd5\\x9d7\\x8c~'\\xc2c{\\x1d\\x1d\\x1aF\\xc9\\xcc\\xf2 H\\xd4\\xfa\\xac`\\x9c\\x9f\\xf6\\x9c\\xb1\\xfck'M\\xf1]\\x96\\x91\\xe18t\\xe8#\\xba73\\x96\\x9e\\xeaf\\n\\x03\\xc8\\xdf\\xf0,\\x90\\x14\\x01\\xf9\\x9e\\xf5\\x89\\xe0O\\x0fE\\xe2?\\x12\\x84\\xbbR\\xda}\\xacmqu\\x83\\x82\\xca8\\x0b\\xc7L\\xb1Q\\xf4&\\xb4\\xbcCec\\xb2v\\xb7\\xb2\\x86\\x14G\\n\\x85\\x17\\x19'\\xff\\x00\\xac*\\x954\\xb4\\x12\\x9c\\xad\\xcd\\x7f#\\x95\\xbd\\xbd\\xfbe\\xdb\\xc8\\x18\\xe0\\x9e3R[\\xdb$\\x80,\\xaa\\n\\x9a\\xa9\\xf6@\\xec@%iB\\xddZ6\\xe8\\xd8\\x95\\x1e\\x9c\\x8f\\xca\\xad\\xf6F(\\xd0m6\\xe2\\xcd\\xfc\\xeb\\x19\\xb7\\x1e\\xe8\\x7f\\xcf5cO\\xd4D\\xf7jdo\\\"\\xe9\\x184d\\xf4\\x0e\\x0eF?\\x1a\\xa9o\\xac\\x03\\x810\\xda}GJ\\xd5\\xb7\\xd3!\\xd7\\n\\xc4\\x81wc>p\\xfe\\x01\\xdc\\x93\\xe9YI\\xb5\\xf1\\x1b\\xd3\\x87<\\x94a\\xab}\\x0e\\xfb_\\x8e;\\xdb\\xeb]R\\x03\\x1a%\\xd5\\xb2\\xcb1n|\\xacz\\x8fS\\xd0}\\x0f\\xa5a$B\\xf5\\x99\\x89t\\xb4V\\xe4\\x83\\xf3J\\x7f\\xba?\\xcf\\x03\\xf0\\x15\\xa5a\\xa7\\xda\\xdc\\xe8\\xce \\xb8e\\xb6\\xb3\\x94&\\x1cd\\xc80\\ts\\xeb\\xcb\\x00\\x07\\xaf\\xb7J\\xf2\\xc8\\x91\\xa8X\\xd7h\\x03j \\xfe\\x11\\xe9\\xf5=\\xcf\\xf9\\x1c\\x95\\xe7\\xa9\\xf4\\x99~\\x16)r\\xc7o\\xb4\\xfb\\xf9/.\\xfd\\xc8\\xa5\\x00\\xb60\\xa0\\x7fuz\\x0fj\\xa1\\xa9j\\x90i\\xb1\\xaf\\x98\\xc3\\xccs\\x85_\\xea}\\xa9\\x9a\\xb6\\xab\\x16\\x95\\x06_\\x0fp\\xe3\\xe5O\\xf1\\xf6\\xae\\x0e\\xe6\\xe6k\\xcb\\x86\\x9ew,\\xecy540\\xee\\xa3\\xe6{\\x1d\\x19\\x9ej\\xb0\\xb1\\xf6T\\xb5\\x9f\\xe5\\xfdv;\\xcdme]6dFO\\xb2\\xdc2\\xb4\\x0cW2I\\xf2\\x8c\\x9c\\xf6\\x1d\\x7f>(\\xf0=\\xca\\xca\\xd3iNK\\x89\\x95\\xe2e\\xe4\\x8d\\xa5K\\x03\\x8e9\\x18~\\xbe\\xb5=\\xac\\xff\\x00n\\xf0n\\x9b\\xa9\\x85\\x0f\\xf6=\\xd6s\\x81\\xd5x\\x01[\\xf2\\xdb\\\\\\xff\\x00\\x87\\x1ehu\\xfd\\xe8\\xcaX+;q\\xecT\\x1f\\xfcz\\xba\\xe3jw\\xbfC\\xe7\\xaa)\\xd7\\xa9\\x15\\x17w-\\x0bzu\\x9cz\\x05\\x8c\\xf7s\\xa8\\xf3\\x8ex'\\x903\\xc2\\xff\\x00\\x9f\\xe9Sx\\x0e\\xf5\\xb5\\x1dr\\xfa\\xce\\xeeo\\x9bQ\\x88\\xec\\xc9\\xc0\\xf3S\\x0c\\x9f\\xa0#\\xf1\\xac\\x9f\\x16^3\\xdcGh\\xa4\\x85A\\xbd\\xbd\\xc9\\xff\\x00\\xeb\\x7f:\\xcf\\xf0\\xfc7\\x17:\\xed\\x84V\\xa4\\x89\\xbe\\xd0\\xae\\x18\\x7f\\x0e\\x0es\\xf8b\\x95*nqr\\x96\\xf2\\xfe\\x91\\xbe;\\x10\\xa9V\\x86\\x1e\\x8f\\xc3O\\xf1}OQ\\xd0t\\xa6\\x9fYv+\\x9d\\x83\\xfdY\\x1c\\x86\\xcf\\x03\\xf9\\xd7\\xb8\\xe8\\x1e\\x13\\x82\\xd2\\xd1%\\xbbP\\xd7\\r\\xce?\\xbb\\xed\\\\%\\x83\\x05\\xd4\\xc4\\xab\\x19V\\x92M\\xcd\\xe5\\xaf\\xcc\\xc7\\xdb\\xdf\\xb5z\\xc5\\x84s\\xf9\\x08\\xf7*\\x11\\xb1\\xf2\\xc4\\x0eB\\x0fs\\xdc\\xd7di\\xba4\\xd4z\\x98ck6\\xfd\\xdd\\x0c=V\\xda \\xafim\\x18P\\xbf4\\xcc?0\\xbf\\xd4\\xfe\\x1e\\xb5\\xf2\\xde\\xb5\\x8b\\x8dN\\xf5\\xe3P\\xdek\\xb3u\\xe9\\xc9\\x1f\\xe7\\xeb_Rx\\xdfW\\xb4\\xf0\\xef\\x85\\xaf\\xaeX\\xaa\\xcf*4p\\xafvv\\x18\\xcf\\xf5\\xaf\\x96%\\xb7d\\x06V\\x1c\\x87$\\xb6q\\xc1\\xff\\x00\\xeb\\x8f\\xd6\\xb1\\xad+\\xa4\\x88\\xa4\\xdc\\xa3\\xb1V\\xddY%\\x95X\\x86\\xd87g\\x1c\\x95\\xf4\\xa2\\xa3\\xbb\\x97d\\xbb\\xd7\\x91\\xb5A\\xe3\\xa8\\xc5\\x15\\x87-\\xca\\xf6\\x9c\\xba#\\xec\\x8d:;Qi\\x04\\x8d\\x1a\\xaf\\xee\\xc0@G;}q\\xdb?\\xe1^\\x7f\\xe3;\\x9bXn\\xbc\\x88\\xce\\xf9K\\x17\\x91W\\xf8FO\\xf5\\xaa\\xff\\x00\\xf0\\x92\\xeaV\\xd6l\\xe9(i$_\\xbe\\xe3%~\\x9d\\x85r\\x12M$\\x973\\xca\\xee\\xcc\\xef\\xcb\\x12z\\x93\\xcdu\\xd5|\\x8b\\x97\\xb9\\xe9e\\xb8\\tJ\\xb3\\xaa\\xde\\x8b\\xa1\\xc6x\\xc7U\\x96R, '\\xcd\\x98\\x82\\xfbz\\x81\\xfc*>\\xb5\\x7f\\xc3>\\x17\\x87B\\xb0\\x1a\\x8f\\x8a\\xef\\x1a\\xd6\\x069\\x8e\\xc6<\\x19\\\\\\xfa\\x1f\\xee\\xfd\\x07>\\xb8\\xae\\x87B\\xd3\\xedm|-7\\x8a\\x84\\t&\\xaad\\x91Q\\xe4\\x19X\\xc0\\xfe\\xe8\\xecO\\xafZ\\xf3H/'\\xbeIond2NX\\xe0\\xb1\\xc8P{\\x01\\xda\\xb9>$\\xe2\\x8e,m\\x7fi_\\xda\\xcb\\xd1.\\xc9\\x1d\\xaf\\x88\\xfch\\r\\x97\\xd9\\xb4\\xbbe\\xb0\\xb19\\xfd\\xda\\xe0;\\xfao=\\xcf\\xe2k\\xcd\\xf5+\\x9e<\\x859c\\xcc\\xad\\xea}?\\n\\xd3\\x8e\\x11;\\xdb\\xbc\\xae\\xceL\\x80`\\x9e1YW\\xd1\\xab\\xea\\xf2\\xc7\\x8c(8\\x00}+jQIhy\\x95$\\xe4\\xf5=?\\xe1\\xbd\\x87\\xd8<\\x0b\\x7f\\xa8\\xb7\\xcb.\\xa3r!\\x8c\\xf4>\\\\c'\\xf0,\\xc3\\xfe\\xf9\\xab\\xbe<\\xd3\\x86\\x9do\\xa7i\\xa4\\r\\xe2\\xdf\\xed\\x13\\x0cr$~p~\\x8a\\x14V\\xdf\\x86ma\\x7f\\n\\xf8V\\xd0\\xa0\\x10\\xbc*YGr\\xd2\\xb6k3\\xe2<\\xee\\xfe-\\xd5\\x19\\xb0v\\xbe\\xd1\\xec\\x00\\x00\\x7f*Qwl\\xd2Q\\xb4\\x12<\\xa9\\xe2\\x119\\x00\\xf3P3\\x8d\\xd8\\xe8i\\xf7n\\xdfho\\xadC\\x17\\xcd\\x92y5M\\x18\\xa68Y\\x8b\\x97T\\x11\\x92\\xccp1\\xd6\\xb6\\xfc\\xab\\xabK8\\xb4M\\x16#-\\xd4\\xf2(\\x9d\\xd4e\\xa4bp\\x10{s\\x8aM%BZ\\xdc\\xdc\\x01\\xfb\\xc8\\xd4\\x05>\\x99\\xef]\\x1f\\x83\\xe3\\x11=\\xe5\\xead\\\\D\\x80F\\xdf\\xdd\\xdd\\xc1#\\xdf\\x19\\x1f\\x8ds\\xcaz\\xbb\\xec\\x8f[\\x0fG\\x96\\x11P\\xf8\\xaau\\xec\\xb6\\xfb\\xdf\\xe4i^\\xc2t\\xcbh\\xf4\\xb5tf\\x88\\x07\\xba\\x96?\\xbb$\\xb8\\xc1\\xc7\\xa8\\x1c\\xaa\\xfe'\\xbdc\\xdc\\xcem\\xa1\\x92q\\x13;\\xaa\\xe4(\\x19\\xda=Mh;\\x19e\\xf9\\xf9\\xf9w\\x9fs\\xc5k\\xf8ESV\\xf0\\xbe\\xad\\x05\\xca/\\xde\\xdc$A\\x87\\x07` \\xe7\\xd8\\xf4\\xaexR\\xe7\\x93m\\x9e\\xe6*\\xba\\xc0a\\xe3\\x18-v_\\xe6x\\x95\\xf5\\xcc\\xb7w\\x92M)%\\xd8\\xf7\\xaa\\xf5\\xa7x\\xabqg\\xf6\\xd6EYL\\x9b[`\\xc0n3\\x9cz\\xfd+7\\x15\\xe9A\\xabh|uK\\xb97'v\\xce\\xdb\\xc1\\x97\\x89k\\xe1\\xedXJ\\xae\\xe9#*\\x88\\xc0$7\\xca\\xdb\\xbf\\x1f\\xbb\\xf9T>\\x1cE\\x96\\xfa\\xf2\\xe4#*\\xecEM\\xde\\x87'\\xfaU\\xbf\\x87\\xc4\\xbd\\xa5\\xfa\\x12v\\xa4\\x91\\x90=\\xd9_?\\xfa\\x08\\xad\\x1bx#\\x8a\\xff\\x00P\\x080<\\xc58\\x1fL\\xd7\\x05y\\xd9\\xce>\\x87\\xd1e\\xb4\\xb9\\xa5B}\\x15\\xff\\x00S\\x9d\\xf1\\xde\\x9alu[y\\x94f)\\xe0R\\x18\\x03\\x82G\\x07\\xaf\\xbf\\xf3\\xa9\\xfe\\x1aC#\\xf8\\xa3\\xcdP<\\xb8\\xa1b\\xe4\\xaez\\xe0\\x00=\\xf3\\xfc\\xabS\\xc5\\n\\xb7\\xbe\\x08\\x82\\xe2e\\x06X$\\x01\\x18u\\xc1\\xe3\\x19\\xfc\\xbf!\\\\\\x04\\x177\\x16\\xe1\\xc4\\x13\\xcb\\x10q\\x86\\x08\\xe5w}q\\xd6\\xbd\\x1am$\\x99\\xe0\\xceMVr\\x96\\xf7>\\xb0\\xf0\\xd3\\xd8X]\\x1b\\xab\\xdb\\xebX\\x1d\\x17;$pd\\x03\\xfd\\xde\\xd5.\\xbd\\xf1\\x7fA\\xd2\\xf6\\xc5e\\xbe\\xf2i\\x1bj66\\xc6\\x0f\\xb9<\\xfe\\x95\\xf3\\x87\\xc3\\xb9\\xdd|e\\ngr\\xcf\\x14\\xb1\\xc9\\x9e\\xe3a?\\xcc\\n\\xe8o\\xed\\xe3\\xb8\\x17K*\\xee\\x03\\x91\\xec@\\xcei\\xcanrf\\xb2JpU_{X\\xbf\\xe3o\\x13_k\\xd2\\x89o_s\\xbf\\x08\\xa3\\x85U\\xe7\\x80+ \\\"\\x8bdI\\xe3!\\x19x\\xc1\\xfc\\xff\\x00\\xcf\\xd2\\xa94\\xcd\\xf5\\x8e|C\\xa8\\xebs\\xac\\x11\\xc5=\\xcc\\xbd\\x00\\x1b\\x9c\\xff\\x00\\xf5\\xab\\x17\\x89\\x85\\xec\\x8f^\\x9eE]\\xc7\\x9a\\xabQG\\xb5\\xcf\\xe2]\\\"\\xdc\\xe2[\\xd5C\\xe8T\\x8f\\xe9L\\x1e*\\xd1Y\\x0b\\x8b\\xcf\\x90us\\x13\\xed\\x1f\\x8e1^k\\xa7x^T\\xb5\\x96\\xe3Ug\\xb7\\x08\\xdbvn\\x19\\x07\\xb7\\xaf'=1\\xf8\\x8a\\xba\\x12\\xc2\\x08e\\x8e\\xce\\x18\\xe0\\x9d\\x81\\x90M7\\xefxNJ\\x90F\\x01#q\\x1dy\\\\V\\x8am\\xee\\x8eZ\\xd8|-=!''\\xe5k\\x1e\\x95o\\xabi\\xd7k\\x9b{\\xfbi@\\xeb\\xb2U8\\xfa\\xf3\\xc5[\\x040\\x04\\x10A\\xe8Eyq\\x96\\xfe\\xca\\xdcI&\\xa9y\\xbd\\x9c:)\\x9fo\\x00r\\x02\\xe0\\x0cr\\xbcs\\xd3\\xebV\\xf4\\xdd`4\\xcc-5Ky[\\x0c\\xff\\x00tn\\xc7^X\\x00}\\x8f4\\xf9\\xd1\\xc7\\xec[\\xd8\\xf4z+\\x9d\\xb7\\xd7\\xaeax\\x9a\\xee%\\x92\\xdaP1$\\x7fyO\\xd3\\xf8\\x94\\xfa\\x8e{`\\xf5\\xae\\x81\\x1dd\\x8ddF\\x0c\\x8c\\x01VS\\x90G\\xa8\\xaaN\\xe6N-n:\\x93r\\x97)\\xb8n\\x00\\x123\\xc8\\x07\\xff\\x00\\xd4ik3S\\xb7\\xba]\\xf7zz\\x03x\\x14\\x05\\xc9\\x18p\\t\\xf9[$q\\xcd48\\xab\\xbb\\x1atS!wxQ\\xe4\\x8c\\xc6\\xe5Ad';OqE\\x04\\x95\\xaf\\xb4\\xd8\\xaf\\x8cr\\x12c\\x9e,\\xec\\x91z\\x80z\\x83\\xea\\x0f\\xa5Q\\xddqc)3 \\x00\\x90\\x03\\xaf*\\xdf\\xe1\\xf4?\\x86kj\\xab^\\xdd\\xdaZ\\xc0\\xc6\\xeeX\\xd2\\xd8\\xa9M3\\x86P\\x94U\\xd8\\xeaBB\\xa9bp\\x00\\xc94\\xb4S \\xe5\\xe4\\xd5\\xafu)\\x9e+(\\xe5XK`8R\\t\\x1e\\xbc\\xf4\\x15\\xa9\\xa4\\xe8\\xe9\\xa7\\x97\\x99\\xf0\\xd3\\xb8\\xc1=v\\x8fL\\xd6\\xa5\\x15M\\xf65\\x95W\\xcb\\xcb\\x15d\\x15\\x14\\xf7\\x11\\xdbDd\\x95\\x82\\xa8\\xfdi\\xf2H\\xb1F\\xce\\xe7\\n\\xa3$\\xd7\\x96\\xf8\\xa7_\\xbe\\xd6uq\\xa5X\\xa34e\\xbc\\xb6\\n~\\xf9\\xfe\\xe8>\\x9e\\xa7\\xfa\\x0eq\\xa9QA\\x1a\\xe10\\xb2\\xc4N\\xcbD\\xb7d\\x9e&\\xf1\\xd9\\xba\\x94\\xdai\\xc4\\x14\\x07\\r \\xe4\\x0fe\\xf5>\\xfd==k\\x81\\xbf7w&{\\xb9\\\"*\\xa0\\xf2\\xeey'\\xde\\xbb\\xe4\\xf0\\xcd\\xbf\\x87\\x83\\xc9r\\x8b$v\\xf1\\x19\\xe6\\x95\\xbf\\xe5\\xa3c\\x0b\\x12\\xfbf\\xb9\\x1dJ\\xf6)t\\xbf\\xb3;\\x86y.\\x01\\x94\\xaf\\x038$\\xfe\\xa7\\x1f\\x85q\\xd4\\x8bz\\xcd\\xea}V\\x03\\xd8\\xc1r\\xd0W]\\xceNx\\x9d$*NN3\\x9a\\xf6/\\x0e[\\xe8\\xfa\\x1f\\x86\\xe2\\xbc\\xb4Y\\x0b_D\\x8c\\xe7v^S\\x8c\\xec\\x1e\\x83\\x9eH\\xc6>\\xb5\\xe5\\xd1\\x08\\xe4\\xb9\\xdapA\\xb7\\x07\\xf1\\xc8\\xafI\\xf0Lp^xb\\xcak\\x953J\\x8ab]\\xfd\\x15\\x03\\x1c\\x00*(5\\x196Fv\\xdc\\xe9E_K\\x8c\\x9c\\xdd]\\xdc\\xad\\xcc\\xc1\\x19\\xd03*\\xe3\\t\\x12\\x01\\x92\\x00\\xf4\\xed\\xef\\x9e\\xf5\\xcb\\xf8\\x8f\\xc4\\x11YJ\\xd6vq\\xee\\xc6w)\\xfb\\xa9\\x91\\xc0nrN\\x0f?\\xd2\\xbd\\x1fT\\xb7W\\xd3\\xae`\\x81@i\\xd8D\\x0fp\\xa7\\x03\\xfa\\x93\\xf5\\xaf)\\xf17\\x87\\xa4\\xd3nd\\x17\\x03t\\x8cKo'!\\xf2z\\xd6\\xb5k8\\xad\\x0f'/\\xc2\\xd2\\xadS\\x96\\xa3\\xd3\\xb7s\\x1a\\xff\\x00\\xc4Z\\x86\\xa2\\xf0\\xcbqq\\xb4\\xc2\\n\\xaf\\x92J\\x0eq\\x9e\\xfe\\xc2\\xa8\\xc52(\\xd8\\xae\\xa63\\xfc9\\xfb\\xbfJh\\x0c\\x9c\\x18\\xd3i\\xee\\xa7\\x15\\x03G R\\xa0\\xa3.~^q\\x8f\\xa7\\xbdrs9=Y\\xf4\\xf0\\xa5\\x1a*\\xd0\\x89\\xd2\\xe8\\xda\\xd5\\xcd\\xa11G9Ul\\x06S\\xca\\xb6\\x0ey\\x07\\xe9\\xd6\\xbd\\xa7\\xc1z\\xb2\\xdd\\xdb4\\x1b\\xf2\\x0edE'\\x95k\\x88_ \\xce#'\\x93\\xb9r\\t#\\xa5u^\\x1d\\xf1u\\xdd\\x94\\xd1\\xb0\\x90\\xc3w\\x1b\\xa3'\\x98G\\x96\\xdd\\xb6\\x96\\x1d\\xfa\\x8f\\xa37#\\x15\\xd1Br\\x84\\xac\\xde\\x87\\x93\\x98\\xe1\\xa1\\x88\\x872\\x8d\\xa5\\xe9\\xf9\\x9fKQU4\\xcdB\\x1dSO\\x86\\xf2\\x03\\xf2\\xca\\x81\\x8a\\xe7\\x95$g\\x07\\xdf\\x9a\\xb7^\\x89\\xf2\\x8d4\\xec\\xc2\\x8a(\\xa0G=w\\xafMqx\\xb6Z\\\\{\\x99\\xb3\\xfb\\xe2\\xa4\\x8f\\xc0z{\\x9f\\xfe\\xbdGm\\xe1A3\\x99\\xf5Y\\xda\\xe2F9(\\x0e\\x07\\xe2\\x7f\\xc3\\xf5\\xad\\xcb+\\x08,!\\xf2\\xe0\\\\g\\xef9\\xfb\\xcc}I\\xab5<\\xb7\\xd5\\x9d_Y\\xe4\\\\\\xb4t\\xf3\\xeaA\\x15\\x9d\\xb4\\x16\\xc6\\xda\\x18#\\x8e\\x12\\x08(\\xab\\x80s\\xd6\\x8b;8,-R\\xda\\xd96D\\x9furO\\xeajz\\xc0o\\x12\\xa5\\xac\\xcd\\r\\xe4-\\xe6\\x03)a\\x16\\x0e\\xd0\\x8a\\x1b\\xa9<\\xe5Nr>\\x98\\xcd6\\xd21\\x8a\\x9c\\xee\\x96\\xa6\\xec\\x91\\xac\\x88Q\\xc6A\\xaa\\xd0~\\xeegC\\xd4u\\xff\\x00hz\\xfe\\xb5\\x15\\xbe\\xaf\\x1d\\xc5\\xc4p\\xfd\\x9a\\xe23\\\"\\xb3#8\\\\\\x15^\\t\\xe1\\x8fC\\x81\\xff\\x00\\x02\\x15@\\xf8\\x85F\\x825\\x07\\x84\\x19wF\\xbeW@K\\x85n\\x0ey\\xc2\\xb6\\x7f\\x0e\\x82\\xa5\\xb5\\xb9Q\\xa7?\\x86\\xc6\\xfd\\x15\\x94u\\x95yf\\x8e\\x18\\x1c\\xaaE$\\x8b+\\x15\\xda\\xc56\\xf4\\xc1\\xce>a\\xe9Ri\\xda\\xbcZ\\x84\\x86$\\x86TuR\\xccX\\x0cp\\xc5{\\x13\\xdd[\\xf25\\\\\\xc8\\x87NI^\\xc5\\xd1!7\\x0f\\x1e8UV\\xcf\\xd4\\x9f\\xf0\\xa9*\\x15\\xff\\x00\\x8f\\xe9\\x7f\\xeb\\x9a\\x7f6\\xa7\\xcd*A\\x0c\\x92\\xc8p\\x88\\xa5\\x98\\xfb\\x01\\x9ad\\x18\\xfa\\xfd\\xe2Gg2\\x17e\\x00m\\x1bN\\x0b1\\x1d\\xbe\\x80\\x8f\\xc4\\x8fJ\\xe4<4,\\xecc\\x96\\xf8,b`\\xdeE\\xbe\\xe6\\xc8\\xcfV?@9\\xff\\x00\\xf5\\xd6]\\xf7\\x88\\x0e\\xaa/\\xe5\\x9fr-\\xb1\\\"\\x05S\\xc0ry$\\xfex\\xf6\\xc5r/\\xacO\\xe4\\x88\\x84\\x8c\\xa8\\xb9\\n\\x07\\x18\\xcf_\\xce\\xb8jWJWG\\xd4a2\\xe9\\xfb\\x17M\\xbb^\\xd7\\xfe\\xbf\\xae\\xa7G\\xe3\\x7f\\x11\\t\\xe2\\x8e\\xde\\t\\x8b\\xc4O\\x9as\\x9c\\xff\\x00\\xb2\\x0f\\xd7\\xef}My\\xf3]3[$y;\\x83\\x16'\\xdf\\xaf\\xf5\\xa7\\xde\\\\<\\xf2\\x96f$f\\xaa\\xa8\\xe8?\\x1a\\xe3\\x9c\\xdc\\x8f{\\x0fB4`\\xa1\\x12h\\xe4o5\\x88<\\x84\\xc0\\xf6\\xafa\\xf8v\\xa1|+n\\xac:\\xe5\\x87\\xe3\\xcf\\xf5\\xaf\\x1e\\xb7\\xc9\\x86w\\nw0\\n\\xbe\\xf9\\xe7\\xf9W\\xa9h\\xfa\\xd4zE\\x94:]\\xac_j\\xbbT\\x00\\xa2\\xb6\\xd5\\x8c\\x00\\x06]\\xbf\\x84q\\xf5\\xf6\\xab\\xa7\\xa6\\xe7\\x97\\x9b'R\\x11\\x8c<\\xd9\\xd6\\xf4\\xb8#\\xa8\\x1c\\xd6g\\x88\\xf4\\xd8\\xf5\\xad9\\xa3\\xc9YT\\x13\\x19\\xf7\\xf45\\x93\\xaax\\x8e-4\\xabj:\\xc5\\xb5\\xbb\\xb0\\xfb\\x8a\\x02\\x0f\\xc3y%\\xbe\\xa0\\n\\xdc\\xd3\\xddn\\xad!\\x966.\\x8c2\\x18\\xf7\\x15\\xa5\\xae\\xb5<(\\xb7NJI\\xea\\x8f\\x0c\\xd4,\\x8d\\xbd\\xc3#\\xc6\\xe9\\\"\\x9ev\\x9cV|\\xa9\\xc2\\x92d\\x05{\\xe3\\x07\\xf2\\xef^\\x95\\xf1\\x03G\\x16\\xd7\\x82\\xe2$\\xc2J7c\\x19\\xf9\\xbb\\xd7\\tm\\xa4\\xdcj\\xb7igm\\x17\\x9b3\\xe4\\x85\\xe0`\\x0e\\xa4\\x92p\\x00\\xeeM`\\x93R\\xe5>\\x9e\\x15\\xa3R\\x87\\xb5\\xe9\\xd4\\xcct_0\\x91<\\x88\\xec\\xa3;[$\\x8fR=}\\xe8+9\\x03\\x0c$S\\x9e\\x18`\\xaf\\xb7\\xb9\\xae\\xd6\\xc7\\xc0\\xdaL\\xaa\\x9fi\\xd5\\xa2\\x9eA\\x9c%\\x94~`\\x07\\xbe$b\\x01\\xfa\\x81Q\\xdc\\xe9:\\x1e\\x9a\\xb2\\xcbmou,p\\x8c3K8\\x08\\x0ep\\x00T\\x03\\x93\\xf5\\xad\\x94\\x19\\xc6\\xf1\\xb4\\x9b\\xd2\\xee\\xfd\\xaf\\xfa\\xd8\\xed~\\x11\\xea\\xd2}\\x9d\\xec\\x9awX\\x90\\x80!\\x97\\x92\\xa4\\xf6\\xcfn\\xff\\x00\\x95z\\xd5|\\xfb\\xe0\\x1dA\\xa2\\xd6\\x162\\xaa\\x03\\xe0\\xe0\\x12\\xbd\\x0fl\\xf5\\xfds\\xf5\\xaf\\xa0T\\x86P\\xc3\\xa1\\x19\\x15\\xe8\\xd3\\x92qM\\x1e.qG\\x92\\xbf2\\xfbB\\xd1E\\x15g\\x92\\x15\\xca\\xea~(\\xb9\\xb1\\xd4\\xee\\xacV(K-\\xdd\\xac0\\xb3\\x03\\xca\\xca@ry\\xe4\\x8c\\xfbu\\x15\\xd3\\xf9\\xb1\\x8f\\xf9h\\xbf\\x9da]\\xd9\\xf8~\\xf7P\\x12Mu\\x1b\\\\\\xb4\\x81\\x94\\xac\\xdd\\x18\\x18\\xc8\\xc7\\xe3\\x12~^\\xe6\\xa6JM{\\xa6\\xd4\\x1c\\x14\\xaf5t@5\\xadVCm\\xb1\\xac\\x94O\\xa9Oe\\xf3B\\xc7\\x01<\\xdc7\\xdf\\xff\\x00\\xa6c\\xf34\\x8f\\xac\\xddG\\x03y\\xa9i\\x1d\\xd0\\xbc\\x82&\\xb6h\\x182,\\x93l\\xdd\\x9d\\xdf6A\\x040\\xe3 \\xfe\\x1a\\x89\\xa4\\xd8'\\x93\\x87o\\xdc\\xdd=\\xdafO\\xf9h\\xfb\\xb7\\x1f\\xa7\\xce\\xdc{\\xd1>\\x8f\\xa7\\\\\\xbc\\xb2NY\\xe4\\x93g\\xcef9M\\x8d\\xbdv\\xf3\\xc6\\x1b\\x9a\\x9eY\\x1a{JW\\xdbO\\xf8?\\xe4T\\xbb\\xd4n-t[\\x8b\\xe8\\xa3\\xb7\\xf3\\xa2\\xb90 1\\x9d\\xa1<\\xe0\\x9d3\\xd7\\x1c\\xf6\\xe6\\xaa\\xddj\\xb7\\xb6\\xe7Q1%\\x8b\\xc3i4\\x11\\x06\\xf2\\x18~\\xf1\\xdc\\x06\\x1f{\\x9d\\xa8\\xeb\\xcf\\x1c\\x9fj\\xd8\\x97L\\xb1\\x97Nk\\x17v0\\xb4\\x9ec\\x1f3\\xe6-\\xbf~s\\xfe\\xf75\\x17\\xf6&\\x9c`\\x9e\\x06y\\x1a)\\xdd\\xa4t3\\x1cng\\xdeXw\\xce\\xe0\\x08=\\xa8jA\\x1a\\x94\\xd6\\xeb\\xaf\\xe1\\xa7\\xfc\\x1f\\xbc\\xce\\xbb\\xd7d\\xd3\\xaf\\x92) \\x80\\xda\\x19\\xe6\\x8d\\xf6\\xa1\\x05UcR\\xbd\\xf1\\x92N\\xde\\x9d\\xc5;\\xc3\\x9a\\xbd\\xce\\xa35\\xb8\\x9e+h\\xfc\\xed:+\\xa6\\x11!\\x18ff\\x18\\x19'\\x81\\x8f\\xd4\\xd5\\xf9t]6eU\\x95\\x99\\xf0\\xe6BZL\\x96m\\xca\\xd9?\\x8a/\\xe5\\x8a~\\x9f\\xa4\\xd8i\\x92F\\xf6\\xcc\\xc0\\xc7\\x02\\xdb\\xae\\xe93\\x84RH\\x1f\\xa9\\xe6\\x84\\xa5\\x7f u){;%\\xa9u\\x7f\\xe3\\xfa_\\xfa\\xe6\\x9f\\xcd\\xaa\\x87\\x89e0\\xf8v\\xf5\\xc7M\\x98?B@?\\xa15qdO\\xb6\\xcb\\xf3\\xaf\\xfa\\xb4\\xef\\xee\\xd5\\x0e\\xafl5\\x1d\\x1e\\xee\\xd5\\x08gx\\x88P\\x0f\\xf1u\\x1f\\xae+C\\nm)\\xa6\\xfb\\x9e7q\\xa6\\xc9\\x17\\x86\\xf4\\xed\\x80\\xf9\\xb7\\xec\\xf36{\\xe5\\x88_\\xd0\\x03\\xf8\\xd77sg*D\\x18\\xa9.\\xe3\\xe4_\\xefq\\x92~\\x82\\xbd\\x9bR\\xd1\\x91\\xb4\\xcd\\x03\\xcb\\x07m\\xbc&\\x0cm\\xec\\xd0\\x90\\x0f\\xe0\\xc0~\\xb5\\xc7\\xdeiF\\xe1\\xac\\xa6\\x852\\xabcp\\xe8\\x07\\xfb%\\xd7\\x1f]\\xa3?RMy\\xd50\\xfa\\xdf\\xfa\\xe8}>\\x173\\xbbq\\xf3\\x7f\\xab\\xff\\x00#\\xcd\\xe4\\x84\\xbc\\xe5\\x10n\\nON\\xf8\\xabVz[]\\xca\\x15\\xb2\\xaaFX\\xfa(\\xea\\x7f\\xcfz\\xd1\\xd2\\xb4\\xe3t\\xf3\\xa3K\\x141\\xc4\\x0bK,\\x8e\\x14*\\xe4\\x03\\xf9\\x9c}s]>\\x8b\\x1e\\x99,2\\xc3\\x0c\\xf1\\xc9$\\x8aW\\x03\\xa9\\x1d\\xf1\\xfc\\xbf\\xfdu\\x84a\\xd5\\x9e\\x86/\\x19\\xc9\\x17\\x18o\\xf9\\x1c\\x9cvr\\xbc\\x88\\\"\\x8c,\\x8e\\xc6O\\x9b\\x85\\x88u\\xc9\\xf6Q\\x8f\\xc7\\x8a\\xce\\xd5\\xf5\\xbb\\xfbm.\\xe0h$\\xc3ko(\\x8a\\xf3Qo\\xbe\\xd2\\x9e\\xaa\\x9e\\xe3<\\xb7\\xbf\\x15\\xea\\xf6\\xfaB\\x98\\xda8\\x90nn\\xa7\\x1f\\x8di\\xe8^\\x08\\xb1\\xb4\\xd2\\xee\\xad'\\x8b\\xe4\\x9d\\x9d\\xb6'\\x01Kw\\xfa\\xf4\\xe6\\xba)\\xa5s\\xc1\\xc4\\xe2\\\\\\x92Rz\\x7fV>}\\xf0\\xa2]\\\\jRI\\x1aen\\x89\\xb4\\xb8\\x9ev,X\\xb8;NNNz\\x1e>\\x95\\xf4>\\x95l\\xb6V0Z+g\\xca\\x8c.j\\x95\\x8f\\x82\\xa2\\xd2U%\\x99\\xd6y\\xd4\\xfc\\xad\\xb0\\x00\\xb8\\xe0}N\\x0f_\\xe5ZJ\\x8c\\x8d\\xbb$\\x92y\\xcd96\\xd6\\xa6\\x13\\xf6o\\xf8l\\xce\\xf1~\\x9d\\xfd\\xa7\\xa0\\xbe\\xd5\\x06H\\xb2\\xeb\\xf4\\xef\\x8a\\xe0\\xf4\\xed)\\xf4\\xef\\rMt!Pf\\r%\\xc38\\xff\\x00\\x96k\\xd11\\xdcq\\x9cw\\xafW8d\\x00\\xf4\\xefX\\xf7\\xd6\\xa8\\x96\\xad#F\\xa6\\xda \\\\\\xa9 \\x06\\xc0\\xce\\x0f\\xb5gmn\\\\1\\rQt^\\xd7\\xb9\\xc8i\\x13I5\\x8b\\xb3,p\\xa1M\\xe5\\xf6\\x04X\\xd7\\xb9'\\xd8s\\\\n\\xb9\\xad\\x7fj^G\\x15\\xb2\\x18\\xb4\\xd88\\x81\\x08\\xc1s\\xd0\\xc8\\xde\\xe7\\xb7\\xa0\\xad\\x8f\\x1a\\xf8\\x96K\\xd5\\x1ae\\xbbD\\x90\\x07\\\"Q\\x0ep\\xd8\\xe8\\t\\xf4\\xe3?\\x97\\xbex\\xf0N\\xc5~\\xd9\\xa9\\xa8\\xedtz\\x99e\\x05+V\\x97\\xcb\\xfc\\xcd\\xdd\\x10\\xe3U\\xb3\\x03\\xef\\x16\\xc7\\xe3\\xbb\\x8a\\xfae~\\xe8\\xc0\\xc0\\xc7J\\xf9\\x87G\\x90\\xa6\\xb3fGi\\x97\\x1f\\x9d}\\x1d\\xa0\\xeai\\xachVw\\xe8G\\xefc\\x05\\x87\\xa3\\x0e\\x18~\\x04\\x1a\\xea\\xc2;\\xc0\\xc7\\x88\\xe0\\xefN]54h\\xa2\\x8a\\xeb>d\\xa0R&\\xbbd1DT\\x0c,a\\x07'\\x00\\x92}\\xb9\\x15\\x1a\\xe8\\x1ag\\x9ae\\x92\\xd2)d'9t\\x18\\x1fA\\xd2\\xb4\\x04Q\\xac\\xad(@\\x1d\\xc0\\x0c\\xdd\\xc8\\x1d?\\x9d>\\x9d\\xfb\\x0e\\xed\\x11\\x0bku\\x00\\x08#\\x00p\\x06\\xd1A\\xb7\\x80\\x0c\\x98c\\xff\\x00\\xbeEKQ\\xcf\\x047PI\\x04\\xf1$\\xb0\\xc8\\xa5]\\x1ceX\\x1e\\xa0\\x8e\\xf4\\x85\\xeas\\xdaw\\x8a\\xb4-W\\xc4w\\x1a%\\x9ay\\x970+3H#S\\x19\\xc6\\x01\\xc3g\\x9eO\\xa5t?g\\x83\\xfex\\xc7\\xff\\x00|\\x8a\\xf3\\r\\x02\\x18\\xad\\xfe8j\\xf0\\xc1\\x12E\\x12Z\\xe1Q\\x14*\\xa8\\xdb\\x1f\\x00\\x0e\\x95\\xeau\\x9d99'~\\xe7V.\\x94)J*\\x1b4\\x9f\\xdeG\\xf6x?\\xe7\\x8c\\x7f\\xf7\\xc8\\xa3\\xec\\xf0\\x7f\\xcf\\x18\\xff\\x00\\xef\\x91Y:\\xf6\\xa9}\\xa3\\xf9W1[\\xc1=\\xa1`\\x92)b\\xb2\\x02OQ\\xd8\\x8a\\xd5\\xb6\\xb8K\\xabh\\xe7\\x8f!]r\\x01\\xea=\\x8dkm.s\\xb85\\x15.\\x84+o\\x07\\xdbe\\xfd\\xcc\\x7f\\xea\\xd3\\xf8G\\xabU\\x94\\x8a8\\xf3\\xb1\\x15s\\xe81K\\xb4n-\\x81\\xb8\\x8c\\x13\\xfe~\\xb4\\xb4\\x89\\x1b\\xe5\\xaf\\xcb\\xc7\\xdd9\\x1f\\xaf\\xf8\\xd5\\x15\\xd1\\xac\\xe2\\xfb \\x82?)m\\x8b\\xecQ\\xc8!\\xf3\\xb8\\x1c\\xf69\\xcdh\\x12\\x00\\xc98\\x02\\xb2\\xf5[\\x98\\x9e\\xc5\\xc4n$\\xdd\\x132\\xec9\\xcf\\x1c\\x10\\x7f:\\x994\\x95\\xd9q\\xe6\\xe8a\\x9f\\x04\\xd8i\\x12M\\xa8\\xd8@\\xd2\\xca\\xb2\\x99V\\x12\\x01\\xc2\\xed \\x85\\xcfq\\xb8\\x91\\xf8\\x0fz\\xf2\\x9dy\\xfcg$q\\xeaZu\\xf4\\x91\\x03<\\x90I\\x1c!@WS\\xf2\\x00\\xec\\x0b>\\xe5\\x04\\xe7\\xa7#\\x81\\xd2\\xbd\\xefN\\xd4 \\xd4`w\\x81\\xf7yo\\xe5\\xbf\\xb3`\\x1f\\xe4A\\xfck6\\xfbN\\xfbB\\xdc\\xc0\\x80ae\\x13\\x08\\xb6\\x8c7\\x00\\x82s\\xe8\\xc1\\x88\\xfaTJ\\n\\xd7\\x89\\xb4k7;\\xd5\\xd4\\x9fM\\xb7\\x86;\\x0by.\\x161rbS.\\xde\\x06\\xfcs\\xfa\\xe6\\xa7{\\xc8\\xd3\\x81\\x8a\\xe6\\xc5\\xc4\\x88|\\xa6\\x05J\\xf0sR\\xac\\xc1\\x87'\\x9a\\xe6s\\xec\\x8btz\\xb7r\\xed\\xd5\\xe7\\x99\\xc6x\\xaa[\\xf7\\xb6\\x051\\x9b4D\\x0e\\xfc\\xf6\\xac\\xdb\\xb9\\xa2\\x8aH\\x95\\x89gX\\x97\\xf8\\x8e\\x0f\\xd2\\xb8/\\x8a\\xd3L`\\xb2\\xb7\\x89\\xb1m\\x1c\\xb9\\x95\\x07s\\xb0\\xed\\xcf\\xb0\\xe7\\xf3\\x15\\xde\\xcd\\xa9\\xefX\\x9a?\\xc3\\xad\\x07R\\x83\\xed\\x11\\xdd^,\\x9dJ\\x07_\\x94\\xff\\x00\\xdf<\\xd6\\x86\\x9d\\x1cz\\x16\\xad\\x1cA\\x1d\\xc4i\\xf6k\\x8c\\x1f\\xbc\\x99\\xc8a\\xee\\x08\\xcf\\xe0k\\xbe\\x8d\\t\\xd3\\xd5\\x9e.a\\x88\\xa5\\x8b\\xa2\\xe8\\xc7\\xe2G\\xa4\\xd1U\\xed\\xe7\\xdd\\x88\\xa4`_\\x19V\\x1d$_Q\\xfd}?\\x11Eu\\x9f$X\\xa2\\x8a(\\x00\\xa2\\x8aC\\x9c\\x1cc=\\xb3@\\x1ec\\xa3\\x7f\\xc9v\\xd6\\x7f\\xeb\\xdb\\xff\\x00e\\x8e\\xbd>\\xb8{\\x0f\\x06k\\x16~2\\x97\\xc4\\x8f\\xaa\\xd9<\\xf7\\x03d\\xd1\\x0bV\\nS\\xe5\\x04/\\xcf\\x90p\\xa3\\x9ek\\xa7\\xd6\\xe1\\xd4nt\\xe7\\x83Lx\\xe3\\x9eO\\x94\\xc9#\\x11\\xb1{\\xe3\\x00\\xf3Y\\xd2\\x8bWO\\xb9\\xdb\\x8b\\x94*J\\x1c\\xb2\\xbd\\xa2\\x97\\xdc:\\xe2\\xe2\\xdeu\\x91\\x01\\x8eG^\\x06FB\\xfb\\x9f\\xc7\\xf9Uo\\r\\xb4\\xa7M\\x91dR\\xa1'q\\x1a\\x9e\\xa1z\\x8c\\xfeu\\x8b\\xa4\\xf8:\\xfa\\xda\\xe1d\\xbe\\xd4VH\\xd0\\xeeX\\xa3\\x07\\x19\\xf59\\xc6\\x7f\\x97\\xb5u\\xd0A\\x1d\\xbc+\\x14c\\n=\\xf2I<\\x92}\\xebyYh\\xb50\\x9b\\x8a\\\\\\xa9\\xdc\\x92\\x90\\x90\\xa0\\x92p\\x05) \\x02I\\xc0\\x1dM`j\\x9a\\x84D)\\x9a\\xe6KxT\\xee\\xc2m\\x1b\\xbd\\t-\\xd3\\xd7\\x18\\xac\\xa5%\\x15\\xa9\\x9cb\\xe4\\xec\\x8ek\\xc7\\x9a\\xae\\xa5\\xe4,\\x10\\x99b\\xb5\\x9d\\xb6o\\x8c\\xe0\\x93\\xfd\\xd0}\\xfd\\xfd8\\xac\\x9f\\x0e^.\\x93\\xa7\\x8bi\\xb6\\x8b6\\x94\\xb4\\x87o\\xefc\\xfe\\xf0#\\x1dA\\xf5\\xe4t\\xf4\\xadk\\xfdB9\\xaf-R\\x036\\xc3\\x91\\xber\\xfb%\\xfap\\x10\\xe3\\x1d\\xb3\\xd3=\\xab\\x9a\\xf1>\\x8b\\xa9i\\xca/mS>a\\x1c\\x01\\xbe9\\x06:g\\xfa\\x1f\\xc3=+\\x95+\\xce\\xed\\x9e\\xb5\\x19R\\x95%NJ\\xc7\\xb0\\xd8\\xc3k\\r\\x9ckf\\x13\\xc8a\\xb9J\\x1c\\x86\\xcf9\\xcf|\\xfa\\xd47o\\xf6K\\x98\\xee\\xdb\\xfdK\\x0f*c\\xfd\\xd1\\x9f\\x95\\x8f\\xb0$\\x83\\xfe\\xf6z\\n\\xf1\\xbf\\x87\\xdf\\x10\\xc6\\x95\\xab\\x7fej.\\xd1\\xe9\\xb7\\r\\x85\\x126~\\xc9!\\xf4?\\xf3\\xcc\\xfe\\x87\\xd3&\\xbd\\xc5\\x95]J\\xb0\\x0c\\xac0A\\xe4\\x11]KTyU\\\"\\xe3&\\x8e\\x13\\xe26\\xa5w\\xa0h\\xad\\xa8Z\\xd8\\xb5\\xd6>@\\x10\\xe0\\xab1\\x01K\\x1f\\xee\\xe7\\x83\\x8erG\\\"\\xb9}+U\\xd7\\xec\\xb5\\x84\\xd35\\xc4\\xb7\\x9eY\\x94\\xca\\x1a\\xd5O\\xee\\x14\\xf6b~\\xf0\\x1d3\\xfc\\xeb\\xd3.\\xac\\xcc\\x16\\xafn\\xf0\\xb5\\xd5\\x83\\x02\\xad\\x19\\x1b\\xde5=F:\\xba\\xfbu\\x1d\\xb3\\xdb\\x98\\x8b@\\xd3t\\xd9d\\xd4-d7&\\xe8mY\\x9d\\xcb\\xe1A\\xce\\x01\\xcf\\xa8\\x1e\\xfcs\\xde\\xb9\\xeaB\\xc7^\\x1a\\xa4l\\xd4\\xb5};z\\x96\\x94\\xe6\\xa57\\x11[\\xa3K+*E\\x1a\\xeewc\\xc2\\x8a\\xaf$\\xd1\\xc1\\x03\\xcd,\\x8b\\x1cH2\\xce\\xc7\\x01G\\xa9\\xae.\\xefZm\\x7fQKx\\x83.\\x9f\\x13n\\x08z\\xca\\xc3\\xa37\\xf4\\x1d\\xbe\\xb5\\x8a\\x89\\xaf-\\xdd\\x8d\\x99\\xef&\\xd7oVR\\x1a;e\\xe2\\x18\\xcfU_\\xef\\x1f\\xf6\\x8f\\xe9\\xd3\\xd6\\xacOi\\x1d\\xf5\\x9c\\xd6 \\x05\\x89\\xe2d\\x1ct\\xc8\\xc6\\x7fZ\\xc6\\xb8\\xf1&\\x8d\\xa5\\x82\\xb7:\\x95\\xb4Ex*\\x1fs~C&\\xb3\\x7f\\xe1h\\xf8f\\xdc\\xb4\\x90\\xdcMq\\xb3\\xef\\x18\\xe3\\xda1\\xff\\x00\\x02\\\"\\x8bI\\xf45s\\x84\\x15\\x93\\xd8\\xe3\\xa5\\x84\\xc2f\\x86e\\xdb L2\\xe7\\xa3\\x06 \\x8f\\xccUh\\xc3\\x06#\\xb8\\xe4}*\\xe5\\xfd\\xdc:\\xb4\\xd2j\\xb6\\x81\\xd6\\xda\\xe8\\xbc\\x88\\x1f\\x19\\x07\\xcen8\\xc8\\xe8Eh\\x9b\\x01>\\x8fm}\\x02\\xf2\\xbb\\x92P;\\x15\\x1f0\\xff\\x00\\xbe6\\xb7\\xe0\\xd5\\xcc\\xe3\\xabG\\xd4P\\xad\\xcdN5\\x1fS\\xb0\\xf0O\\x89\\r\\xbc\\xb6\\xf1J\\x0e\\xc5\\x18-\\xed\\x8c\\x7f\\x85]\\x1a\\xa1\\xfe\\xd9\\xb8\\xd4\\xa4\\x8c\\xb5\\x94\\x92yr{\\x03\\xe9\\xee0\\x0f\\xe5\\xeb\\\\\\x96\\x8b\\x11\\x8aU\\xc1\\xc0_\\x9b#\\xfb\\xbd\\x1c~\\x1d~\\x95\\xd3\\x1b\\x80t\\xeb\\x8d\\x1eX\\xd43\\xa9de\\xf5\\x07\\xaf\\xe6\\x0f\\xe9^\\x95\\x1a\\xad\\xd3\\xb3\\xdc\\xe3\\xafB\\n\\xab\\x94V\\xfb\\xfau;\\x8d?V\\xb5\\xb8&\\xc5\\xe4\\x05\\xe3\\x1b\\xe2\\x99\\x1b\\xef\\x8cp\\xcb\\xef\\xea;\\xfe4W\\x8fY\\xdf\\\\\\xe9\\xf7\\nZFP\\x8f\\xc3g\\xfd[\\x7f\\x81\\xa2\\x85T\\xe0\\xad\\x91\\xbek\\xc1\\xe8}\\x08\\x8e\\xb2\\\"\\xba0ea\\x90A\\xc8\\\"\\x9d\\\\\\x9d\\x8e\\xbbg\\xa1Yy\\x1a\\x94\\xf1\\xc1\\\"g\\xf7*\\xdb\\xc7\\xe0{T\\xd6\\x9e5\\xb2\\xbfp--\\xe6\\x95{\\x95\\x03\\x8f\\xe9\\xfa\\xd6\\x8aj\\xd7z\\x1e$\\xb0\\x95uqW]\\xce\\x9a\\x8a\\xaa.\\xdaD\\xccPH\\xc7\\xb7L~})\\xb0=\\xf9?\\xbd\\x8e ?#\\xfc\\xcd54\\xf69\\xac\\\\\\xa2\\xa9Kyq\\x04\\x8a\\x1e\\xc9\\xde2q\\xbe'S\\xb7\\xdc\\x83\\x8f\\xd35m\\x1d\\\\eNE;\\xa0i\\xa1\\xd4QX>)\\xd6-\\xb4\\xcb(\\xe2\\xb8\\x9d\\\"\\x17\\r\\x86g`\\xaa\\x10\\x0c\\xb6I\\xe9\\x9cc\\xf1>\\x94\\xde\\x80\\x95\\xdd\\x8b\\xb7\\x13Or\\xa8m\\xa3/ny,\\x08\\x1eg\\xa62~\\xef\\xbf\\x7f\\xa7_;\\xf1N\\x91\\xe3+\\x8b\\xc9\\xf5\\x08\\xeet\\x9b+8\\xe3\\xdb\\x143\\xb3\\xc8\\xf9\\xcf\\xde8\\x18\\x0cx\\x1d\\xc5r^1\\xf8\\xc7g\\xa7\\xc3-\\xaf\\x87\\x9c\\xdc\\xdft\\xfbS\\x8c\\xa2}3\\xf7\\xbf\\x95yu\\xdf\\xc4\\xdf\\x19^\\x9f\\xdfk\\xb7\\x00g%c\\n\\x8a~\\xa0\\x01\\x91\\xeck\\x1b9\\xebc[\\xa8=\\x19\\xed\\xba\\x17\\xdb\\x9fN:F\\xbdl\\xa2E`\\xb0J\\xc7tRn \\x0ezg<\\xf3\\x83\\xf9W\\xa9Zx\\x7fO\\xb3\\x08\\x129\\x1fj\\xe3\\x12L\\xee\\xa7\\x8c\\x13\\xb4\\x923\\x8e\\xf8\\xaf\\x0c\\xf8{\\xf1\\x12\\xfbZ\\x1f\\xd9:\\xe5\\xb4LY>[\\xc4\\x01\\x08\\xef\\x87\\x1d9\\xe9\\x91\\x8f\\xa1\\xafU\\xb0\\xd6>\\xc9`\\xe4jv\\xf2\\xdb\\xaa\\xe1cw\\xc4\\x8a{\\x05=\\xfd1\\xd4v\\xf4\\xa5M(\\xbb2\\xaa\\xc9\\xce)\\x9c\\xdf\\x8f\\xfe\\x1eBc}[O\\xb7\\x0e\\x88\\t\\x9a\\x15\\xfb\\xc0z\\xaf\\xaf\\xd3\\xadh|:\\xf1Qm=4\\x9dF`\\xdeP\\x02\\xdav?y;!'\\xb8\\xec{\\x8cg\\x9e\\xba\\x1a\\x97\\x8b\\xafm\\xa3\\xf2\\xb4\\xcd&\\xe6\\xf3?zRG\\xcb\\xef\\xb7\\x96?\\x95r\\xabg\\x7fs\\xbbS\\xba\\x8e(\\xecn\\xb0\\xb1\\x1f'k\\xbb\\x93\\xfc)\\xd5\\xf3\\xf4\\xf7\\xaa\\xeb\\xee\\x9a\\xc1*\\x90~\\xd1\\xaf\\xd4\\xf5\\xb5\\xb8\\x85\\xe5\\xf2\\x96T2c;3\\xce>\\x95\\x93\\xad\\xe9\\xd6\\xabo-\\xd2\\xb1\\x82f#\\x94\\x8c\\xb8\\x91\\xba\\x0c\\xa0#q\\xf7\\x04\\x1e98\\x15\\xc4\\xda\\xf8W\\xc5\\x17\\x13%\\xccS\\xa5\\x92'\\xdc\\x13\\xb6\\x18\\x0fP\\x06H\\xfa\\x13[\\x9en\\xb3o*\\xad\\xee\\xa1\\xa6^\\x18\\xb7yk\\xe7\\x18\\xd9I\\xe3'\\xe5 \\x902:\\x8e\\xa6\\x9f?I\\x18\\xca\\x11\\x8e\\xb4\\xe5w\\xe8r\\x1e,\\xb0\\x92\\xd7A\\x9fY\\xd5\\xae\\xee\\xd6\\xca&\\t\\x1c!W&A\\xbb$*\\x9d\\xaa;d\\x97?/\\\\\\x1a\\xf0\\x1dC\\xc57\\xd7RH\\xb0\\xc8\\xd1BO\\n[vG\\xb8\\xe9\\xfaW\\xb8\\xf8\\xf2\\xff\\x00\\xc4\\xff\\x00`\\xba\\xb7\\x9e\\xd5\\xbf\\xb1\\xe5\\x8c E\\x0b$k\\x81\\x80w.@'\\xdc\\xd7\\xce\\x92\\xc6\\xd1J\\xc8\\xeaU\\x81\\xc1\\x06\\xad(\\xf42\\xf6\\x93z6\\x12K$\\xa72;9\\xf5c\\x9ar*\\xf9e\\xa4b\\x17\\xb2\\x8e\\xa6\\x99\\x1co#\\x85Dg>\\x8a2jv\\xb1\\xb9\\r\\x81o>\\x7f\\xbac9\\xa6I\\xd9\\xe82=\\xcf\\xc3\\xbdAb'\\xce\\xb2\\x98\\xb7\\xd1\\x18)\\xfe`\\x9f\\xc0\\xd7s\\xf0\\xc7Q\\x8fT\\x92].r\\xaan\\x94\\x01\\xbb\\xa4W\\x0b\\xca\\x9f\\xa1\\x04\\x8fpq\\\\\\x0f\\xc3\\xbb\\x93e\\xaeOa{\\x0c\\x82\\xdbP\\x81\\xa1`\\xca@-\\x8e?B\\xc3\\xf1\\xa6\\xab\\xcf\\xa1k\\xf2[F\\xce\\x93\\xc1&\\xdc\\x83\\x82\\xeb\\x9e\\x08>\\xa0\\xd7\\x1dJ~\\xf3\\x92\\xf5=\\xfc\\x1dy{(\\xa6\\xfd\\xd7\\xee\\xfa5\\xaag\\xa6\\xdd[\\xcf\\xe1\\xedWc\\xa1X\\xd2L\\xaa\\xb1\\xce\\xdfc\\xfc\\xbd\\xf0\\x0fz\\xd0\\x9f\\x17\\xb0\\x9b\\x8bg%c\\xf9\\xd0\\xf7\\x03\\x002\\xfe\\x03c\\x0fl\\xf7\\xa8!\\xd5\\xa1\\xf1\\xbe\\x8e\\\"\\xb8`5\\xc8#\\xf9\\x1b\\xa7\\xda\\xd4\\x0f\\xfd\\x0cc\\xf1\\xc7\\xb5f\\xf8OW\\xfe\\xc7\\xd6\\x847\\x8b\\xba\\xd6S\\xe5\\xca\\xac>\\xefP\\x1b\\xea2\\x7f\\x02Ec\\xcdi'\\x1d\\x99\\xed\\xc5\\xcePm\\xaf~?\\x8f\\xa7\\xa9\\xa84\\xff\\x00\\xb7 \\xb8D\\xdeq\\x89cQ\\xd7\\xe9Ew\\x96z4:.\\xac\\x85q%\\x9c\\xe3tn\\x0e@\\xff\\x00\\xeb\\x7f\\xf5\\xa8\\xae\\x8b\\x1euL\\xd1\\xc5\\xfb\\x8a\\xe8\\xf1\\xef\\x07\\xfc<\\xf1?\\x8e$\\xfe\\xd2\\xd5'\\x9a\\xce\\xc5\\xbee\\x96`s'\\xfb\\xab\\xdc{\\xf4\\xf7\\xafS\\xb2\\xd3n\\xbc-4\\x16\\xc8\\xd1@\\xaa\\x00\\xf3<\\xb2\\xcb'\\xb9?\\xe4\\xd7\\xa2TW\\x16\\xf0\\xddB\\xd0\\xcf\\x1a\\xc9\\x1buV\\x15\\xa5JNK\\xddvg\\xcf\\xd1\\xc4:m\\xdd]=\\xcckO\\x16\\xe9r\\xde\\x0b+\\x8b\\x98\\xe0\\xba\\xe87\\x1c#\\xff\\x00\\xba\\x7f\\xa1\\xad\\xea\\xe1{D\\x95\\x0b\\xce\\xdb#w\\xc0\\x10G\\xa7H-54\\x16\\xf2\\x94\\xcd\\xb48\\xda\\xb1\\x9f\\xe2\\x00z\\x91\\x8eO'\\x07\\xf1\\xef\\xe06\\xf3\\x9f&\\xd6'\\xb89?\\\"1(\\x0f\\xbfa\\xf8\\xd6V\\x9f6\\x91\\xa2\\xda\\xed\\xbd\\x99\\xf5[\\xb6\\x18r\\xa8\\x02c\\xfb\\xb98\\xdc>\\xb9\\x1e\\xd5\\xb3\\x16\\xab\\xa8j\\x89\\x8bU[x\\x86\\x00\\x8e\\x11\\xb9\\xb1\\xdb-\\xd0\\x0f\\xc0}k(\\xc5=\\xd9\\xd3R-\\xea\\xa3e\\xdd\\x96\\xa6\\xd1\\xe4\\xc6\\xdc[F\\x08\\xfb\\xc5\\xd8\\x91\\xf4\\x1cg\\xf3\\xa94[%\\x97\\x1a\\x94\\xcd\\xe6\\xb1\\x04[3\\x0cmBrX\\x0e\\xc5\\xcf?L\\x0e\\xd5V\\xfe\\xde\\xea\\xcbK\\x9eW\\x91#2\\xed\\x85C1v/#\\x04\\\\\\x93\\xee\\xc3\\xb9\\xab:\\xd6\\xa0\\x96\\x1aq\\x8e\\x06U)\\xb56\\x83\\xd0v\\xfeUm\\xa8\\xad\\x8eu\\x079Y;\\x90kZ\\xd8\\x8841\\x9e\\x0f\\x19\\x06\\xb99&\\x12\\x02\\xdcUy$yX\\xb3\\xb1$\\xf5\\xcd0\\xf01\\\\\\x92nN\\xec\\xf5)\\xd0PV-\\xdb\\xdfMn\\xd9I\\x08\\x07\\x83\\xee*\\x03\\xa4xn\\xeaS,\\x9aU\\xa5\\xad\\xc1\\xe4\\xcb\\x1d\\xb22\\x93\\xee\\xbf\\xe0E0t\\xe9R\\xace\\x90\\x90\\x0f\\x1di\\xc6N;\\x0eta=\\xca\\x9a\\x8e\\xfd\\x1e0\\xf6Zc\\xdf\\xc3\\x8c\\x93d\\x17\\xe5\\xfa\\xa9!\\xbfB=\\xeaK-OR\\x95\\x15\\xe1\\xd0\\xe4`\\xc3 \\x1b\\x84\\xe7\\xf2\\xcd<\\x8aU@\\xbc\\x8e\\x0f\\xb5[\\xad'\\xb9\\x8a\\xc2E;\\xdc\\x8fU\\xd4n.t\\xf9\\xed.\\xb4\\xcd\\x82E\\xc0\\\"l\\x94=\\x9b\\x05GC\\x83\\xf8W\\ts(6w\\xeduj\\xb2I%\\xbbq\\xb4\\x12\\xb2(;X\\x7f\\xc0\\x878\\xf7\\xf4\\xafAvy\\x93d\\x923\\x8e\\x98c\\x9a\\xe55;3\\r\\xd1\\xdb\\x9d\\xd9\\xca\\x9f_o\\xc7\\xf9\\x8fzp\\x9bn\\xcc\\xf4pq\\x86\\xb4\\xa7\\xb4\\xbf\\x07\\xd1\\x9c&\\x9fv\\xf6\\xb3,\\xd1\\xbb\\x01\\x90\\xeaP\\xe0\\x82\\x0fP}s\\x8a\\xec.v\\xea\\xf0\\xff\\x00iB\\x17\\xed*\\xbb\\xaeQ?\\x8c\\x7f\\xcfE\\x1f\\xccv<\\xf4\\xe6]\\xbc\\xb3\\xbb\\x06E\\xfa\\xfd\\xd1N\\xbb\\xf8\\xa3\\xa1Z\\xdb\\xf9\\x1a\\x1d\\x8d\\xe6\\xb1p\\xbc-\\xae\\x99\\x07\\x98\\x01\\xf4,\\xb9Q^#\\xae\\xea\\x91i2\\xed\\xd4\\xaf\\x13_\\xd5\\x07\\xcc\\xc0\\x9c\\xd9\\xc0\\xc7\\xb2'G\\xc7\\xa9\\x18\\xf4\\x1cf\\xa9i><\\xf1\\x0c\\x1a\\xa5\\xbd\\xdd\\xbd\\xf1\\x8d\\xa1?,`~\\xec\\x0fM\\xbd1\\xed]\\x11\\xf7Q\\xc3Z\\xa2\\xa8\\xf6;}w\\xc5_\\x105\\xdd\\x7fF\\x93P\\xf0\\xc5\\xf6\\x99\\xa2\\xdbj\\x10\\\\I\\x12\\xc2\\xc7\\x85pwH\\xd8\\xe8:\\xf4\\x02\\xbb\\xcdi\\xe4:\\x95\\xcad\\x94f\\r\\xf9\\n\\xf2\\x9b\\xcf\\x18j\\x9a\\xbd\\xfc\\x97W\\xf3\\x82\\xf2\\x8d\\xb8A\\x85\\x03\\x18\\xc0\\xafQ\\x9eG\\xba\\xb0\\x82\\xf8\\xaf\\xef\\x1a\\x152\\x8fF\\xc7?\\xaek\\x1a\\xd2\\xb9\\xd1\\x84\\x87,\\x8a\\xd0C\\xbd\\xd4\\x13\\xd6\\xa7\\xb8\\xb5@\\xd8^\\xd4Y\\x95YT\\x93\\x9c\\x0c\\xd3g\\xbcV\\x9fj\\xf3\\xcf5\\xcd\\xccv\\xb5'!\\xb1\\xc3\\x96\\x02\\xb4\\xa0\\x81bC\\x91\\x9c\\xd5D\\x99K\\x0c\\x0cSn\\xaf\\xccJ\\x0ex\\x00\\xb1>\\xb8\\xff\\x00\\xeb\\xe2\\x85\\\"$\\xa4\\xf4*7\\x0c@\\xf5\\xa1T\\xf6\\xa6\\xa0\\xca\\x82jT\\x1c\\xe0U\\x16\\xc5\\x95|\\xb7\\x8c\\xf6`\\x7f:\\xc5\\xbd\\x8c\\\\\\x16\\xcf>\\x95\\xab})\\xf3\\xa0\\x84u\\x08\\xcd\\xf4\\xe4\\x7f\\x81\\xaa\\x13\\xa9R\\x00\\xed@\\xd2kS\\x9c\\xb9\\xb6Y\\x84\\x88\\xc8\\x19_!\\x90\\xff\\x00\\x17\\xd3\\xdf\\xbdb\\\\\\xda\\xf96\\xc8\\x9b\\xb7\\x85c\\xb5\\x88\\xea\\xa4\\xf4>\\xe2\\xbaMR\\x19`\\xf0\\xcc\\xfa\\x84g\\x0e\\xac]r:s\\x90\\x7f.+\\x16\\xda\\xfa\\xdfX\\xb5bP$\\xbf\\xf2\\xd2?\\x7f\\xef\\x03\\xfc\\x8d[^\\xd1y\\x9e\\xde\\x17\\x10\\xaa;?\\x89~$\\xba\\x1e\\xa6\\xb6w\\t$\\xcb\\xe6\\xc5\\xfe\\xa6\\xe6\\\"\\x7f\\xd6F\\x7f\\xaf\\x1d}@4T\\xda\\x0f\\x86\\xdfV\\xd5|\\x8f\\xb5\\xc3\\x04j7\\x17s\\xf30\\x1d\\x80\\xee\\x7fN\\xfe\\xd4TF\\x85I+\\xd8\\x8cEL4gi\\xb6\\x9f\\x95\\xd7\\xe4}\\x0fa{\\x16\\xa3e\\x15\\xd4@\\x85q\\x9d\\xa7\\xaa\\x9fCSJ]bfA\\x96\\x1c\\x81\\xeb\\xed^Y\\xa2\\xf8\\x9c\\xe9\\xd3\\xc6\\x16\\xee6\\xb7\\xec\\x8a\\xdb\\x86;\\xf1\\xfe\\x7f\\xa5w\\x16z\\xe5\\xd6\\xa4\\x8el\\xec\\x98\\xe0\\xe3q*\\x14~9\\xe7\\xea\\x05wS\\xab\\x19\\xa3\\xe5\\xf18\\t\\xd2\\x95\\xd7\\xc2mG2\\xc9\\xc7!\\xba\\xe0\\xf7\\xa9+84\\xf0\\xc2\\x1e\\xe6%\\x010Wd\\x99?O\\xba*\\xf8pFI\\x18\\xecsZ\\\\\\xe1\\x94lEum\\x05\\xc4dL\\x06\\x00?6pG\\xe3\\xfeEpZ\\xdf\\x88$\\xb2\\xb8\\x92\\xd2\\xcc\\x1b\\x8beR\\xad,\\xcf\\xb7\\xe6\\xf4\\xc6\\x0eG\\xe0?.\\xba\\x1e!\\xf1l[\\x1e\\xd2\\xc6X\\xdb\\xfb\\xf3\\x03\\xd0\\x7f\\xb3\\xeb\\xf5\\xfc\\xab\\xc7\\xb5\\xfb\\xdb\\xbd>V\\xb8\\xb7u\\x96\\xd0\\x9d\\xd3\\xc4I%\\x0f\\xf7\\xc7\\xb7\\xa8\\xfc}j^\\xbb\\n\\xf6\\xd0\\xe8\\x9f\\xc5\\x97Q\\xc8\\xfbt\\xb8\\xa5\\xe3\\x1b\\xa3\\t\\x8f\\xe4\\xa4\\xd6\\r\\xfe\\xb7\\xaa\\xea\\x10Lm!Kl\\x02Y\\xe1O\\x99FpO\\xde8\\xfa\\x8a\\xc4]~\\x01\\x13\\x9b\\x9b\\xf9P\\x9e\\x89\\x14Ls\\xf8\\x9c\\x01\\xf9U\\x8bk\\xe3\\x1d\\xaaOm)\\x8cJ\\x01\\x85\\x93\\xa8\\xe3\\x04\\xe0\\xff\\x00#\\xd6\\xb3\\x94V\\xe6\\xb0\\x93\\xb5\\x8c\\t\\xfc3qz\\x1a\\xea\\xe2\\xe2{\\x96<\\xee\\x92A\\x82~\\x80\\x92kn\\xe2\\x18\\xfc)\\xa4\\x7feY*\\xad\\xfc\\xe8\\x1a\\xfet\\xea;\\x88\\x81\\xfe\\xe8\\xef\\xeay\\xf4\\xad\\xff\\x00\\x0ei\\xafq\\x04w\\x12yP\\xa5\\xb4\\xdb\\x9b\\x00\\x90_\\xaa\\xec^\\xa4g\\x0c\\x07lb\\xa9\\xebRiVw\\xcd\\x15\\xc3[@\\xee7y\\x97\\xb2\\x02\\xcc3\\x8c\\xec\\x1c\\x0e\\xf5\\x9f=\\xdd\\x91\\xd4\\xa9(\\xc7\\x99\\x9eo,\\x12]Np\\t\\xabpY\\x18\\x06X\\x15\\xf7#\\x15\\xbf4\\xde\\x19\\x005\\xc6\\xbf\\x0b\\x13\\xfc(\\x8e\\xc0~KP\\xff\\x00j\\xf8:\\x01\\xff\\x00\\x1fs\\xccG\\xfc\\xf3\\xb7<\\xfex\\xa6\\xf9\\xdfBb\\xe9\\xc5\\xeeR\\x84)u\\xfd\\xe0\\xc0>\\xb5\\xed3\\xdc\\xcb\\x1d\\xac\\x01\\t\\xc3G\\x83\\xf8\\xff\\x00\\xfa\\xeb\\xc9\\x13\\xc5\\xbe\\x10\\x81\\x1c\\x0b\\rBg<)h\\xd0\\x01\\xef\\xf7\\xba\\xd6\\xdc\\xbf\\x18t\\x83\\x1ch\\x9a5\\xe1\\x08\\xa0s*\\xae\\x7fCX\\xce\\x8dIluQ\\xc5Q\\x86\\xb2;u\\xb8\\x91T\\x85\\xcfN\\xb4\\xeb}\\xd8,s\\xb8\\x9e\\xf5\\xc0\\x0f\\x8c\\x9az\\xe7\\x1e\\x1d\\x9f\\xdb\\xfd4s\\xff\\x00\\x90\\xe9\\x87\\xe3Z\\xaf\\xfa\\xaf\\rF\\x07\\xfbwd\\xff\\x00$\\x15\\x9f\\xd5j\\x9b\\xbc\\xc2\\x87C\\xd2\\xfc\\xc6\\x08z\\xf4\\xaa\\xd7s4\\x97I\\x17\\x1eZ\\xa2\\xbf\\xeap?L\\xfe\\x15\\xcb\\xf8W\\xc7:\\xa7\\x8a\\xef\\\\\\x9d&\\xd6\\xcfL\\x87\\xfd}\\xc9fl\\x1cp\\xa0\\xf4\\xc9\\xfd\\x07\\xe1[\\xd7\\x13'\\xf6\\x8d\\xba\\xa3\\x02$\\xb7c\\x90s\\x90\\xac1\\xff\\x00\\xa1\\x1a\\x97\\tA\\xd9\\x97\\n\\x90\\xaa\\xb9\\xa2jDAE>\\xd50q\\x1f8\\xc9\\xec*\\x94.\\xc1v\\x8a\\xb8L\\x16v\\xcdqu\\\"\\xae\\x06B\\x93\\xf37\\xd0U-E%\\xad\\x8a\\xe66\\x12\\xb5\\xc4\\xa72?\\x00z\\nMB=\\xb1\\x04^\\x1eN\\x07\\xb7\\xa9\\xac\\xc95\\xad\\xf3\\x17X\\xcc\\x84c\\xe5\\x1ft\\x0f\\xadW\\x9fV3J\\xd2\\xdd\\\\\\x8d\\xc7\\xa4P\\x00q\\xed\\xb8\\xf0?\\x0c\\xd5\\xa8\\xdfs\\xa68J\\xd3{X\\xd0\\xf1\\x1d\\xb7\\xda|<\\xda]\\xa4\\x91\\xac\\x8e\\x02\\x96s\\xc2\\x8e\\xe7\\x8e\\xbfAX\\xfag\\x86\\xb4\\x8d2#\\xf6\\xf6\\x96I\\xb6mY7ye=\\xc2\\x8f\\xfd\\x9b#\\xda\\xa5\\x8a[\\x8b\\x96\\x06\\x04\\xf2#=e\\xee\\x7f\\xe0G\\xfaV\\xad\\xa5\\x95\\x97!\\x8b\\\\>2\\xc7\\x1c\\x0f~\\x7f\\xc2\\xb6\\x84R\\xd1jn\\xb0\\xca\\x8anM\\xfc\\xbf\\xad\\x0cI-\\x96\\xc2\\xf1|\\xbb\\x85\\x96&\\xe69\\xd0`\\x1f\\xc0\\xd1R\\xea\\x1a\\x95\\xac1\\xcb\\x1d\\x9cL\\x89\\xb7/,\\xcb\\xfc\\x81\\xfe\\xbf\\x95\\x15>\\xd1#\\xae\\xcavu\\x12~\\xb6\\xbf\\xe4z&\\xbd\\xe0\\x0b6O\\xb4iQ\\x886\\xaf\\xcf\\x02\\xf48\\xfe%\\xe7\\xefz\\xfa\\xfdz\\xe5hz\\x84\\x9a\\x0b2\\xc9#m\\xe9\\xf3\\xf1\\xb7\\x1dx\\xe3\\x8fn\\xb5\\xdc\\xa5\\xf3\\xdd\\xb1X\\x95\\xd5H\\xc8 d\\xb7\\xd3\\xb0\\x1e\\xe6\\xb1\\xf5\\xdf\\x06\\xae\\xafn\\xf2E\\\"\\xdb\\xdd\\xfd\\xe5\\xc9$9\\xff\\x00l\\xff\\x00P8\\xf7\\xe9Z:i>zkS\\xe6\\xe8\\xe2\\x9a\\x8f\\xb2\\xc4\\xbb\\xa7\\xf7\\x97\\xf4\\xadv=V\\xe9\\xa2\\x1b\\x98\\x85\\r\\xc0\\x1bH=\\xc7\\xb7\\xd7\\xd3\\xa05\\x97\\xe2\\x99uY\\xdakHa\\x8a+b\\xb8i\\x1eM\\xa5\\x97\\xd0{\\x1e\\xff\\x00\\x80\\xfa\\xf2\\x0bqu\\xa1\\xdf\\x0biC\\xda]\\xc01\\x1eN2O|\\xf2\\x0eq\\xee\\x0e=\\xb8\\xed4\\xedb\\xdf\\xc4\\xf6b\\xce\\xf4\\x0b]D}\\xdfG=\\xf6\\xf3\\xd0\\x81\\xca\\xe7>\\x84\\xe34A\\xcaJ\\xcd\\xeae\\x89\\xc2(Z\\xa4u\\x83\\xea\\x8f\\x9f\\xfcM\\xe2\\xf9\\xb4\\xfd^]=\\x93\\r\\x01\\xda\\xdc\\xfa\\x7fZ\\xe4\\xe6\\xf15\\xe0\\xbd\\x12\\x87\\xca\\x9eA\\xcf\\x07\\xf0\\xafQ\\xf8\\xc5\\xf0\\xe6yb\\xfe\\xdf\\xd3af\\xba\\xb6\\x8fm\\xf4\\x0b\\xcb4c\\xee\\xca\\xbf\\xde\\x00p{\\xe0\\x0c\\xf7\\xaf\\x0bL}\\xd7\\xe1OC\\xe8kh\\xc7C\\xce\\x92I\\xd9;\\xa3^\\xf2\\xefy\\xd9\\x12b6\\xfb\\x80v\\xf6\\xab\\xf6\\x1a\\xa1\\ro\\x01c\\xe5\\xc4\\xa12:{\\xd6\\x00\\x9bh1\\xb8\\xfdjt\\x91\\xe0\\xdaI\\x0c\\x85I\\x8d\\x87C\\xebJI\\xb4\\x10\\xd1\\x9fDxb\\xdf\\xed\\x1e\\x1d\\x82\\xe9\\x14\\xacS\\xc8H\\xc62\\x14\\x1c\\x0c\\xfdq^\\t\\xe3-P\\xeb\\x1e-\\xd4.T\\x93\\x18\\x94\\xc5\\x17\\xfb\\x89\\xf2\\x8f\\xcf\\x19\\xfa\\x9a\\xf5\\xef\\x04k/{\\xe0{F\\xb79\\x92\\xd2G\\x82U\\xdd\\x802w\\x02}z\\xff\\x00\\xf5\\xea\\x1bH\\xf4\\xad\\x1fG\\xbc\\xbc\\xd3\\xb4\\xebx\\xae!}\\xe6}\\x99v\\x18\\x04\\x90\\xc7'\\x19\\xdd\\xdf\\x15\\xcdNJ\\x12wG\\xa5Z\\x0e\\xac#fy\\x1d\\x97\\x84|A~\\xaa\\xf0i7>[}\\xd7\\x91|\\xb5?Fl\\n\\xd8\\x87\\xe1\\xae\\xae\\xd8\\xfbM\\xde\\x9fm\\xea\\x1eb\\xc7\\xff\\x00\\x1d\\x04~\\xb5\\xd6\\xea\\xfe#\\x96[\\x18\\xa5\\xfbAf\\x0c\\xd9\\x19\\xe9\\x82x\\xfd+\\x96:\\xdc\\xf2\\xb1%\\xc9'\\xde\\xad\\xd6\\x93\\xd9\\x18\\xac,\\x17\\xc4\\xcd}3\\xe1$W\\xee\\xc9'\\x89\\\"\\x8c\\xa8\\xc9\\xd9l_\\xf9\\xb0\\xab\\x8d\\xf0\\x7fN\\x13\\x98\\x7f\\xe1&\\x93 \\xe0\\xb7\\xd8\\x87\\x07\\xfe\\xfeT~\\x17\\xd4.\\x17U\\x85\\xf1#F\\xff\\x00+\\x10\\t\\xc0\\xf5\\xae\\x8b\\xc4:\\xc7\\xfc#\\x1aK\\xea\\r\\x18\\x9ai\\xe7\\xdbo\\x0b67\\x93\\xc98\\xeb\\x801\\xfa\\x0e\\xf5\\x8f\\xb6\\xaa\\xe7\\xca\\x8e\\xb7\\x83\\xa1\\x1a\\\\\\xec\\xf2\\xef\\x1b\\xf8Hx;W\\xb7\\xb1[\\xf1z\\x93[\\x89\\xd6O+\\xcb\\xc6Y\\x97\\x18\\xc9\\xfe\\xef\\xafz\\xa5\\xe1\\x9f\\r_\\xf8\\xa3U[+(\\x9c\\xaa\\x8d\\xf3J\\xa8XD\\x9d\\xce\\x07S\\xe8;\\x9a\\xf6\\x7f\\nh:\\xc6\\xab\\xe2+\\x7f\\x14x\\xc3L\\x96)\\x00X,\\xad\\x92\\x12\\xa2$$\\xe5\\xf0s\\xfd\\xe3\\x8c\\xfb\\x9fJ\\xef\\xadc\\xf2|q5\\x8e\\x99i,\\x16\\xf2[2\\x99\\xca\\x92\\xa4\\x94\\xdc>lt\\x04\\x8f\\xca\\xba][i\\xd7c\\x8a8^{\\xcbef\\xfeH\\xe5t\\xeb\\xdd\\x07D\\xd1!\\xd3t\\xc61[[\\xfc\\xa42\\x1d\\xee\\xdd\\xd9\\xb8\\xe4\\x9f^\\x9d\\xbbW7\\xae]\\xe9Wn\\xb2\\xd9C4\\x17hr'\\x8d\\xf6}x\\x1ds\\xf8V\\x8d\\xef\\x87\\xe2\\x9e\\xdbS\\x92\\xd7W\\xf3\\xee\\xf4\\xe5/=\\xb4\\x96\\xcd\\x11\\xda\\x0e\\tRI\\xce=\\xc0\\xae8\\xc8O\\x03'\\xe9^t\\xa7$\\xee\\xcf\\xad\\xc2\\xe0p\\xf2\\x85\\x9e\\xb6\\xf5_\\xf0MS\\xad_\\x98V6\\xbb~\\x06\\x0b\\x0c)?\\x95D/\\xb6\\x92\\xd8.\\xfd\\xdaC\\x9f\\xd3\\xfcsY\\xccv\\xa9g`\\x8a:\\x92i\\xb3N\\x96\\xc9n\\xf2\\xeeH\\xa7l$\\xce\\x0e\\xcf\\xa9>\\x9c\\x8eiFS\\x7f\\t\\xdd'\\x87\\xc3\\xab\\xbbG\\xfa\\xfb\\xcd7\\xbb\\x9a\\xe3\\x01\\xa4;GA\\xd1G\\xe1S\\xda\\x94\\x0e\\x00\\xcc\\x8f\\xd7\\x01r\\x7f*e\\xbd\\x82J\\xd8YL\\xb8\\xea\\xcb\\xf2\\xa0\\xfa\\x1e\\xad\\xf5\\xe0}k\\xa6\\xd0\\xb4ine\\xfb.\\x9bn\\x1d\\xd7\\xe6\\x91\\xcf\\n\\x9f\\xed;v\\xfe|p\\ri\\x14\\xef\\xdd\\x98T\\xc5\\xc5E\\xcbh\\xf7z\\x11Ems2\\xef\\x99\\xfc\\x94\\xc6q\\xf7\\x9c\\x81\\xfa\\x0f\\xd6\\xae\\xf8oP\\xb7\\xd3o\\xeeZ\\xe5w\\xad\\xd4F1\\xb8\\xe7\\xcb\\x1dG\\xe2O_\\xaf\\xb5G\\xaa^[[\\x07\\xb2\\xb2\\x97\\xcf\\xed5\\xd60$>\\x88;&\\x7f3\\xcf@+\\rw\\xdcL\\\"\\x8c\\xed\\x18\\xdc\\xef\\xfd\\xc5\\xf5\\xff\\x00\\x01\\xdc\\xd6\\xf1\\x93\\x8bL\\xe4P\\xf6\\xf0s\\xab\\xa4^\\xcb\\xf5\\xff\\x00#C\\\\\\x82+\\xab\\xf0\\xf6\\xf1\\x05\\x8d\\xc2\\xfc\\x80\\xe7\\xcc\\x93\\xa6q\\xd8\\x0e\\x0f\\xd4\\x8fz*\\xe5\\xba\\xf9q\\xc7:\\xc2\\xed+\\xfc\\x96\\xf1\\xe0\\xbb1\\x1f\\xc4{\\x90=h\\xaa\\x94T\\xe4\\xe4\\x86\\xb1\\n\\x97\\xb9\\xbd\\xbb\\xb4Y\\xd1\\xd5\\x9c_@\\x16\\x85\\xee\\xe2\\xb0\\xb3\\x93%@\\x9a%\\x01\\xbdU\\x94\\x80r\\x0f\\xd0\\xfb\\x8a\\xb9K\\x13\\x0f\\x8eIz\\x9c\\x8a\\x9e\\n\\xa6\\xb4\\xa3'\\xe5u\\x7f\\xba\\xc7\\xceg\\xc1W\\\\\\x86\\xb9\\xb6\\x18\\xe8|\\xd0\\x7f\\x95`_\\xda\\xcd\\xa6^Oa1\\x04\\xc6\\xe5X\\x03\\x91\\x91\\xc6E{\\xdc\\xbaW\\x87\\x1bT\\x13\\x9d^\\xd6\\xde%;\\xb6E\\x97\\r\\xe9\\x81\\x81\\x8f\\xe5L\\xb3\\xf0\\xc7\\x82\\xde\\xf5\\x9a\\xce(\\xf5+\\xe6\\xcb\\x97\\xbb-'\\xd4\\xed\\xc0_\\xcf4P\\xc6\\xdeO\\xda\\xc9\\x0f\\x13\\x96F\\xd1xu/>n\\x9f\\x81\\xe7\\x9f\\x0bo\\xee\\\"\\xd5.t\\xb1os5\\xae\\xa1\\x17\\x97#E\\x19q\\x13\\x83\\x95b\\x00\\xe9\\xd4\\x1fc\\xed^\\x9f\\xa9ir\\xc8\\xc4\\ta\\x8a)\\xa2\\xd9\\\"\\xca\\xc0c\\xdbh\\xc9\\xfd*\\xde\\xa1t\\x9a5\\x9cKzd\\x86\\t2#\\x82\\x08\\xc2\\xaf\\x1e\\x8a0\\xb5\\x05\\xbc\\x93_\\xda-\\xcd\\x9e\\x90\\xcd\\x03gk\\xcdr\\xb1\\xee\\xc7\\x1c\\x0c\\x13\\xfa\\xd1W\\x13MN\\xfa\\xdc\\xea\\xc3`%\\x1a^\\xf3\\xbc~K\\xf1g\\x1c\\xde\\x10\\xd3 \\x81\\xa3\\xbb\\xd4.'R\\xfb\\xca\\xc2\\x81\\x07A\\xfcG>\\x9e\\x83\\xad\\x11\\xe9\\xda-\\xa6\\x05\\xa6\\x98\\x8e\\xfd\\x9aRd?\\xaf\\x15\\xbfwuom2\\xc7\\xa9\\xe9s\\xda\\x16\\xfb\\xb2\\t\\x04\\x8a\\x7f\\x11\\x8f\\xebQ\\\\\\xda(\\x08bux\\xa4\\x1b\\x95\\x90pEf\\xb11\\x92\\xdc\\xf5(`\\xe8S\\xb3q\\xf9\\xbd\\x7f\\xe0\\x0b\\xa4\\xdb\\xcdu:\\xa0\\x01W?uF\\x07\\xe4+\\x9d\\x97K\\xba\\xf1\\xcf\\xc4\\x14b\\xd2A\\xa3\\xe9\\xa7\\x0b m\\xbf*\\x9eJ\\x9fVn\\x87\\xae1\\xe9[\\x1e!\\xd6\\xc7\\x85t\\x18\\xfc\\x82>\\xdfz\\xde\\\\#\\xba\\xaf\\xf17\\xf2\\x1fSP\\\\\\xd8L5\\xabK{\\xd6`\\x92\\xaaJ\\xcb\\xb8\\x9d\\x80\\x8c\\xb0\\x1fL0\\xfc*=\\xa4\\xa8\\xc7\\x9d-\\xeerV\\x841\\xb5\\xdd\\x17+(\\xab\\xbd7=\\x02K\\xcdWQ\\xd4\\xeda\\x87P\\x91\\x97\\xccU\\xf2\\xe3\\x9f\\xa8\\xc8\\xec\\x0f?\\x05\\x195\\x8bb\\xb7\\x96z\\x8d\\xb3Z\\xc8\\xaf\\x10ddnJ\\x91\\xb8\\x10~_\\xa7Z\\xa7\\xa6iz\\x05\\x84?h\\xb6\\xd1\\x9c\\x82\\x7f\\xd6\\xcd2\\x8f\\xcb?\\x8dR\\xc4a\\xd4SW\\x93-\\xbc\\xc2\\xa5\\xe5\\xa58\\xbf5\\xd3O\\xebc\\x82\\xd1\\xf4\\xdd_Q\\xd4!\\xbb\\xbd\\x8aI-\\xd4\\xe7\\x13\\x1c\\x03\\xf4\\x1f\\xfdj\\xeb\\xed\\xb4X,\\xed\\x92k\\xe7>U\\xbad\\xeeb@\\x00}\\xecz\\xe2\\xba\\x98\\x99\\xe7\\\\\\xda\\xe8\\xef'\\xc9\\xbf)r\\x84\\x95\\xce28y\\xdb\\xfd\\xb3\\xd9Ga\\xd3\\xb9\\xed\\x8bo\\xa7\\x95e\\x17\\x01\\xcfq\\x0cC\\xf9\\xb1\\x18\\xcf\\xd0\\x11\\xef]\\xb6_\\r2hS\\x95Y\\xaa\\xd8\\xa7w\\xd2=\\xbd\\x7f\\xe0\\x98\\x9f<\\xb3$1+I,\\x87\\n\\xaa\\t,~\\x83\\x9a\\xdc\\xba\\xb5\\xfe\\xc0\\xd1\\xa3\\xb8\\xb9\\xb6\\xdf\\xe6J\\x15\\xd0J\\x03\\xe7\\x07\\x93\\xc1\\x1d\\xb0\\x07oJ\\xb3g\\xf21X|\\xbbD~\\x1b\\xcb\\x19v\\xfa\\xb7$\\xfd3\\x8f\\xa5[\\xd5\\xac\\x86\\xab\\x15\\xb6\\x83e\\x19\\xf3\\xe5q4\\xd2\\xb1\\xc9\\x8d\\x06yo\\xafa\\\\\\xf8\\xa8\\xaat\\xf7\\xd7C\\xbeU%:\\xb1\\xe7\\xd2?\\xa7{\\x92h:\\xc4z\\xbd\\xb4\\xd25\\x81\\xb4\\xb2\\x88mgY\\xb2\\xd2\\x1f\\xee\\x83\\x81\\xc7\\xe3\\x81EjE\\xa4[Z[\\xc3\\xa7\\xdb\\xa6\\xf4\\x8f\\x80:\\xe4\\xf78\\xeeM\\x14\\xa8\\xa9(\\xfb\\xda\\xbfS\\x86s\\xa3\\xcc\\xdc4]5=\\x19I\\x07c\\x1c\\x9cpq\\xd6\\xbc3\\xe2\\x1a\\xc0\\xbe:[D\\x85!\\xb6\\x8f\\xcb\\xca\\\"\\xe1r\\xdc\\xb1\\xc7\\xbe\\x7fJ\\xf5{\\xbb\\xbd/\\xc3\\x90D\\xb7Z\\x85\\xc3H\\x9c\\xc7\\x1bJd\\x91\\xc7N\\x9e\\x9d\\xb3\\xc0\\xf7\\xaf'\\xf8\\x85\\\"\\xea\\xd7\\x91k\\x90Bc\\x8d\\xc0\\x89\\xd4\\x9c\\x90G\\xdd'\\x1d28\\xfc:\\xd6\\xb9\\x82\\xbc\\x15\\xbb\\xfe\\x86\\x19\\x0cyqN_e\\xa6\\x93\\xf3.\\xf8\\xb6\\xc3Q\\xd2fW\\xbaTH\\x9c\\xfe\\xeeP\\xf9C\\xfdG\\xe2\\x07\\xe3W\\xfc0\\xb6W\\xc9\\xf6{\\xb7)\\x93\\xbd\\x1dH\\xc6}\\xb3\\xdc\\x1a\\xafay\\x0e\\xb5\\xa5%\\xd1\\x8c\\xc9(\\x8fl\\xe7\\xabo\\x1f\\xa9\\xf5\\x02\\xb1a\\xd5\\xb4\\xdby\\x19,\\xcd\\xf1br\\xf0\\xc7\\x08*~\\xaaO\\xf8\\x1fz\\xe4\\xf6\\xb4\\xa3\\xcb$\\xfdQ\\xdf\\xec\\xebJ\\x93\\xa4\\xfe%\\xd5\\x1d\\xef\\x884\\xbdg\\xec\\xe8l\\xb5{\\x8b\\xbb5\\x00\\x8bW\\xa6\\xf6oC\\x0bZ\\xbc\\xfe\\xd4\\xb3[+@&H\\xe4\\xdf%\\xc7H\\xd3\\x821\\x93\\xf5\\xff\\x00\\xf5\\xd5kh\\xae\\xe4\\x868`2%\\x95\\xb2\\x16y\\xca\\xe1q\\xcb1$\\xf4\\x1dkwA+\\xa6\\xea\\x97\\xbe\\x1f\\xb9h\\xf0\\x8ce\\xb7\\x92E\\x1c\\xaf^\\xfe\\xdc\\xfeu_\\xc6W\\xf6w\\xfao\\xf65\\xa5\\xf3Jf?\\xe9\\x1fg\\x05\\xd8\\x81\\xd1\\x07lg\\xaf=\\xb1\\xebUFP\\xbf5G\\xa9\\x18\\xb7Y\\xafcGm\\xd5\\xb7w\\xea\\xde\\x89\\x1c\\x17\\x86\\xad\\xe5\\xf1\\xaf\\x8dn\\xb5\\x99\\xd9\\x8d\\x86\\x9c\\x07\\x91\\xbf=s\\xfb\\xb1\\x8f\\xc0\\xb1\\xf7\\xae\\xd6\\xee\\x05]{N\\xf3$\\xde\\x1a\\x192\\xc4c\\x8c5C\\xa5\\xe9\\xff\\x00\\xd8\\x9e\\x16\\xfb\\x16\\x9d\\x0c\\xf0J\\xce\\xd2Hn!\\xd8\\xd27\\xb7n\\x14t\\xf6&\\xab\\xd9\\xddK\\xfd\\xb1\\xa64\\xec\\xd2K\\xb2@3\\xdc\\x9d\\xc0\\x0f\\xce\\xb5\\xc5UUcx=\\x17\\xf93\\x93/\\xa7\\xec\\xa5%5\\xef\\xb5+\\xfd\\xc6=\\xf5\\xe5\\xb6\\x9dr\\xfeZ\\xca\\xce\\xdf1\\xda\\x8c\\xe4\\x8e\\xc7?\\xd6\\xadY\\xea\\xd7W\\xd0\\xcdj\\xb6RIo$d<\\xcc\\xdc!\\xed\\x9f|\\xe2\\xa9\\xc7\\xfd\\xa3\\x14W\\xf2Cd\\xf3\\xea\\x13\\xb1U\\xbb\\x9d\\x80H\\xf8\\xc1+\\x9e\\x8cz\\x02:\\x0cs[\\xf6S\\xcd\\xa7xf\\xe1\\xae\\x961#\\xc4\\xa9\\xc3\\x13\\x99J\\x85b;u\\x05\\xabj\\x94\\xa9F\\x9bs\\x95\\xdf\\xea\\x10\\xc4b\\xaa\\xce1\\xa3\\x05\\x18\\xddl\\xbc\\xfb\\x94\\xac\\xa4\\x9e\\xe3\\xc3\\xd7V\\xd9c\\x0cD\\xb9\\x1d\\x97\\x8c\\x8f\\xfd\\x04\\xfeu\\x1f\\xf6o\\xf6\\x8e\\x9f\\x04F9\\xf2T`+&\\x0e\\t<\\x02\\xde\\xf5\\xab\\xa4Z\\x9b\\x7f\\n_\\xcc\\xfbA\\xb8\\x8d\\xd8+u\\xda\\x14\\x80G\\xe3\\x9f\\xc2\\xb2\\xaf5\\xa9\\xf4\\x8d?M\\r\\x03\\xb5\\xbc\\x91n\\x06>\\xad\\x869\\xe0\\xff\\x00\\x9f\\xadqQSu-M\\xd9\\x9d\\xf8\\xf7I\\xc6j\\xa2\\xbcy\\xd7\\x7f\\xe5\\xf2k\\xa9\\xd0K-\\xf5\\x9bA-\\x86\\x914~L\\x02\\xddB\\xc8\\x8f\\xf2\\xe4\\x1c\\x90\\x01\\xe7<\\xf4\\xefO\\xb8\\xb76\\x0b}\\xa83\\xac\\x97\\xc60\\xf23\\xb6\\xe2[\\x00c#\\x1c{q\\xf4\\xae\\x7f\\xfe\\x12\\xdd*i7C\\x7fw\\x04G\\x00$\\x88\\x0e\\x0f\\xb9\\x04~\\xb8\\xfcj\\xf6\\xa7}j\\xbe\\x1f?g\\x9d\\xa5k\\x97\\xd8\\t@\\xbf( \\x93\\xc1>\\xc2\\xb7\\xab\\n\\xd0M\\xcaW\\xe9\\xd8\\xe7\\xc3G\\x0bR\\xa4cN*\\xf7\\xf3\\xfd[3\\xa4\\xd7uYQ\\t\\xb8h f*\\x0cJ\\x10\\x0e\\x99\\xc69\\xee+\\xaf\\x92\\xdeiZ+\\x0by$d\\x03\\xfdc\\xb9b\\xfcd\\xb1?L\\x9a\\xb3\\xa9xf\\xc6\\xcb\\xe1\\xd5\\x9c7\\xd2%\\xb5\\xd0\\x1fh\\x127]\\xed\\xfc$zc\\x03\\xf0\\xaa\\x1e\\x18\\xf1\\x04p[\\xb6\\x97\\xa9K\\x1d\\xbc\\xd0.c\\xb8(\\x19\\x9a>\\xbbA'\\x1d:\\x1e\\xe2\\x95\\x14\\xa9T\\x8c\\xea\\xab&\\xbf\\xaf\\xf8'eLE:\\xb0o\\x0e\\x97\\xba\\xde\\x9f\\x93\\xf35m\\xacc\\xd1\\xac\\xc4\\xf3D'\\xbb\\x95\\xb6A\\x19<3\\x9e\\xdfA\\xd4\\x93\\xd8V\\x95\\xa0\\x87I\\xb3b\\xf2\\x87\\xba\\xb8;\\xe7\\xb8#\\x06F\\xf4Q\\xd4\\x81\\xd0c\\x81\\xdc\\x8a\\xe6\\xac5G\\xd55\\x1b\\xadS\\xcce\\xb7\\x80y\\x16\\x9ef;\\xf2\\xccs\\xc08\\xc7\\xe7P\\xc9x\\x97W\\x0c\\x91\\xdc,\\xb2\\xbf\\xde;\\xf2O\\xe7\\xce=\\xff\\x00\\xa7^\\x9a1\\xf6\\xf3ue\\xb2\\xd1/\\xd4\\xe4\\xadNr\\x97$\\x9e\\xaf\\x7f\\xf2\\xf9~}\\xf47%\\xd5e\\xbaqkd\\xcd\\x08s\\xb5\\x9d\\x0f\\xce\\xc3\\xb8\\xdc>\\xe8\\xf5\\xc7\\xd3'\\xb1Y\\xba\\\\\\xd0\\xc9\\xa8\\x9b\\x18.#\\x13\\x04/)\\xcf*\\xa3\\x1c\\x01EvA\\xdd{\\xabC\\x9eT)E\\xda\\xd7\\xf3j\\xe6-\\xd6\\xab\\xe6\\xcd#\\xc2K3\\x9d\\xcf+\\x92r}rz\\xfdM\\x16\\xb7\\xb1H\\x8f\\x04\\xeaf\\x8eQ\\xb5\\xc1\\xee*\\x80\\xb63\\xe4\\xb3,q\\xaf_\\xee\\xaf\\xd4\\xf74\\xd3\\\"\\xc5\\xf2[\\xe7\\x93\\x8d\\xe7\\xef7\\xd3\\xd3\\xf9\\xd7=k\\xcdZG\\xbf\\xec\\xa0\\xa3\\xca\\x87f\\xfb\\xc2\\x17\\xdfk\\x885\\xce\\x9b!\\x01\\xf1\\xd8z7\\xf7Xv?\\xfe\\xaa\\xeam'\\xb6\\xd4\\x0f\\xf6\\x86\\x91\\x1a\\xc9-\\xc8\\n\\xcf\\x12\\x93!?\\xdd s\\x9f_Z\\xd2\\xf0\\xaf\\x82\\xb5[\\xc8\\xd6}D\\xb5\\x95\\xa3\\x0f\\xf5L\\xb9\\x91\\xc7\\xfb\\xa7\\x85\\x1f^}\\xaa}k\\xc1\\x1a7\\x87n\\xc6\\xa3\\xa1\\xebw\\x1a\\x15\\xf9\\x1f\\xea\\xe1\\\"D\\x90\\x7f\\xb5\\x19\\xe3\\x1f\\x88\\x15\\xcb\\xf5Y\\xafy\\xaf\\xeb\\xfa\\xff\\x00\\x86<\\x1a\\xf8\\xe8*\\xbc\\x90|\\xcf\\xfa\\xfb\\xcc\\x1f\\x1cx{Q\\x83\\xc2CT\\xbb\\x84#[\\xca\\xbc\\x16\\xcb\\x84n\\x0eq\\xd0goz\\xcc\\xf1?\\x89\\xf4\\xb7\\xf0F\\x8f\\x05\\x92\\xa1\\xbf\\xbb\\x84\\x1b\\x99:\\xb2*\\xf0W\\xdb,;v\\x15\\xa7\\xe2\\x1dg\\xc5Z\\xdf\\x87\\xee4y/\\xb4;\\x88\\xa6P\\x8d>\\xd9\\\"c\\xc8=0Fx\\xac\\xaf\\x06\\xfc1\\xd7\\xe1\\xd4\\x03j\\xbaF\\x9fwa(\\xe5\\xe6\\x91\\x95\\xa3=\\x88\\x05r~\\x98\\xc5E\\xa2\\xdbt\\xd3\\xf4\\xfe\\xbc\\xcc~\\xb1R<\\xbe\\xdfK;\\xae\\xc7M\\xa3h\\xd0i\\xbe\\x1f\\xb6\\x16\\xf2\\xa8\\xb8\\x9e%\\x92bW;\\xc9\\x19\\xc6F6\\x81\\x9f\\xf6\\xbe\\x82\\xa9\\xeb\\x96WZ\\x86\\x8b%\\x84\\x16\\xad-\\xd3\\xc8\\x865G\\x0c\\x17\\x07\\x96\\xf5\\xe9\\x91\\xd3\\xbdv\\xf2i\\xba\\x1e\\x94\\xaa\\xba\\x9e\\xa2\\xa7\\xcbP\\x05\\xbc'hP:|\\xab\\x96\\xfdqX\\x97\\xff\\x00\\x12\\xb4\\x9d\\x19Z\\xd7G\\xd2\\x1b=\\xd9\\x80\\x89I\\xf5\\xe3$\\xfe8\\xae\\xb7\\x86\\xe5\\xa5i\\xbb\\n\\x95j\\xf5gz\\x11r}\\xfa\\x1c\\xdd\\xf1\\xbc\\xd2\\xfc\\x07yi}{\\x05\\xcb$k\\x12$Hw'#\\x00\\x9e\\xa7\\xf2\\x1d*\\xbf\\x84\\xae\\xd2\\xe7@\\x8by\\x969m\\xa5)\\xc7\\x1b\\x94\\xfc\\xc3\\xf0\\xe4\\x8f\\xc2\\xa3\\xd4|w\\xaaj\\xd2~\\xfb\\xc8D\\xec\\xb1\\xc48\\xfcNH\\xfc\\rI\\xa7]__\\xcc\\xa9\\xe7;)=\\x1b\\xe6\\xfeu\\xc1e\\t\\xfb\\xae\\xe7\\xa6\\xb0\\xf5\\xd4/U%\\xd4\\x9f[\\xb7\\xd3t\\xebmC\\xc4\\x9a\\xd4\\x8d\\x7f\\x14q\\xaa\\xdb\\xc1!\\xdb\\x86'\\x01x\\xc6FO\\xe5\\x9a\\xcd\\xf8y\\xa9\\x99\\xec5]wP\\x1fg\\xb0\\x85Dq\\xf9Q\\xe1s\\xd5\\x88\\x00r@\\xda?\\x1a\\xf3\\xcf\\x89~*\\xfe\\xda\\xd5\\xd7L\\xb4\\x94\\x1d>\\xc0\\x95\\x05>\\xec\\xb2\\xf4f\\xf7\\x03\\xa0\\xfcOz\\xf5\\xd6\\xd44\\xaf\\x07\\xf8r\\xd29\\x9c[\\xd8[\\xc4\\x91\\xfd\\xc2\\xdb\\xd8\\x8c\\x9e\\x06rI\\xc9\\xae\\xc7B4im\\xef3\\xc6u^\\\"\\xb3N^\\xe4~\\xe2Ak.\\xb5\\nO\\x1a\\\\A`]d\\xf3g\\xc0\\x92P\\x0eF\\xd5\\xfe\\x11\\xeey\\xf6\\xae/\\xc4\\xd7\\x8f\\x1f\\x8a\\t\\xb1\\xb7p\\xb6\\x85Uv\\xa1\\xc6\\xe0w\\x1f\\xd4\\x9a\\xe8t\\xff\\x00\\x1a\\xc6\\xc8\\x1bA\\xd0\\xf5[\\xdb\\x01\\x96d0\\x84D\\x1dI\\x8d\\x89\\xe7\\xfd\\xdc}1\\xd2\\xa0\\xb0\\xf8\\x95/\\x89$[}&=\\\"\\xc6Wm\\xaau\\x1b\\xa3\\xbc\\x9e\\xc0 Q\\x93\\xf8\\x9a\\xe0I\\xd9\\xceK^\\xa7El\\x81\\x9e\\xe2\\xb2\\x01h\\xa5\\xf3c\\x1f'\\x1eb\\x81\\xd3\\xde\\xb4\\xa3\\x17\\x18Y\\x8a\\xa5I:\\x8ew\\xdc\\xed\\xe5\\xf1T\\xa5#2YZ\\xcf\\x02\\x8e\\x0c\\x882\\xa7\\xd8\\x8eE\\x15\\xc7\\xad\\xd8\\x84\\x8c\\x03\\xf3s\\x83\\xd1\\x85\\x15m3U]\\xf7\\xfc.z\\xe5\\x8e\\x9d\\x7f\\xe2\\x0b\\xc1kg\\x06\\xed\\xbf\\xc2\\xbcG\\x18\\xf5'\\xb7\\xf3>\\xf5\\xea\\xfe\\x15\\xf0F\\x9d\\xa0\\xc5\\x1d\\xd4\\xaa.5\\x0cd\\xcc\\xe3\\x88\\xcfp\\x83\\xb7\\xd7\\xaf\\xf2\\xadk]&\\xdbH\\xb5\\x82\\xcfM\\x80E\\x12\\xe7\\x81\\xceO\\x19f=\\xcf\\xb9\\xaf4\\xf8\\x85\\xe3\\xc6\\xb8y\\xb4M&S\\xf6t\\xca\\\\K\\x19\\xe6S\\xddA\\xec\\xbe\\xbe\\xbfN\\xba5\\x1aQ\\xe6\\x96\\xac\\xdex\\x9a\\xf9\\x95EF\\x8f\\xbb\\x1f\\xd3\\xcf\\xfc\\x8d_\\x18|N\\x8a\\xc9\\xa4\\xb1\\xd1\\x1dd\\x94p\\xf7\\\\\\x15_\\xf7{\\x1f\\xafO\\xafQ\\xcai\\xde\\x1f\\xd4\\xf5\\x89\\x05\\xee\\xb5|l`\\x97\\xe7\\xdd6^i\\x87\\xaa\\xc7\\xf7\\x8f\\xd4\\xfe\\xb5\\xc7Y\\\\\\xdcY\\xcen\\x14\\xc6\\xb2\\x83\\x94b\\xb9)\\xee\\t\\xef\\xef\\xd4v\\xab\\xd1]\\xdejS2<\\xf73n9p\\xad\\x8c\\xfb\\xb1<~'5\\x8d8\\xcb\\x11/{n\\xdd\\x0f^\\x9e^\\xb0\\xd0\\xe5\\xa6\\xd4{\\xc9\\xeb'\\xe8\\xba\\x1d\\xc3\\xf8\\xa3D\\xf0\\xa9\\xf2\\xb4=/\\xed\\x17\\x8b\\xc1\\xbb\\xbdp\\xcc\\x0f\\xb0^\\x9f\\x81_\\xa5s\\xba\\xa7\\x8d\\xb5\\xfd_p\\xb8\\xd4$H\\x8fX\\xa1\\xfd\\xdac\\xd3\\x8eH\\xfa\\x93X\\x176\\xe6)X\\tcU\\xf4V\\xdeG\\xb1=\\x0f\\xe1Ic\\xa7>\\xa1t!\\x8fsaK3\\x1ev\\x81]5\\xa9F\\x9cRk~\\x8bCj\\x18L$S\\xa9nf\\xb7\\x94\\x8bI\\xac\\\\\\xfd\\x9f\\xca\\x81\\xc2\\xa8\\xee\\xab\\xfdzU\\x06/#\\x96\\x92B\\xccz\\x92sVD\\x0e\\xb7\\rl-\\xf3*\\x9c\\x1c\\x02\\xe7\\xfc)&\\xb3h\\x01\\xf3\\xa6\\x8e&\\xfe\\xe1;\\xdf\\xf2\\x1d+\\x82\\xab\\x94\\xd6\\xdbz\\x9d\\xf1\\x94#\\xb5\\xb5\\xec>\\xd2%g\\x00\\x02MZ\\xf1n\\xbd\\x1f\\x86<.\\xf0C ]N\\xf9\\x0cq\\x05\\xea\\x88xg\\xf6\\xe3 {\\x9fj\\x87NYW2*\\x96\\xc7B\\xff\\x00*\\x93\\xeei-\\xfc;\\xa6I\\xa8\\xbe\\xad\\xae\\xcb\\xfd\\xa7z\\xe7\\\"26\\xc3\\x18\\xec\\x02\\xf7\\x03\\xdf\\x8fj\\xc6\\x97*\\x974\\xf6G\\x99\\x99\\xfbj\\xb1\\xf6t\\x96\\xfd{\\x1e{\\xe1\\x9f\\x07j^!\\x9e9V\\x06\\x8bN\\x0e<\\xdb\\x99>U\\xc6y\\n\\x7f\\x88\\xfd?\\x1cW\\xb1_\\xea\\xd2$\\xc4[\\x8d\\xb1\\x81\\xb4\\x06\\xe9\\x81\\xd3\\xadV\\xbd\\xd7\\x1d\\xe3\\x11\\xc4\\x15#Q\\xb5UF\\x00\\x1e\\x80V\\x04\\xf3<\\xacK=:\\xf5\\x1dm\\xd6\\x86yvS\\xec\\x13r\\xd5\\xb3\\xa3\\x87Z\\x9eD\\x95&\\xbdt.\\x8c\\xa1\\xa2\\x03(H\\xc6F{\\x8a\\xcc\\xd3\\xadtO\\x0f\\xc5\\xb7I\\xb3>y\\xebs#n\\x95\\xbf\\x1e\\xdfA\\x8a\\xcbVU\\xfb\\xc4\\xd4\\xdf\\xdaI\\x02eQ\\x06:\\xb3\\x9c\\n\\xc7\\x97\\xa6\\xc7l\\xf0\\x14y\\xb9\\xda\\xbd\\x8d\\x02\\xfa\\x85\\xd4\\x99We\\x07\\xbb\\xf3\\xfc\\xe9\\xcfo$+\\xba{\\xb8\\x87\\xd4b\\xb9\\xf5\\xf1\\x0cW\\x97\\xf0X\\xc7|\\xa6i\\xe4X\\x91#8\\x1b\\x89\\xc0\\xe7\\xa0\\xfc\\xe9\\x9a\\x85\\xdc\\xba|j\\xff\\x00eV\\x95\\xc9\\x19\\x98\\x96\\xdaA\\xc7#\\x8e\\xe0\\xd6\\xca\\x9c\\xbb\\x19T\\xc5\\xe1\\xa9-f\\xb4\\xe8\\xb55\\x92\\xeev\\x94\\xa4Q\\xf9\\xe0wL\\x8ak\\xf8\\x86\\x1b\\t\\xc2M,p\\xcc9R\\xd2\\x83\\x83\\xef\\x8c\\xd6t\\\"\\xe7X\\xf0\\xce\\xa2g\\x92Cp\\x90\\x87\\x8f\\xcb;\\x15N\\x0e@\\x00\\x81\\xd5H\\xe8My\\xa1'\\xc8~\\xa5\\x8b\\r\\xe4\\xfe\\x83\\xf9\\xfeB\\xbaa\\x84oV\\xcf#\\x13\\x9d\\xc3\\xe1\\xa7\\x0b\\xfa\\x9e\\xc3>\\xaf\\xf6\\x19_\\xca%-.G\\x99\\t\\xceU\\x1b\\xd3>\\x98?\\x96+\\x9b\\xd4\\x9fz\\xd6\\xd3|\\xc0\\x0c$\\xc3\\xa3\\xafjqW\\xd1\\x9c\\x18\\x88\\xc5Zkf\\x97\\xc8\\xbfk\\xae\\xea~qC?\\x98\\x8d\\xf3l~A\\x1f\\xce\\xa1\\xb9\\x88\\xb3\\xbb,j\\xf6\\x92\\x9c\\xb2\\xa1\\xdc\\x10\\xfa\\x8fJ\\xcbY\\xe5\\x85\\x93\\x8c:\\x10T\\x8fJ\\xd0\\xfbl2N\\xee\\xc0\\xfc\\xc0|\\xdc\\xf1\\xfa\\xff\\x00\\x8diklc\\x16\\xadf\\xca2\\xda\\\\[\\xab\\x04r\\xf17A\\xd8\\xff\\x00\\x81\\xa1\\x1d%Vx\\xb7\\x07_\\xbc\\x87\\x82+v\\xd9<\\xb8\\xc9\\x8b3@\\xd9\\xdc\\x8f\\xce}H5\\x8f\\xadi\\xafh\\xd1\\xde[\\x0c\\xc0N3\\xddO\\xa3S\\x8b\\xe6vc\\xa9I\\xc2<\\xc8\\xa1+\\x90\\xa5\\x1b\\xb3\\x1c{\\x1f\\xf04S\\xae\\nKm\\x1d\\xcc`p\\x02H3\\xc8\\xf44V\\x91\\xd8\\xe6\\x93\\xb3=\\xf7\\xc4\\x7f\\x145-T<\\x16\\x01\\xac-O\\x1f#~\\xf5\\xc7\\xbb\\x0e\\x9fE\\xfc\\xcdp\\xbb\\xcbp\\xaa\\x14\\x0f\\xc0Pb\\xdb\\x92O\\xe2i\\x87\\xdc\\xf1^d\\xeaNN\\xf2>\\xff\\x00\\r\\x85\\xa3\\x87\\x8f-%o\\xcf\\xe6\\xc5!s\\xf3\\x1d\\xe6\\xac\\xc5\\\"\\x05\\xfd\\xfb\\xb8\\x8f\\xb4q`\\x13\\xf8\\xf4\\x1f\\x91\\xaay$\\xe1E\\\\\\xb6\\x86\\x15p\\xf77\\x1b=\\x90no\\xfe\\xb7\\xf3\\xf6\\xae\\x9a8\\x89\\xad#\\xa26\\x95\\x9a\\xb5\\x87\\xdc\\\\\\xed\\x8fl6\\xf1\\xc2\\xa7\\xfe\\x04\\xe4{\\x93\\xcf\\xe5\\xc5v?\\x0fl\\x84\\xb6:\\xb4\\xb2\\x02$dTRGnI\\xff\\x00>\\xd5\\xcd6\\xa7em\\x19[\\x0b%W\\xef<\\xc7{\\xfdFx\\x1f\\x80\\x15\\xa1\\xe1-}\\xb4\\xedRD\\xb8-\\xe5\\\\\\xe037\\x1c\\x8e\\x9dk\\xa21\\x8b\\x9a\\xa9)\\\\\\xe3\\xc5\\xd3\\xa9,<\\x94U\\xbf=\\xc3\\xc46\\x970\\xcc\\x0ce\\xd1\\xb1\\xf3\\xaa\\x1co\\x1d\\x8f\\xbd`-\\xd0A\\xb6(cC\\xfd\\xed\\xbb\\x9b\\xf5\\xaf}\\xbf\\xf0\\xbd\\xa6\\xa9\\xa6 ]\\xa2@\\x03\\xc5 \\xed\\xff\\x00\\xd65\\xe5\\xbe*\\xf0\\x8d\\xd4z\\xbd\\xbcze\\x8d\\xc3\\xc9p6\\xc9o\\x1a\\xe4\\xac\\x83\\xa9\\x07\\xa6\\xd3\\xd7=:\\xd4b\\xa9\\xc9\\xbex\\x7f^\\x87\\x16\\x032\\xa18\\xfb9\\xbb5\\xdc\\xe4\\x1e\\xe6F}\\xce\\xec\\xc7\\xd5\\x9a\\xacF\\xb7R\\xa6\\xe5\\x85\\xca\\xe3;\\x88\\xc0\\xfc\\xcdw\\xd6\\x1f\\x0eg\\xd3\\xec\\xfe\\xd9\\xacOga\\x1a\\xe38\\x06yI=\\x87@\\x18\\x9e\\x80n\\xae;\\xc4\\x96\\x90Mr\\xc29oL\\x11\\x9d\\xbeSK\\x82\\xc7\\xfd\\xa2\\xb8\\x00\\xfb\\x0e\\x9e\\xa6\\xb0Xkk'\\xa9Us\\x9a\\x11mS\\xd6\\xc6\\r\\xe6\\xa7\\r\\xa9\\\"i\\xe3R\\x06H\\x07q\\xc5f\\xff\\x00m\\xb4\\xe8^\\xd6\\xdei\\x94\\x1c\\x16\\xc0\\x02\\xbam\\x07^\\x97@\\x17\\xb62Cn\\x9a}\\xfayS\\xab\\xc6\\x18\\xa0<\\x16\\xc9\\xeb\\xc7\\x07?^\\xa2\\xb9MKK\\x7f\\x0ej\\xf2\\xc5\\x03\\x13l\\xdf:\\xa9\\xe4\\xf9g\\xbf\\xe0x\\xf6\\xe3\\xb1\\xad^\\x1e)\\x1eU\\\\\\xf6\\xbc\\xe5\\xcb\\x0fu~?\\xd7\\xc8W\\xd5\\xa1\\xba\\x84E\\x0c\\x97\\x91\\xdc\\xb3\\xf9yxTF\\x1b\\xd0\\x9d\\xd9\\x15\\xcd\\xdf\\x7fhC\\xa8H\\xb2\\xdd\\x91p\\x84\\xab)vB\\xbe\\xdf6+\\xb1\\xfb\\x0c\\x00Ez\\x80\\xcd\\x0c\\xc3e\\xc4C\\xf8\\x97\\xb3\\x0fF\\x1d\\xbf\\xfdu'\\x894km_M\\x8eHdO\\xb6\\xc2\\xbbc\\x97\\xa7\\x9c\\xbd\\x94\\xfb\\xfa~UT\\xdcb\\xf6<\\xfcD\\xebVM\\xcem\\x9eu'\\x9a\\xae\\x1d\\xd4\\xabg \\x81\\x8f\\xcb\\x15\\xed\\x97\\xfa\\x85\\xbf\\x88<5\\xa4j\\xado\\xfe\\x91%\\xb2\\x89\\x9f\\xcb\\xc0yFC\\xb7Nrr\\x7f\\x1a\\xf0\\xf6VG(\\xc0\\xab\\x03\\x82\\x0f\\x04\\x1a\\xf5]\\x1b\\\\\\x17\\xff\\x00\\x0f,m\\xb0\\x82m>F\\x83\\x00|\\xcf\\xb8\\x96\\x07\\xf5#\\xf0\\xad+h\\x939\\xb0\\xd1r\\x93\\x82\\xeaV\\xd1o\\xe1\\xd3\\xfc@\\xb1\\xb4\\xab\\x1cl\\xa4\\xbeH\\xe0\\x10p\\x01 \\xe3\\x95\\x07\\xf1\\xac\\xe84;X\\xf5;\\xb9\\xd9U\\xe0y\\x8b\\xc3\\x11\\x19\\xc2\\xe4\\xe0\\x9f\\xcf\\xa5M\\x15\\x8c_m\\x92\\xe8 \\xf3\\xdb\\x82s\\x95Oa\\xefW\\x86\\x14`~$\\xd7\\x15\\\\C\\xb7,\\x0f\\xa6\\xcb\\xf2\\x84\\xadW\\x10\\xae\\xfa/\\xeb\\x7f\\xc8\\xd1\\x81\\xa5kI\\xa6I\\x91d\\x81\\xd2@\\xaexa\\xc8 ~b\\xb9=rX\\xae\\xe0A dU}\\xae\\x0fT=\\x8duz2A=\\xf3[\\xdc\\x12\\x12h\\x99A\\xcf~\\x1b?\\xf8\\xeds\\xbe \\xb2\\x134\\xa2\\\"\\xc6H\\xc9\\x00\\x95\\xc0\\x91G\\xf5\\xefN\\x84\\xee\\x94H\\xcdh\\xdaNH\\xe6%\\x8eHeh% \\x95\\xfb\\xae9\\xe3\\xfc*\\x19_\\x18o\\x98\\x13\\xc1\\xc7@}*\\xd4q\\t0\\x0b\\x1d\\xf1\\x8c\\x8fu\\xf4\\xa8\\xe7\\x8b\\x7f\\xcd\\x12\\xff\\x00\\xbc=}\\xeb\\xa55s\\xc1k\\xb1>\\x9dz\\xf6\\xac\\x08b\\xca\\xfcq\\xfe\\x7f\\x9dt\\r%\\xbc\\xf1m\\x93r\\x87\\xfb\\xca\\xcb\\xc1\\xac-/I\\xbb\\xbfy\\x16\\xd2\\xd9\\xe5eP\\xdb\\x15I\\x0e?\\xc6\\xb4\\x90=\\xb4\\xa2'\\x0f\\x11\\xc6Lr/#\\xe9\\x9a\\x99\\xae\\xa8\\xe8\\xa3&\\x97+\\xd8\\xc7\\xd4t\\xc1f\\xc5\\xd1\\xb7[K\\xd1\\x94\\xfd\\xd3\\xfd\\xd3EhL\\xfb\\x19\\x95\\xc0x\\x1c|\\xfb\\x061\\xeeG\\xff\\x00\\xaa\\x8a\\xb8\\xcd\\xd8\\xc6tb\\xde\\x96G[#\\x03\\xd0g\\xdc\\xf4\\xa8H,y\\xe6\\xac\\x04P\\x83y\\xa4a\\x95\\xe0m_S^kM\\xea}\\xfa \\xe1{\\xd1\\xc9\\xe9\\xc7\\xd6\\x9b$\\x91\\xc6z\\xf2z\\x0e\\xa4\\xd3?}'\\x7f)\\x7f6\\xff\\x00\\x01\\xfa\\xd4\\xd8\\x1c\\xba\\x12\\x19V\\x0c1|\\x1e\\xc4\\xf5\\xfc*\\x1f:Y\\xdc,1\\xb33\\x10\\x01a\\x92I\\xe9\\x85\\x1c\\x9a\\xb3e\\xa5\\xcf\\x7f}\\x15\\x9d\\x8d\\xbb\\xcfu1\\xda\\x8a\\xbc\\xb3~'\\xa0\\x1e\\xa7\\x81^\\xed\\xe0\\xaf\\x87\\xb6~\\x19\\x8d/.\\xc2\\\\\\xea\\xa4\\x7f\\xac\\xc7\\xc9\\x0ez\\x84\\xcf\\xfe\\x85\\xd4\\xfb\\x0e+\\xa2\\x8d9T\\xf4<\\xac\\xc31\\x8e\\x15Y\\xfc]\\x97\\xea\\xc7|8\\xb3\\xf1-\\x8e\\x82\\xb0\\xeb\\xc5\\x04`\\x7f\\xa3\\xc6\\xff\\x00\\xeb\\x95}\\x1b\\xb0\\x1e\\x83\\xa8\\xef]5\\xf0\\x84\\x04\\xb8\\x966V\\x80\\xeeI@\\xce\\xdf\\\\\\xe3\\xb7\\xadG\\xa8\\xeb\\x96:`e\\x9aM\\xf3(\\xcf\\x93\\x17\\xcc\\xf8\\xf5=\\x94{\\xb1\\x03\\xde\\xbc\\x93\\xc5\\xdf\\x10u\\x7f\\x13\\x1b\\xbd\\x17\\xc3v\\x8am`\\no\\xa7I\\x03\\x1c\\x1c\\xe22\\xc7\\n3\\x82\\x08\\x19\\xe0\\x1c\\x1e\\xb5\\xe8\\xa6\\xa0\\xads\\xe3e9U\\xa8\\xea[s\\xa7\\xd6\\xb5{{\\x9dov\\xa5s\\xe4C\\x13yp\\xc6\\x8c\\x1b\\xcb\\x07\\xac\\x9f\\xef\\xb78\\xfe\\xea\\xfb\\x93\\x8ek\\xc6\\xfe!\\xf0\\x9f\\xf6|Vz\\xf5\\xe6\\x16v\\xd3^\\xdc\\xc7m\\x00\\xcb9\\xfc\\x07\\xb9\\xaf^\\xb5Xm\\xbc+\\x0c\\x1b\\x9ei\\xadXC#9\\xce\\xe4a\\x95\\xc8\\xfe\\xefP>\\x95\\xd3Z1\\x85\\xb9O\\x03\\t:\\xd8\\x95)\\xd5\\xd57\\xbf\\x9fc\\xce\\xe6\\xb7\\xdd!\\x90(V\\x03-\\x8e?Jd^`\\x0f\\xb1\\x19\\xb2\\xa0\\x10\\xa35\\xb1\\xac\\xdaD\\xd7(\\x9ayb%P]\\x0f\\xf0\\x9fJ\\xec<-\\xe1\\xcf\\xec\\xebU\\x92\\xe1w\\xdd\\xbfS\\xd7g\\xb0\\xf7\\xad\\xa8\\xd3uv9\\xdd6\\xa6\\xe2cx;\\xc2\\xba\\xdc\\xfa\\x84R\\xf9\\xadc\\x16C\\x9d\\xc4\\x83\\x80y\\xe0v#=i\\xbe4\\xb8D\\xf1t\\xd6\\xdbH\\x82(\\xd1\\x10\\x9e\\xa4\\x7f{\\xf1\\xc9\\xafR\\xb4\\xb6\\x95Q\\xe3D*\\xb8\\xcc\\x8e}\\x05x\\xa7\\x8a.\\xa5\\xbd\\xf1E\\xe4\\xb7\\x00.\\xc9<\\xa5\\nz\\x058\\x1f\\xe7\\xde\\xba+B0\\xa7\\xca\\x89\\x95\\xe0\\xf43\\xaee\\x8a&\\xda\\xec\\xdbs\\xf2\\x9c\\xe0\\xfe\\x07\\xfa\\x1a*\\xbc\\xb1\\x19<\\xb8\\xdd\\x81l\\xe0\\xafq\\xefEr+[S6\\xe6\\xde\\x88\\xef\\x03md]\\xac\\xf29\\n\\x8a\\x01,\\xc4\\xf4\\x00\\x0e\\xa6\\xadk\\x1ae\\xee\\x99r\\xb6\\xd7\\x8c\\x91O\\xb04\\x90\\xa9\\xdc\\xd1\\xe7\\x90\\x1b\\xb08\\xe7\\x1c\\xf5\\x1f\\x87m\\xe0\\x9d\\x11\\xf4(\\xe2\\xd7\\xa7\\xb2[\\xcb\\xdb\\x91\\x9bQ#\\xff\\x00\\xabS\\xd1\\xb1\\x8e\\xa7\\xb7L\\x0f\\xadU\\xd643,o$\\xbb^\\xeeY\\x0bM+\\xf5c\\xc985\\x9cp\\x92t\\x9c\\x8f\\xa8\\xfe\\xd1\\xe6\\xc4\\xaa{G\\xf3\\x7f\\xe4\\xbf\\x1fC\\x84HR1\\xbb\\x1dzg\\x92}\\xcd[\\xb0\\xd3\\xeeu+\\xb8\\xadmai\\xae&m\\xb1\\xc6\\xbdX\\xff\\x00@:\\x93\\xda\\xa6\\xbe\\xb0{i#\\xf38\\xde7/\\xfb\\xbe\\xb5\\xd1\\xe9\\x1a\\xee\\x9b\\xe0\\x93\\xe6\\x1b\\xe4\\xba\\xd4\\xa5\\x03u\\xbd\\x94a\\x8ck\\xd7c\\xca\\xd9\\x03\\xdc(\\xce{\\xf0+\\x9e\\x14\\xbd\\xef{c\\xa3\\x1f\\x8e\\x8e\\x16\\x95\\xe1\\xac\\x9e\\xc8\\xf4\\xef\\x08\\xf8J\\xc7\\xc1\\xfa~\\xf9\\x99$\\xd4g\\x00M>:\\xff\\x00\\xb0\\x9d\\xf6\\x8f\\xd7\\xa9\\xf4\\x0f\\xf1\\x17\\x88#\\xb1\\xb3\\x91\\xa7\\xbe\\x82\\xc21\\xff\\x00=\\xa4\\xda\\xc7\\xfe\\xf9\\xcb\\x0f\\xa0\\xc7\\xfb\\xc2\\xbc\\xc7S\\xf8\\x87\\xaf\\xeb\\x92\\x8b[8\\x1e6\\x91r#\\xb6\\xc88\\xf7n\\xb8\\xf5\\xed^W\\xe2X\\xe4\\xb4\\xbc\\x90Oz\\x93\\xdf0-/\\x97&\\xe5\\x88z\\x13\\xd3w\\xd0\\xd7zzr\\xc7C\\xe2*Js\\x93\\xa9SW\\xd5\\x9d7\\x8c~'\\xc2c{\\x1d\\x1d\\x1aF\\xc9\\xcc\\xf2 H\\xd4\\xfa\\xac`\\x9c\\x9f\\xf6\\x9c\\xb1\\xfck'M\\xf1]\\x96\\x91\\xe18t\\xe8#\\xba73\\x96\\x9e\\xeaf\\n\\x03\\xc8\\xdf\\xf0,\\x90\\x14\\x01\\xf9\\x9e\\xf5\\x89\\xe0O\\x0fE\\xe2?\\x12\\x84\\xbbR\\xda}\\xacmqu\\x83\\x82\\xca8\\x0b\\xc7L\\xb1Q\\xf4&\\xb4\\xbcCec\\xb2v\\xb7\\xb2\\x86\\x14G\\n\\x85\\x17\\x19'\\xff\\x00\\xac*\\x954\\xb4\\x12\\x9c\\xad\\xcd\\x7f#\\x95\\xbd\\xbd\\xfbe\\xdb\\xc8\\x18\\xe0\\x9e3R[\\xdb$\\x80,\\xaa\\n\\x9a\\xa9\\xf6@\\xec@%iB\\xddZ6\\xe8\\xd8\\x95\\x1e\\x9c\\x8f\\xca\\xad\\xf6F(\\xd0m6\\xe2\\xcd\\xfc\\xeb\\x19\\xb7\\x1e\\xe8\\x7f\\xcf5cO\\xd4D\\xf7jdo\\\"\\xe9\\x184d\\xf4\\x0e\\x0eF?\\x1a\\xa9o\\xac\\x03\\x810\\xda}GJ\\xd5\\xb7\\xd3!\\xd7\\n\\xc4\\x81wc>p\\xfe\\x01\\xdc\\x93\\xe9YI\\xb5\\xf1\\x1b\\xd3\\x87<\\x94a\\xab}\\x0e\\xfb_\\x8e;\\xdb\\xeb]R\\x03\\x1a%\\xd5\\xb2\\xcb1n|\\xacz\\x8fS\\xd0}\\x0f\\xa5a$B\\xf5\\x99\\x89t\\xb4V\\xe4\\x83\\xf3J\\x7f\\xba?\\xcf\\x03\\xf0\\x15\\xa5a\\xa7\\xda\\xdc\\xe8\\xce \\xb8e\\xb6\\xb3\\x94&\\x1cd\\xc80\\ts\\xeb\\xcb\\x00\\x07\\xaf\\xb7J\\xf2\\xc8\\x91\\xa8X\\xd7h\\x03j \\xfe\\x11\\xe9\\xf5=\\xcf\\xf9\\x1c\\x95\\xe7\\xa9\\xf4\\x99~\\x16)r\\xc7o\\xb4\\xfb\\xf9/.\\xfd\\xc8\\xa5\\x00\\xb60\\xa0\\x7fuz\\x0fj\\xa1\\xa9j\\x90i\\xb1\\xaf\\x98\\xc3\\xccs\\x85_\\xea}\\xa9\\x9a\\xb6\\xab\\x16\\x95\\x06_\\x0fp\\xe3\\xe5O\\xf1\\xf6\\xae\\x0e\\xe6\\xe6k\\xcb\\x86\\x9ew,\\xecy540\\xee\\xa3\\xe6{\\x1d\\x19\\x9ej\\xb0\\xb1\\xf6T\\xb5\\x9f\\xe5\\xfdv;\\xcdme]6dFO\\xb2\\xdc2\\xb4\\x0cW2I\\xf2\\x8c\\x9c\\xf6\\x1d\\x7f>(\\xf0=\\xca\\xca\\xd3iNK\\x89\\x95\\xe2e\\xe4\\x8d\\xa5K\\x03\\x8e9\\x18~\\xbe\\xb5=\\xac\\xff\\x00n\\xf0n\\x9b\\xa9\\x85\\x0f\\xf6=\\xd6s\\x81\\xd5x\\x01[\\xf2\\xdb\\\\\\xff\\x00\\x87\\x1ehu\\xfd\\xe8\\xcaX+;q\\xecT\\x1f\\xfcz\\xba\\xe3jw\\xbfC\\xe7\\xaa)\\xd7\\xa9\\x15\\x17w-\\x0bzu\\x9cz\\x05\\x8c\\xf7s\\xa8\\xf3\\x8ex'\\x903\\xc2\\xff\\x00\\x9f\\xe9Sx\\x0e\\xf5\\xb5\\x1dr\\xfa\\xce\\xeeo\\x9bQ\\x88\\xec\\xc9\\xc0\\xf3S\\x0c\\x9f\\xa0#\\xf1\\xac\\x9f\\x16^3\\xdcGh\\xa4\\x85A\\xbd\\xbd\\xc9\\xff\\x00\\xeb\\x7f:\\xcf\\xf0\\xfc7\\x17:\\xed\\x84V\\xa4\\x89\\xbe\\xd0\\xae\\x18\\x7f\\x0e\\x0es\\xf8b\\x95*nqr\\x96\\xf2\\xfe\\x91\\xbe;\\x10\\xa9V\\x86\\x1e\\x8f\\xc3O\\xf1}OQ\\xd0t\\xa6\\x9fYv+\\x9d\\x83\\xfdY\\x1c\\x86\\xcf\\x03\\xf9\\xd7\\xb8\\xe8\\x1e\\x13\\x82\\xd2\\xd1%\\xbbP\\xd7\\r\\xce?\\xbb\\xed\\\\%\\x83\\x05\\xd4\\xc4\\xab\\x19V\\x92M\\xcd\\xe5\\xaf\\xcc\\xc7\\xdb\\xdf\\xb5z\\xc5\\x84s\\xf9\\x08\\xf7*\\x11\\xb1\\xf2\\xc4\\x0eB\\x0fs\\xdc\\xd7di\\xba4\\xd4z\\x98ck6\\xfd\\xdd\\x0c=V\\xda \\xafim\\x18P\\xbf4\\xcc?0\\xbf\\xd4\\xfe\\x1e\\xb5\\xf2\\xde\\xb5\\x8b\\x8dN\\xf5\\xe3P\\xdek\\xb3u\\xe9\\xc9\\x1f\\xe7\\xeb_Rx\\xdfW\\xb4\\xf0\\xef\\x85\\xaf\\xaeX\\xaa\\xcf*4p\\xafvv\\x18\\xcf\\xf5\\xaf\\x96%\\xb7d\\x06V\\x1c\\x87$\\xb6q\\xc1\\xff\\x00\\xeb\\x8f\\xd6\\xb1\\xad+\\xa4\\x88\\xa4\\xdc\\xa3\\xb1V\\xddY%\\x95X\\x86\\xd87g\\x1c\\x95\\xf4\\xa2\\xa3\\xbb\\x97d\\xbb\\xd7\\x91\\xb5A\\xe3\\xa8\\xc5\\x15\\x87-\\xca\\xf6\\x9c\\xba#\\xec\\x8d:;Qi\\x04\\x8d\\x1a\\xaf\\xee\\xc0@G;}q\\xdb?\\xe1^\\x7f\\xe3;\\x9bXn\\xbc\\x88\\xce\\xf9K\\x17\\x91W\\xf8FO\\xf5\\xaa\\xff\\x00\\xf0\\x92\\xeaV\\xd6l\\xe9(i$_\\xbe\\xe3%~\\x9d\\x85r\\x12M$\\x973\\xca\\xee\\xcc\\xef\\xcb\\x12z\\x93\\xcdu\\xd5|\\x8b\\x97\\xb9\\xe9e\\xb8\\tJ\\xb3\\xaa\\xde\\x8b\\xa1\\xc6x\\xc7U\\x96R, '\\xcd\\x98\\x82\\xfbz\\x81\\xfc*>\\xb5\\x7f\\xc3>\\x17\\x87B\\xb0\\x1a\\x8f\\x8a\\xef\\x1a\\xd6\\x069\\x8e\\xc6<\\x19\\\\\\xfa\\x1f\\xee\\xfd\\x07>\\xb8\\xae\\x87B\\xd3\\xedm|-7\\x8a\\x84\\t&\\xaad\\x91Q\\xe4\\x19X\\xc0\\xfe\\xe8\\xecO\\xafZ\\xf3H/'\\xbeIond2NX\\xe0\\xb1\\xc8P{\\x01\\xda\\xb9>$\\xe2\\x8e,m\\x7fi_\\xda\\xcb\\xd1.\\xc9\\x1d\\xaf\\x88\\xfch\\r\\x97\\xd9\\xb4\\xbbe\\xb0\\xb19\\xfd\\xda\\xe0;\\xfao=\\xcf\\xe2k\\xcd\\xf5+\\x9e<\\x859c\\xcc\\xad\\xea}?\\n\\xd3\\x8e\\x11;\\xdb\\xbc\\xae\\xceL\\x80`\\x9e1YW\\xd1\\xab\\xea\\xf2\\xc7\\x8c(8\\x00}+jQIhy\\x95$\\xe4\\xf5=?\\xe1\\xbd\\x87\\xd8<\\x0b\\x7f\\xa8\\xb7\\xcb.\\xa3r!\\x8c\\xf4>\\\\c'\\xf0,\\xc3\\xfe\\xf9\\xab\\xbe<\\xd3\\x86\\x9do\\xa7i\\xa4\\r\\xe2\\xdf\\xed\\x13\\x0cr$~p~\\x8a\\x14V\\xdf\\x86ma\\x7f\\n\\xf8V\\xd0\\xa0\\x10\\xbc*YGr\\xd2\\xb6k3\\xe2<\\xee\\xfe-\\xd5\\x19\\xb0v\\xbe\\xd1\\xec\\x00\\x00\\x7f*Qwl\\xd2Q\\xb4\\x12<\\xa9\\xe2\\x119\\x00\\xf3P3\\x8d\\xd8\\xe8i\\xf7n\\xdfho\\xadC\\x17\\xcd\\x92y5M\\x18\\xa68Y\\x8b\\x97T\\x11\\x92\\xccp1\\xd6\\xb6\\xfc\\xab\\xabK8\\xb4M\\x16#-\\xd4\\xf2(\\x9d\\xd4e\\xa4bp\\x10{s\\x8aM%BZ\\xdc\\xdc\\x01\\xfb\\xc8\\xd4\\x05>\\x99\\xef]\\x1f\\x83\\xe3\\x11=\\xe5\\xead\\\\D\\x80F\\xdf\\xdd\\xdd\\xc1#\\xdf\\x19\\x1f\\x8ds\\xcaz\\xbb\\xec\\x8f[\\x0fG\\x96\\x11P\\xf8\\xaau\\xec\\xb6\\xfb\\xdf\\xe4i^\\xc2t\\xcbh\\xf4\\xb5tf\\x88\\x07\\xba\\x96?\\xbb$\\xb8\\xc1\\xc7\\xa8\\x1c\\xaa\\xfe'\\xbdc\\xdc\\xcem\\xa1\\x92q\\x13;\\xaa\\xe4(\\x19\\xda=Mh;\\x19e\\xf9\\xf9\\xf9w\\x9fs\\xc5k\\xf8ESV\\xf0\\xbe\\xad\\x05\\xca/\\xde\\xdc$A\\x87\\x07` \\xe7\\xd8\\xf4\\xaexR\\xe7\\x93m\\x9e\\xe6*\\xba\\xc0a\\xe3\\x18-v_\\xe6x\\x95\\xf5\\xcc\\xb7w\\x92M)%\\xd8\\xf7\\xaa\\xf5\\xa7x\\xabqg\\xf6\\xd6EYL\\x9b[`\\xc0n3\\x9cz\\xfd+7\\x15\\xe9A\\xabh|uK\\xb97'v\\xce\\xdb\\xc1\\x97\\x89k\\xe1\\xedXJ\\xae\\xe9#*\\x88\\xc0$7\\xca\\xdb\\xbf\\x1f\\xbb\\xf9T>\\x1cE\\x96\\xfa\\xf2\\xe4#*\\xecEM\\xde\\x87'\\xfaU\\xbf\\x87\\xc4\\xbd\\xa5\\xfa\\x12v\\xa4\\x91\\x90=\\xd9_?\\xfa\\x08\\xad\\x1bx#\\x8a\\xff\\x00P\\x080<\\xc58\\x1fL\\xd7\\x05y\\xd9\\xce>\\x87\\xd1e\\xb4\\xb9\\xa5B}\\x15\\xff\\x00S\\x9d\\xf1\\xde\\x9alu[y\\x94f)\\xe0R\\x18\\x03\\x82G\\x07\\xaf\\xbf\\xf3\\xa9\\xfe\\x1aC#\\xf8\\xa3\\xcdP<\\xb8\\xa1b\\xe4\\xaez\\xe0\\x00=\\xf3\\xfc\\xabS\\xc5\\n\\xb7\\xbe\\x08\\x82\\xe2e\\x06X$\\x01\\x18u\\xc1\\xe3\\x19\\xfc\\xbf!\\\\\\x04\\x177\\x16\\xe1\\xc4\\x13\\xcb\\x10q\\x86\\x08\\xe5w}q\\xd6\\xbd\\x1am$\\x99\\xe0\\xceMVr\\x96\\xf7>\\xb0\\xf0\\xd3\\xd8X]\\x1b\\xab\\xdb\\xebX\\x1d\\x17;$pd\\x03\\xfd\\xde\\xd5.\\xbd\\xf1\\x7fA\\xd2\\xf6\\xc5e\\xbe\\xf2i\\x1bj66\\xc6\\x0f\\xb9<\\xfe\\x95\\xf3\\x87\\xc3\\xb9\\xdd|e\\ngr\\xcf\\x14\\xb1\\xc9\\x9e\\xe3a?\\xcc\\n\\xe8o\\xed\\xe3\\xb8\\x17K*\\xee\\x03\\x91\\xec@\\xcei\\xcanrf\\xb2JpU_{X\\xbf\\xe3o\\x13_k\\xd2\\x89o_s\\xbf\\x08\\xa3\\x85U\\xe7\\x80+ \\\"\\x8bdI\\xe3!\\x19x\\xc1\\xfc\\xff\\x00\\xcf\\xd2\\xa94\\xcd