From fa9601b9263dcf2ab9aa83b050bb4568bbd8bf37 Mon Sep 17 00:00:00 2001 From: Pfaeff Date: Wed, 2 Aug 2023 20:49:03 +0200 Subject: [PATCH] tmp --- .gitignore | 160 ++++++++++ .gitmodules | 3 + LICENSE | 21 ++ README.md | 21 ++ __init__.py | 17 ++ install.py | 19 ++ pfaeff.py | 279 ++++++++++++++++++ pixeldetector | 1 + requirements.txt | 2 + workflows/SDXL_pixelart.png | Bin 0 -> 30245 bytes .../SDXL_pixelart_preserve_aspect_ratio.png | Bin 0 -> 22137 bytes 11 files changed, 523 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 LICENSE create mode 100644 README.md create mode 100644 __init__.py create mode 100644 install.py create mode 100644 pfaeff.py create mode 160000 pixeldetector create mode 100644 requirements.txt create mode 100644 workflows/SDXL_pixelart.png create mode 100644 workflows/SDXL_pixelart_preserve_aspect_ratio.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68bc17f --- /dev/null +++ b/.gitignore @@ -0,0 +1,160 @@ +# 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/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8c68db9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "pixeldetector"] + path = pixeldetector + url = https://github.com/Astropulse/pixeldetector diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..927fe62 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Pfaeff + +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..9af96b4 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# pfaeff-comfyui + +Work in progress + +## Installation (not tested, yet) + +1. `git clone https://github.com/Pfaeff/pfaeff-comfyui.git` in `ComfyUI/custom_nodes/` +2. Restart ComfyUI, installation of dependencies should happen automatically + +## SDXL pixel art example workflows + +Simply drag one of the images into ComfyUI after installation. + +### SDXL Pixelart workflow with background removal + +![SDXL Pixelart workflow](workflows/SDXL_pixelart.png) + + +### Aspect ratio preserving SDXL Pixelart workflow + +![Aspect ratio preserving SDXL Pixelart workflow](workflows/SDXL_pixelart_preserve_aspect_ratio.png) \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..610069c --- /dev/null +++ b/__init__.py @@ -0,0 +1,17 @@ +import os +import importlib + +def install_dependencies(): + spec = importlib.util.spec_from_file_location('pfaeff_install', os.path.join(os.path.dirname(__file__), 'install.py')) + pfaeff_install = importlib.util.module_from_spec(spec) + spec.loader.exec_module(pfaeff_install) + +try: + import diffusers + import cv2 +except: + install_dependencies() + +from .pfaeff import NODE_CLASS_MAPPINGS + +__all__ = ['NODE_CLASS_MAPPINGS'] \ No newline at end of file diff --git a/install.py b/install.py new file mode 100644 index 0000000..b9e38c5 --- /dev/null +++ b/install.py @@ -0,0 +1,19 @@ +import sys +import os +import subprocess + +if sys.argv[0] == 'install.py': + sys.path.append('.') + +pfaeff_root_path = os.path.join(os.path.dirname(__file__)) + +if "python_embed" in sys.executable: + pip_install = [sys.executable, '-s', '-m', 'pip', 'install'] +else: + pip_install = [sys.executable, '-m', 'pip', 'install'] + +requirements_txt = os.path.join(pfaeff_root_path, "requirements.txt") +if os.path.exists(requirements_txt): + subprocess.run(pip_install + ['-r', 'requirements.txt'], cwd=pfaeff_root_path) + +subprocess.run(['git', 'submodule', 'init', '--init', '--recursive'], cwd=pfaeff_root_path) \ No newline at end of file diff --git a/pfaeff.py b/pfaeff.py new file mode 100644 index 0000000..291a7a4 --- /dev/null +++ b/pfaeff.py @@ -0,0 +1,279 @@ +import os +import torch +import nodes +from nodes import MAX_RESOLUTION +import cv2 +import numpy as np +from PIL import Image +import tempfile +from collections import Counter + +from diffusers import StableDiffusionInpaintPipeline +from diffusers.models import AutoencoderKL +import subprocess + + +class AstropulsePixelDetector: + @classmethod + def INPUT_TYPES(s): + return {"required": { "image": ("IMAGE", ), + "max_colors": ("INT", {"default": 128}) + }} + RETURN_TYPES = ("IMAGE",) + FUNCTION = "run" + + CATEGORY = "Pfaeff/image" + + def __init__(self): + current_script_dir = os.path.dirname(os.path.realpath(__file__)) + self.pixeldetector_path = os.path.join(current_script_dir, 'pixeldetector', 'pixeldetector.py') + + + def run(self, image, max_colors): + + if image.shape[0] > 1: + raise Exception("Batches are not supported since output images can have different resolutions!") + + numpy_image = (image[0, :, :, :].cpu().detach().numpy() * 255.0).astype(np.uint8) + + # Create a temporary file for the input image + temp_input_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False) + temp_input_path = temp_input_file.name + Image.fromarray(numpy_image).save(temp_input_path) + temp_input_file.close() + + # Create a temporary file for the output image + temp_output_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False) + temp_output_path = temp_output_file.name + temp_output_file.close() + + # Construct the command for calling the pixeldetector script + command = [ + "python", self.pixeldetector_path, + "--input", temp_input_path, + "--output", temp_output_path + ] + if max_colors: + command.extend(["--max", str(max_colors)]) + + command.extend(["--palette"]) # TODO make this a parameter + + # Run the command + subprocess.run(command) + + # Read the processed image + processed_image = Image.open(temp_output_path) + processed_image = np.array(processed_image) + # Close and delete the temporary files + os.unlink(temp_input_path) + os.unlink(temp_output_path) + + # Convert back to torch + image_result = torch.from_numpy(processed_image).float() / 255.0 + image_result = image_result[None, :, :, :] + image_result = image_result.to(image.device) + + return (image_result, ) + + +class BackgroundRemover: + @classmethod + def INPUT_TYPES(s): + return {"required": { "image": ("IMAGE", ), + }} + RETURN_TYPES = ("IMAGE",) + FUNCTION = "run" + + CATEGORY = "Pfaeff/image" + + def detect_most_common_color(self, image): + # Reshape the image to be a list of pixels + pixels = image.reshape(-1, 3) + + # Convert pixels to tuples so they can be hashed + pixel_tuples = [tuple(pixel) for pixel in pixels] + + # Find the most common color using a Counter + most_common_color = Counter(pixel_tuples).most_common(1)[0][0] + + return np.array(most_common_color) + + + def run(self, image): + batch_size, height, width, channels = image.size() + + if channels != 3: + raise Exception("Input must be a 3-channel image") + + image_result = torch.zeros((batch_size, height, width, 4), dtype=torch.float32) + + for b in range(image.shape[0]): + numpy_image = (image[b, :, :, :].cpu().detach().numpy() * 255.0).astype(np.uint8) + + # Find the most common color in the image + most_common_color = self.detect_most_common_color(numpy_image) + + # Create an output image with an additional alpha channel (shape will be (height, width, 4)) + output_image = np.zeros((numpy_image.shape[0], numpy_image.shape[1], 4)) + + # Iterate through the image and set the RGB channels to match the original image + # If the pixel matches the most common color, set the alpha channel to 0; otherwise, set it to 255 + for i in range(numpy_image.shape[0]): + for j in range(numpy_image.shape[1]): + if np.array_equal(numpy_image[i, j], most_common_color): + output_image[i, j, :3] = numpy_image[i, j] + output_image[i, j, 3] = 0 + else: + output_image[i, j, :3] = numpy_image[i, j] + output_image[i, j, 3] = 255 + + image_result[b, :, :, :] = torch.from_numpy(output_image).float() / 255.0 + image_result = image_result.to(image.device) + + return (image_result, ) + + +class InpaintingPipelineLoader: + @classmethod + def INPUT_TYPES(s): + return {"required": { "model_name": ("STRING", {"default": "stabilityai/stable-diffusion-2-inpainting"}), + "vae_name": ("STRING", {"default": "stabilityai/sd-vae-ft-mse"}), + }} + RETURN_TYPES = ("INPAINT_PIPELINE",) + FUNCTION = "load_inpainting_pipeline" + + CATEGORY = "Pfaeff/loaders" + + def load_inpainting_pipeline(self, model_name, vae_name): + vae = AutoencoderKL.from_pretrained(vae_name) + inpaint = StableDiffusionInpaintPipeline.from_pretrained( + model_name, vae=vae + ) + + if torch.cuda.is_available(): + inpaint.to("cuda") + + return (inpaint,) + + +class Inpainting: + @classmethod + def INPUT_TYPES(s): + return {"required": { "inpainting_pipeline": ("INPAINT_PIPELINE", ), + "image": ("IMAGE", ), + "mask": ("MASK", ), + "text": ("STRING", {"multiline": True}), + "num_inference_steps": ("INT", {"default": 20}), + "guidance_scale": ("FLOAT", {"default": 8.0}), + }} + + RETURN_TYPES = ("IMAGE",) + FUNCTION = "inpaint" + + CATEGORY = "Pfaeff/inpainting" + + def inpaint(self, inpainting_pipeline, image, mask, text, num_inference_steps, guidance_scale): + + extra_kwargs = { + "num_inference_steps": num_inference_steps, + "guidance_scale": guidance_scale, + } + + image_result = torch.zeros_like(image) + + for i in range(image.shape[0]): + + numpy_image = (image[i, :, :, :].cpu().detach().numpy() * 255.0).astype(np.uint8) + init_image = Image.fromarray(numpy_image) + + numpy_mask = (mask.cpu().detach().numpy() * 255.0).astype(np.uint8) + mask_image = Image.fromarray(numpy_mask) + + inpainted = inpainting_pipeline( + prompt=text, + image=init_image, + mask_image=mask_image, + width=image.shape[2], + height=image.shape[1], + **extra_kwargs, + )["images"] + + image_result[i, :, :, :] = torch.from_numpy(np.array(inpainted[0])).float() / 255.0 + + image_result = image_result.to(image.device) + + return (image_result,) + + +class ImagePadForBetterOutpaint: + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "image": ("IMAGE",), + "left": ("INT", {"default": 256, "min": 0, "max": MAX_RESOLUTION, "step": 8}), + "top": ("INT", {"default": 256, "min": 0, "max": MAX_RESOLUTION, "step": 8}), + "right": ("INT", {"default": 256, "min": 0, "max": MAX_RESOLUTION, "step": 8}), + "bottom": ("INT", {"default": 256, "min": 0, "max": MAX_RESOLUTION, "step": 8}), + "inpaint_radius": ("INT", {"default": 5, "min": 3, "max": 128, "step": 8}), + } + } + + RETURN_TYPES = ("IMAGE", "MASK", "IMAGE") + FUNCTION = "expand_image" + + CATEGORY = "Pfaeff/outpainting" + + def add_padding_and_create_mask(self, image, left, top, right, bottom): + # Add padding around the image + padded_image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=0) + + # Create a mask with same size as padded image + h, w = padded_image.shape[:2] + mask = np.zeros((h, w), dtype=np.uint8) + + # Set the padded region in the mask to 255 + mask[:top, :] = 255 + mask[-bottom:, :] = 255 + mask[:, :left] = 255 + mask[:, -right:] = 255 + + return padded_image, mask + + + def expand_image(self, image, left, top, right, bottom, inpaint_radius): + batch_size, height, width, channels = image.size() + + image_result = torch.zeros((batch_size, height + top + bottom, width + left + right, channels), dtype=torch.float32) + mask_result = torch.zeros((height + top + bottom, width + left + right), dtype=torch.float32) + + for i in range(batch_size): + img = (image[i, :, :, :].cpu().detach().numpy() * 255.0).astype(np.uint8) + + img, mask = self.add_padding_and_create_mask(img, left, top, right, bottom) + + inpainted = cv2.inpaint(img, mask, inpaint_radius, cv2.INPAINT_NS) + + image_result[i, :, :, :] = torch.from_numpy(inpainted).float() / 255.0 + + if i == 0: + mask_result[:, :] = torch.from_numpy(mask).float() / 255.0 + + image_result = image_result.to(image.device) + mask_result = mask_result.to(image.device) + + masked_image = torch.zeros_like(image_result) + for i in range(image_result.shape[-1]): + masked_image[:, :, :, i] = image_result[:, :, :, i] * (mask < 0.5) + + return (image_result, mask_result, masked_image) + + +NODE_CLASS_MAPPINGS = { + "AstropulsePixelDetector": AstropulsePixelDetector, + "BackgroundRemover": BackgroundRemover, + "ImagePadForBetterOutpaint": ImagePadForBetterOutpaint, + "InpaintingPipelineLoader": InpaintingPipelineLoader, + "Inpainting": Inpainting +} \ No newline at end of file diff --git a/pixeldetector b/pixeldetector new file mode 160000 index 0000000..6267db4 --- /dev/null +++ b/pixeldetector @@ -0,0 +1 @@ +Subproject commit 6267db449241135515a6252f46db119f446683b0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..36c27aa --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +opencv-python-headless +diffusers \ No newline at end of file diff --git a/workflows/SDXL_pixelart.png b/workflows/SDXL_pixelart.png new file mode 100644 index 0000000000000000000000000000000000000000..e0b4b86d8426370791dfd7b0053b1ddfeb4ba8d6 GIT binary patch literal 30245 zcmeIb2UJu`(=I#&K~cbff*^v3peSjE8FCOrMWW;=amX+TGeikyK?M~-$q168ARtLl zQ6wWd2pGswBuT!#hpgy1=RMzh|L>9?hH8@Eg1|3BbPdR zN)ZMlPyv5oTS-6*k$jgq47T+nR#F{nV~eq}!NOda;7kIHE=*?DHaM&u{-dFV4OZ7$ z-wF-BG1(dEI$G))=-Z)nxjDEv?DUP%ShTer#@3F>^#mi6p{2f^oi5hN2LG^xDH;sM zm|0_GF#1MlTO~6q8%s3)LB!9iIG7n>O+lj;6E`>02}Uj*Fqheb1*>f6{jG1_6BEX|zJ zMvUhAh8B#rI6FJEr6nWQ*31xNiLpJwXkcc-h;~BTonYif8JJ-iZOk0emio5X6O3kd z7%MdNARw3tKey$7XKq7FGaE3o783#mmg3ggg#R*93d&%2lGcV8Bec>fbs0SG0fT=! zVpV-h9CTvbTyP!^u3smTvc{rK(6&pXe-V&>G@9q5GZaW3c7gH3V#fE#`6EX?vl_g2`4wt z%K6#rFU<~34&OvsRZmKuLPL6rKQ1`e&$HqWetA-U{G`7Us9=k>H$ywD5eIbRr&C{5 zR^(qPI^wrx0{#~!0`Yqj@t2Dte@8IiW$f?;3${f)T+orEt}b489>RB2V5fc7ge;< zchto@7U+Dr;e25Ab$b50(>@6Z$JpR3?a&I4_c;YTu^|?-WTg?mXoIntC9tkmXk8my zw6U2ZScpjiV`c25A_b^kT5j2%E}5KPrAtZQ9=%Sqev$h%k`cd~LL7Kg6I%?<+DH*? z1(`}bLwJ6X(!Wpa@0hcWSl459TOY$KE)z#`~D1ZZ1@IKR4B&Nj9vQ?C( z<-)Xr(D2d-`qonjoiMa1FbstR6RthI41U%;hXRYv4O5-$NgKvxVbl{Y;D}XAZ-IB8&LRf>EYd+ zoSz5(3!=aR8|3OIxnGJE*0#SQUK`Jo`**_s^YDK`sH+Yj6@$Yr2VCn^Swdd!l$5fR zyxg)vuF&{%JEYopg9Bf(G$4e5v<|XU8(6@FUkXHeHfUR{8Q!M3Fv$UP!U!ofqcO&o zQHeznjKr(wCXvIEXxr)9L-7KB#U+_t`VB-D{H$;JFGN)T!!a7fd%Wj`c6}HQkPB!q zFj;FtAQ6y{S~mUMkld~w!=G(G@Z#(|C}@HI5z~(Z6a7omkHT-{R|CGXpLzUL@cZlAD7U z#SQ1;w^Psr+5q!{= zHdQEmz_J#aZh9PR0ApnrYb|TX0VrN3aeZ6}&A*8c`=5d$cp1W)VL|p8AVIn194w;( z{#pdj-VLyM^OODO)((>76<(}l*+J9lS#tCLbe3==e8XY#|C(G_Gl0n79~WMQ{^Gcn z&D|<}YoRV4`}5<)=+A1i%274^{SLIX4Sd`@{8)N;a~?zS1(Y>dNyb2Ou}b0cJ;fRa z5pWI^l7}A&6alCMKNku}HaocFfFt;L`Qdyh6cV~mz;9%uKCEcKA6N)s&vhPTQ;Giz z79#(S%Ucs&(a77Hex+5k-%&5ZbfQ9L|+{K!ps`>)ORPZ`BcIlpG4S2nWNvSzkH=#Q7?|DurwtlT7_v8o>m z%lB#j)N22KoKt}8$O>cs-~-ml27(vG!Oz3P#S7=>Lm-jd+)D`NA6qa;HvgpsL;RhT z)9MMGUAoZ+%l;iVu>ADqO7@cav zj$@l8;Gymf8EaYjQ<5?egn)DfpbLOm*T>9&u%%mI@WjdnHp}pVk?@U4-_@JqzcF&- znj0>Y*NxtYj-eHKH_*E7R({>6jbRbuH#wP&WB-Ws@mTVwG&naO4-bH-KQYB zgZuYQ(&8KUxl|?aTT&qpwi&2g9ri~m;cH~#(G)%)!Pf=+9JLvO!i051oR*P4x&GDw z`I|h$^00M8tc+ZLZ2$#UKi?SuDmLK_>fZ)ROWys@PWJC8_AmOmxr&35i{)|H99K^hGF4zObo7k;VkSS{!PC$&W(mUfk<1{S?vQ z3KP3N=t3Y-cx=RngahXd{sJ3=;{Uyk)`B7|I39OyZfAai=bPD?^%BLl&b%NHzdz>n zW7cWyQYs&;3FRcX0V}zIL@trHiNF2ngzZc*4)XZx3+ToG*bHNRa3u}cYl^WobH-R> zK}pSW=6Zf|^KRhh`ncyW*@@TGwP@#`uoKeFO_;DLQ2G;l zLF^9Fo{*?Qmk4kqB!HXD`#-{51mxIPxVuy%0UDM);4+L~VJ&pra4wz=yv5VDxp(|S zJOpJY*7?RwIkaNH)~H)=3-NM@{6}%6gs};ulA-=m(b!MS+x%*4b-?CEhi@HrhYZaM z8-G*GxW-qY`p}IJ0RNzE!z+{}uOEk;Dp7s|~9#9JQ3(`Mr%^4?Un; z`1LZo@_lW#Kcl;iclDrxY5io&UsvaX|M^_O9XG_wzmXmI%}H#2oPVlVg%A2O@h3T=GHnBJ4cee~N;+;eSX2sX1*e+@6;fD>yK9)DF2@&|9RDqVjN zx4%kYtS4nfyjG@L`MxS5P<95jl#ThF0CWFsFssyO8mstFKp8;s)UTl} zoEviI5N~+?ph`d4)6G9RvT8O z9|5+7TH5aKr2p@q%^FMp;lbd;w^bs4O{j8jOacO%2r^aN>l3P6h(FoCKLCiIh48+u>MAwFDn043z$}_AA_*yk0Xk5WzTzJ3$ zNBwFG_>jCDP{t2jy?{HH)!P_eBp(NeE#TZJUVap~q=AUoG<;Z!O#h5`|Jo9u!0jVM z?gp2<`NmgENudF2R)FW%dK%P*dK!HF#)`20K0C^V{OJ~imkYJ-76h?L27k>+@In4? zb3Q>fXq~(LPXrEu$6K4^Jpb>cJC+Q>sz572?@Rp6GXr(0KfhD~>Vm=e^+F6;(UtT0 zUA-~1-V*-d=EqmO@^JqN1M~jDgZ*?Mn;Gq;D&uuzZ7`(33ZpirtZYDRfL#jKS2iLp zFTXw?XN|M81oLeO#+G2l<^r+eFjuDAKmb03K>^)I{Tc55eM|m3wr{S9pnCit>L9-E zd1Wt~8Y+GW`Le^2OUP_JXjzMF{$SSeO1@6betW8a#3i6k8rs-@(;6YxW0GG>)z{=4 zj({>e0LI}l;)Ymn&F=gG=i}?@{tidhV~q`B2FdxqLmSJLGyfiG{K_auGXL5MK&QEi zeY5~S0r&?92qfB|>dG^noow zefSfBk}&u#h?1oN%bZz14lK4jVwrq=^o$<|#w>R&A0)nhdudMS5SI9hSUTi&?1J3X zaw~*ZAwt)9iGp^xGz7AX8#|#q$8sy=KGt;tf|#H;e3o9$bYWVBCQvB?WX=qrw|~s6 z@$ZZ9@B>z`gHk0xBo6}m&9zj*zGgiT#=Ly|_;=#g&7}l9I+z0QFV@e;j^F{zVF$$> zKwh~3)u00KCwItq^5jxM)hc25m!}vN(6+|l^{JmJnv!C8H;lkuW>7)AVf96Jl{0#zTj;X&g9{#%%GdtAnAqr?NYy$3Oip=bzr;G z{0Sk(bIjF+`Zv81#fJ^Ac7OLL-v)bG@MBVBV9MMNt}`&ynmiY8l!FroLnpc zBeG(0nQ3n3xs|a8tB}1g=zJifGN>|;U}WQxyDtu*tPo&$!nf;-)1Hb6h9X;7k?u!h zZ`sxqa*s+7;;Z|^yb+N@vbkOu`o9KXaH+=GqH*-Q;E_1BcE-BK~ z`|tY5VT^tid&c*M{csY}|3ZHZRugd0F0Ulzg8lxRV#oW#h*drd4D>o8MRU6O>@*q~ z2<(Tv2);!w$XvvjBr*gc+DDZaN6G17<@9vi#hI*GyC&mXGoKHh!N~I#hdOR;>!Z0G zeKe(@&f40g;e&7AP#;S7QEfF1O!?SJQo{n>Eu%6lJ{=?awfk_QK72xp5ArD(;^MsY zBL{BDO`Hn(V0KWx$p{N;ZX!5x*&r7EHJf0uTs?YRiA`mx}GjP*2XWXV?{29zrzPtR`!laS6 zx+eOzRyv!bRhxN|!_2Lj`UyJJFrjky&}fk>$2ma3I%7>48BeE6~%ER5XCnMGAr#pQi^`s zL!Wp$BSeNqYXOT0vWVahM)xO|MuyQY zXQu5L!gzHaJn6ekO|Ot}ku3SD%CT_qiDDzlSj{NSXko2JLfP}+r}&Ot_?(+hiNc$T z>tzOxQqeh-asHn**oDN%;}2ZCSIS}GbXj1_jW<34M1_Kwz2+`-9RoZuZ&c-DRBrG+ zNeJp@!A+|da5O6txS|y%p)*C)X@w4~LW8OZK$?QeV`b?=Dz-7|C z*V`_}{88+AiITDlv5Z(o`lNFUg9Tf_iJ8G0mqbpY8c(5mgnCi>mS)DZ(mer!sMq^_ zgAu9fuF3WJh?^LgS3%)*j;?F$FO)W;RE4M(FkE}TkR(|?C4mZ zVP7(*c8^_`A{?s>lz5qbKR>|NPp~2s>^0Ea@olrdT-Wti&ow;nznLyLdB?m}5H3SA zz#7u``G-$zI5AN|7yrdl)g+C23!kj7Q!b_*!NZskHsUeE7B5mC?4J1^x&5TEvm6cr z17<@{rrZm>EB6L*E{sGBkea``f1TrISlF~Ij3v)Gm*4nN<+x2{p6b{{x`oQD+KG^! zYsc7OLNDCzlxVw8%sGpZTk2e#Q4arc*Q#BEl<->vg0B48Wt-B#x8LrE=lG;i7&&UX z$mq50aW)2)>rjg(4PRRNR76XkM?9%L&%7hf=I&`WpD!ciU4#W0RN+VL_S=s%R7vV9 z$SksxD7t<49&-0okdTTXO;L68nA(F_!LoL#K+W)OGaLm8(Gz*CkQ~@^8J4QRkoaj) z|B~;X``P<#1u!$poPnY*ne{Y#vKerVZ0`my(RpNH@@YM?9p>JBY>-u(YcqkV+f~R* z9r1mN5S9@PzvpKTsmCLEp|gJcp*nPkR~0#^!nCCQdyK*ym2mK0nZ}W+Z#D6EJ=n;5 zJ6Z!rMW;wrV!TgZIx?XmZz2C-EH|rBriohWgE50KJ+8f0CPR@iBW8sj##x-uOBmJkr;3evp59 z`=A82Ar114Q~8e%b>1baKA?K_s2xSn7Uh(r(^?Y7IF~loZCv^W>DfEp*2eaG*#x4fUFEZ`_8oiY4_}k7RT-TPFikKdF+#U-7=Dmse((+n=cwxLL_mJ`vVNI5L3&`rF4Fj7fC=dJB6l&wFr2^S zmE6I+JNrVkB+i5UyXvEv`9ws@gZVZBg8{*G1;yk7yp`Pzg#7>$g&$RWEzYd zov)&vWsaHYa8qJwrraA>S4BG@BS3QMC~=)R=cU=HR>T{RGg};Hhi+(A_Z-vc>X>;k z{x#8mRL!u$cw(ffRZ0D6%LVJp;*=@1LH;xcAH)s6F$g%}`{ufmig5p>_xH{3`6kv;$Jj3>(SubOuVlQ>vb;;J2h&O?+ zRBgw{@5QAgyXfAn#K?F5DB3ac?z#DxwX2fBe4E-c8UGHE6wNX@(HHv_E-MbXM4cnl zQlr$}cB=05m3|RxX(lUpgg7~;xj8mKrakzJAo^N^;mr5WzW(RxKBvySCNJ8Pf228N z-y}*o@kxKJh0VcvhLS{_LQG(6MwhwlOQQO&97$&X@V}jh`BZlrvubFdV3GlVR1hVI!!b0D2#N zJX||TX-dXgCqJ^_WgwS^d0uYg2_CDct7c8Ddgc!U=N~#h1+pT$Fy}_8WOA3anhNQA zY@ANXY^SntQmd~ytE%i&TE7l)rt$o#S<*d^@}dbj_&8r}o%z8rtIu7|97`rvKZ0%G zd4<|v+CJM$rGOjo2@!^=Texd_wS3xum4HA-rBOvY3Q-v*LvDfKi!kmGDqYvF8F z5-JPVZt0HhEv^SA8B*G1DuteM?TpRk3U@qbaYAXPd(0*`KJxUuh|-?0nnVFs zHox;l-(u%Fj`yFt!JKp+d5c@U!9MuaOR*uuCNLT+efF<4yI4WU!jdli6RlWcmL9C)y_BaSNe~Bp9^dxXi9Uk=%A(!B`oyRojoV3 zk-+(do@o5!#bckQs$OCUJCb#{1Ly8aBAg#+ZFfz4_QH9zAn#=TjyLTjh#!PD@0e8( z&qF6GMQudGtI0Y?uZ_;u&o`C9ChLO|_YdUiimG&!8>Qw8wPlgqjn~?HFCpGU#>(z69SN{6!V`O;$4!Np}RYrAglK|0!pQ*Xjkh{+= zTxjt_=c?7CMG+kG(b;$DFw-t}q84tW9o^q;((K{t1<8I+>3y69b+#?K$9(s?6n}ep z{dSHXJpszKg^yDB0?=CRM4#@IkUp+`qdAaZ zrRIjaL!px6v$swl5jMtt`H&yGQDA|&eDz1F&c~=QL#_}}jV(SPXt*y%bl)S83ifTV zmagKZ3J6Obf@?UF+H_V{ALex>+pX+HuoW}+h~q!j2S#m`T?{^;9c&W^Q7pS0*N)9Is< z!gRrPqfStIscCz$q6qt41~s_&eC%C>^p#YrFSo=A7P7O|p2*8q$3;ocDjPc0>pwek z-ZVc=#Q1y%bFBC7xF+k_L$C!*NdK|?>5oc|4#1&ur3wVQPVUvS-@>k<4kK1(iAFTs zYplAhRp)UhBicMlt#0wF;eb`+Q30EQ*=L~~4C(IG+LKPTPpv$^A6E<2Yk9P9&fIC# zkI2YXDb?rW&3y8?PvrD-#jxweQC5{(X0v+8Mk_>P7wRyfJg5_QhNl;|}7)(4%<)b+9M{8@<;Pt?jukSvT@ zb#?EYePt@$tmK|BUYXxPf8nw4Q}bwrURbQEi7a}IS#fg4=+L{Kv%4s6oPDbJW1d|s z@@u?;_3=dA{$OMy(<9n9wZ!~>%2LLh{XWF?=b3jNP3lN`(M$8i^Frn0{a>y=_ThCf zE_r9?I)C@;87YmSRHlfHU6c5dkMdD1op_SPM-VbcL$TW%bA;a@8n zTV>@V{4TM%)+Bt@*ky9p##TxZ=1j1PkKrjC7hB`6GbX~R@LgV|7Wi3QVueM@ut~DD+8Y` zk?h!as6AwHh1jv|nCfS^?T1prB**G5&Bpm|Cm)+FPEYI)LnND=Cy&`f>GhxjdB2Jk zplXg1#YdLqV{RDV_yA40QHu$KvqYOKY%6wR!i=jdQT$-k0>7 z^skb?8EI;|3Z>1RFH4f{GfR-e>2rVgizba2erk|A8YxFl=Xyv<6lY$T@;s$ZAx(7O zESYRW;`sc9y$@}V^?1-yklZG0w6XA1zCd&+uvLmD%Xgm6%c9WAlid+z#bvVFRd$b8 zau(gT{h2g;(+Tzb`S$$-qB*%EYP$2pFgwf9(|0pXJWrDy?#ZE6oC+16_%N@@Kat7S ze_1$Jl~VZ#eb7`Akz#S^yap^&XjGJkw@+6_r=v?YKt$W((VLTBdjiYc+h`(>hkO}4 z_EmekVonv(uXME3j}>;kO(DyLC~-Kfg5=vMQIBoW^Dm5-05f4b&9ULSUpuZV5gb6rme+Z=`yzM}coA>r~- zm)2IBl=vebkvxm~22H&(Tz6V(&ywyO;D`&KjA)Emu(Bf9M<4StbNEX(Z+U>?9G`F~ zSHMK;H8fL$|YcpaC-zpri7JyYwUbD!7OlI}oL zGcy}pmI}RkQo#2%6Kc89?R3Z4Mu#uhX<>F&T1uaju0P6%@r=Ah5!;|4J?VEp*j|)g zu6`0-V|6OKjwbKbm+ouH*wTv}!iDz@1w2ROY^sjLG^g0kg}zGG7f_#>VpH=G&WQU) zLq|(QEb+t(@uukgk%0cAyDJ?C-zF4R9TW^bOhJnwjIC7da6FU$o->s9KCrfwStDE; zDOwpStRGl>G=><0UAQsAX**>^+&*cy_g@JbcB)Ry%lQ7_`k;5Q`lOuCe%S25I~ok` z6&1$IXGl%`$iQ(EnM1zk>33RhC&`!j@ro?^j@7643D&4$O1H5KV)MyrBKZ{u)V!`b z@x_wRR0+Pg_hbQ=)N=J)9V>7byJkr)!dNRiQVdSVr#J11eom#!O>EG2>8(tLc7840 z;Maneqbg$)x;c5#Q>wL?qd|7BA|$o-dMzFX2?ocs^>?T^81t3f8^q8nC6+OH&2-M` zp6I`UK%#a9rE2HX9Kb)ZdUHF>y@dmd^+XlMNF%%@+0%m z#FyOG^4LYzsvtA(6gLfF7(Lfl&kM=A;iLifL5X|CR5a;kML&J&z88>hq(fi!vdYho zE;ng-u;a>%mqjuh$g=GrrTLjVB)hZ4tLw0Z^$8Y|ugRkY5AUm*%nI7us3+-4(~@Pw zooLX0(StU%Ceu9OH(IYj3hQk-*-JHhX z@j5MTceltzPb*nxsUytt$9lFYY09K};#fR!@iN1)xvB)_LrQIA##Y;AYd*V)+}a!c z$=|N%vM+2eUx-^lmoIbYknP!HwlHJ2Y3hccI?Gr0*=#sn+~}Hv$?6aVqjX|P zZ+8~V`#vomshU9!d6Y&>oXBEvk2EwBH+l99YkYQ~)xh-Og5=xSYG2viBZ@JTnruNP zE^yv2r~M{AH9ro)AdGujB@szC#77dUnklo{c5V%PYgO}gid4^zqo_MLKB>Q>YQX_Y z(fNJbW%Yfh)%U@S`K+SQW3F`6xRK}ElVd(mN0iul?SE{)^^xcV3Ctpy|Ef-|bGd&_ zOOL$b{&x3$6<643`V-CGB&iYEbjmu^@LHq7(^M@^^STDwgYw%LZo zH)d4aPpVR==p)uAZq*RGcR~VQf4=`Jd+Rr+;{_(&W1bPU@&z4V9R&mqlqN}4H$=|} z;O4WkVp>NdX-ZuzF)P4b8Zhwn1myT>Ku~ z@%;l|{CYZ=KaIhyE$@ZUA46f<Z7MP2kiI3 zn^kUOM$##+kk@tAikvgOMCT*=eQWM(Ujn{_^GDv+rfA9NX`1!-@_g-!I__OOGF4qo z6HBXryU|ij6Fv|xS{+jHY_?t}Q){nzq;>U_-?=XJ49$8EA5kX}E(VXiDZ=E1_Ih9Z zt;2(;GvhN!0?w-}0vIH&Gx|DAg;d$YjyiraO6}l@#GUAhovkfok7@&G?%NQ3R=>Jm zxy9FmY$xrA+@~50VLc(+L*qgM-BBSIk73J+S1GSjtNK!y{m%;~wy2Hmo;U+SgU`1e zi-YYdVh9{Nz1_KxAC#&z$*4$uGm3T3Wa9Rfs8jbO&#T#eWDD&*vfEm(@?rFYUE_DT z_Zs7x6)G2!erG&6PGp}n)1H!U*c|`3(8Z3;;JT94+{$e%Ui^LGi?eElg zNPf=1mIllmtbDfQD@$sWB7Z~j9L!_>UHop3TGw3ts3UtCG8#ma6@*{(VM7fUrrqr3 zlO6@j*eTsR<`!0>h)yq<$#ftyHE3#1=hp2J&>S;|i}8a4kzIIwL0%t21TwiAT7?x# z^)U>t4cZL^^|A@731W@DDqXPIvCq-NmX(+4B94bV5EJmaGu=&ToyM>SXI(;H&|9l? z81rM)6?W}##gDwZMs~u%t~FF*XiS-?%L&+?cMS&_8C;WmO?_hqAJ(#aiqorR?dmgo z8eY29IpX#8#`&B4BGwV5{o;oxl~`n9B#&e{fEo{3@N$oQBa)suTiYjeyE52(*8B4l z>X-#3_jfz4GcJ}fXm9s0sU@LUEJaJSpby>f2U%2))4K1mgzAEXB#L9{X;mcg?{dy5 zXXjWRZIN-v%F&7BRJQZ)F{*t>@$T;Sbf*FPS(O8*if3Au>cm&u8$;;jwVmZthPO@2cNbCi=mUk35TvJ9MbD8%yml8 ze86=w_2>&Z(K&6Ho9lomp}GG3+=GfoVDt*P>HPk}Dd(sfL=;#HE`5^S^RVZ@Q}}rc z`s|h|!Dqwv0yGW_pN|!XB_O(#*^1|-J6Kv;WU!@FrjJiM^nB`&DSFS9`cR_odM(F` zP@}}#Mv3kd_w~c23358pTD+74FGNXUj-;{fk8f?T!ZbzZr&<>b!)Ko`y$XM1YO%=1 zMP3Wr`dqcr=X1V4hA554=HB^nFz(UGFz13$ zt3I}BL2nLq?A}+mN}sBUPI+X%j8b8DcbJc&zUMWBDjurL8yC28`IyjmUw1}{2ivl( zlM5D`7c``Y-$%Xsl*JrtCqK`}ZWYgw|D)ig>FMtwmp-IzFWl}vM-F@B-ftT^J+P-hre8Vx;0J;YL+@>De_UFopNZW$46$3u-PT+Q-5Pue~<+f0+E%dWz(1 zqe21wQ45lx{fK=YNh6koWQV8a4$sVF3WR&PO7|s5)J5%(@)mLv;G$O`5~-I9DBC6@ zSTtxgV)RzBxQR004$`+|tkGeQWMfpC(>~d;Z^tv9#vaC``b^L@5ZSauqy)%J-bt4y zVB9tGB{@h%eqdg7=Ee*Q*+gY)a(;QRvHMrij|2G)F%wn7IZX!yO)nkFO;*X^CF6EJ z8!d3|$F_jew)yJc6)u)4BMUkts(TLkRRmG;0!6=e*mvt0md|bSe!KE!(G?4F0^!m2 zDXgEyC}zmfu@4iny*|Xu0rEpmhtVcAAfhMzB}{I3X5KL6@7#ItM?n1Hm(qxi3u$*O zlW#80wlSQ2`?Y(rT`z3gL%&NCg68@4i}@+o({)PH3wuNl!I_=DO}R5sQS79UY--@% zesuiCm40TA@A(M~Io~v|+}|oal6}9j$rzS*lCSsMcJoJ@O zbv~qUsbw)q(4DeyOHU;V+`Y1##63(Me$THB!omQVQU5Yc`*<>ghF1x3zI9J89~k%+ zaYYB|Y|gG+SvVx<&$6ejJjk6#RyOp3vqj!+#N>~q()K6mDK{*1J2{pKZLx-Gt| zS2d-AKEK@lv1}Bz!>-7i#PtGCdnQfJ+K#`rfW4o>DF@evp6ha)*^9KYlSecgx?O1U zF4EK$?tA&D9L-)c&Y~1^x2sd?ys^B>RbAFl+x_9)KT_1EiOQ00_YoWu&QK+-f78uC zUYI*HAoI?pJF1aj=MI_AeqpY=Jp3qSy9cs5$O|8^*1?pNd~Z^6#tP*QHYv%Gd@3C2 zC<8-aj=jYl34GrkO5f#fln-;+9oH5wqFrGq-I2<$8)vPDX*4+X%-F;?rs|nCVlI(x zT;saE9PWP=l&5s}K+%s_oUN2xo9?dYD82C)-ZvId)yIgae zU-DQB&LL(i@fGb$eTy)g5#cb-9JekBhYvOVhiM**+daMM<9g|Gwp>_cm}85SvCZ(^ zf@EalO=AY}gQf%v6JC-~R5{{4`>+H%(Gm@7&3p&@@p1a*V?)-1?u@XY%$X*B7t|9| zL~)oMa{47jEr;L8z^D91e}sOEXZP$ll~R3`^MO}quW{-qeiRHk*Y%>ac9Bplb3hWN zYHzIJ*mrYQEt+k7!fS>(z??p9Qoi3(KBZq*N+5(Yj+27gf_&_Xoe8w@X#ZgbzW3TB zy+PvyA+mJ)Yg5Y((De!=0DB11y@O=(EbV^Cf`W<22Od?@M_YCjmPu|w&OcHO36j!WqKEaQ`wxC4D(-bAj1Hs5Q@uwTLlLA^o8`MY-(~JieyM8SYHk5Op zqC8ME+s5`)#@>F9xeBuW6ugpdNYK>$`%YiSb7x-*&Ci4~$#(y(h1yFzmo_lcns z?X%ho9!m7YCMu`c?%hgUVHhNw;VCLSxdXB`B!KVv)&N9zh-bVS66H2i+3VMYq+wJ`mLR56PM-mDT&4 zWFfvIm-gMA{=;!a^jX_!oWu7|htd~Qx?HIo z2DT&+gd*fJ^N!adw6q!tM+)B^OUb@FKckfuNNMkJF_Ffk~(BRZr$C$YI*w$TgbXd3TK7$L)C4RVbrV^fty+Ka4hkTK0nlp}ND4)a2rLnd>jN`m|rPU?}8o zyrcxno;dIbVPPqS`Y%XD+fT3=Z3)7ojT#@4?1v~d$w zIRX{VH1a5|)V!&d?-40)dqFxu-EaVEsdoI6$mIEXH{#93=JxojbFcovmd?I zg)+b%b;Wt^GUFrRArZVHLR0Uins?kH`W^}4$vxT$eH0kx{R2!?Rw#mcaPu3ll3k9H zNIR-jPas0|;8BOE^0cVd9djV`?w2~H#6QEvx*00YYBcf#3y_HGO33Z4>~5<6{P~OY z;!U9W4?1)$tY>G!!dUBQkM>*X>|IRGo*RAxl8df{9w8LozzZUxt5S8g4`Hke=>`!v zHS`XK90g&H{LJH20^7vMJq?v|6Ql;}3v713%wlCK#X*YBF1cm+YW zXA4EJ&3z3<^i(n>EJN#r-efajMudO9f5>|SXJhwyh7RK1?W9+0wkh;5$2RcKZqL}K zGkQ9_A`up4aj(8V*yU=wMXA}l#)ndS_#A`dgBAk5NUF1GbhN)JiX-?E5;e8IkMdqu zQNU>sSZ*Bow$~-ZopdX8P&Qz0JulyGbo$^dW$O^wVdC`R)A7 z;oc;>m8Z@(;LagkqRkhbnQJmMTrd_64qi`Vs*_dZ_^6&B$UhwGuQ+_q)X=p@8idXX zR0=2SPwLkB6sK1?s8$1tVXjqhik7M0=|OEqp>CTK)S&3eABb>x%c|a zKEG!Ub<3moP^x09Q^nCwUVGDWgL$huLO`CXA)KGRP36KvKnNh`p#vo{Wu7t zHtv|c&sy;; zy-F$Id3}53!rN+E$CGk(!UMMoLT_5@?x~Y|M0`V0$=5^yX&~6PXqKd*nLb?o1Ldt{ zAqUN{l%HtE&{BQH$$mV-shrN6vPRS@7oHtg&ZZyP*g zl_WA6NBM~OyRCDY6u3w9Fp9@9(p61ph=y|^Vvo0qC}BJz!#GY( zBQZpH4;@*3nri-t5|4819>IDP0m!Jr&h?BwQnKJmG-8}O--kKef2L0>m*%{^W&hDT zGE;(PABxMn&bWQ2gb9td?%U@&+6tRXOTW#Z&H~5C*?lNgXzcj5ectLw%rr1noSX%3 zWS#}P#P^3?tC3L|bE2~trbtZ|>QZK9kI_7HHS^PZ6sQGib7%AWdRzAg95%HuW77TN zf>wAi6c>VPs`?8ma#NTnqPgy*R@v~xjL4I9pv3IVAy>^=O&9&}w=-8VNtG4G>WAza zgbm-RCaIZcU`hGVKGt?@1j=cj-e(dBCtq$CjjeUw7CY;GdGY40Lp={e{1H=6BVkRW zB6EEpJ-}r*?6B?5#BOPOyLr*Y24_21yZVBi-SqSARftEC=T*+=%#^ukjEzeG{3lec z)|A%yh12z*!mDSBHd0ZxEa8oTW)wxOK{b{ww8xtXR2y~FUgq3ZSIm&^ON7&m??cC` zPL|hdB9e=8BoeE%)amS-$6B}k$dd`+dD1_UV)1NJHEl=9177~~3_!dc$ZH4BlzTiB z{>EQ{%kp~rrO4pon1S3|`>*>E4VTnaN{7u$G^dK97jUX&A7aMjv@~*0rhGwHh$Pgz zk)9(opJxlRzLk^O-FLIROKU{e{7PHcL6;l!T3!f_kSE4x{ZFWwAl*L%bboK1>JTp% z^ft9-b(lzbJzhVeZIzr=v!8Z{rH3&W+m>gxA%q!eZUssWIpz}_V`D=a9D~zUjlurM zs1AqWGXX~DCu1Ltr=NSO$gCLWMNrStO;1{A5B^UNR}3&oH_H?X%+87>>4N)_-IKL% z`$**sDo;8S>uzCkomu=CdAnj%b9&pe&$x`r!nWJnbFW;mpO}t**YZ+zqC}IfD+HcT zdeF5@JG0U)-Y-M0uP$hS#Uf;%GFOtnXTSFq+pOC3yzw#B}`QuIzBr z+rYgku(xeQqJt^vB%1jra#B;j#;HVETFPrU=q1&~m`@b%4U&o(lV}jsu2l&1BIgL zr`bSeegKQsGV(sCP8S62>4U%DbKU7SqZI94Gp8gBa)PQWyw6HBp9u z$+|*I4XYMTJjo3kymk@rA+?lyU70RS<0!vgA z+|A|a36xkR1B5e54m6Gra?hSXw9!8Usy60Ye~vg}0WhnyJ}^7~ThHD}i6i1x+h8oA z4x#<Bk$VwyA4m8QiFGw&1JL9-nA`&br?;+f5^cKx-DK_AgP@B;}{YdCMmHM7ID&S_st>Ps<4Zo#?nM>qD zIJev0S#Ivwnb=wWPpSLSCPMX0G~=ojC}ceC(o@h9Cym0_W zJZ>^jCo^C^Dbry&@_{UnbSEsexEQ0-#R|&X?L)Z97eu ziH?N@ru6CXSPW1OF=u^WP4(F`S}iR8^a}nF3(gLDJo4Jy)AvKjc`mmye z;|m5eSN6yb4Ds&5iNWi4y$5w5`x(x^de-8l(vYEoV|js{4lw3Ai{bqa3YgT~=OjQ7 zZqWXgnxK}z)ZI?Por@k3z9Zv-gq-L*x7hb%$1z{C&&V3l5c-*rAeM`6X?{1?|w9@n{!F_?b^RSLXDNoIA(f5SUe|nPu5TapJA~ z*%=TMLw3Zrn8P=tg~&I?D!j+CE)=vxq@hs8;a~1vRTAh z#xV0K&6qn4o?0f`4MvVF+8;lCZB(f^FfmH8ftI$zIIUrEVdjXKzN{R*M=Ij!g6ZsK!o zRs~FOtHJQAVU^gSggzpkGtT7{ai0~gMS3gI?`k+bZ%aPyZ2VYBuVM<9n!Ct>Dwv`! zd;a-$xz!-Je)e?KhslPVKg*xd?zhnBxvNTZH_hG2=gIM``q(u^SgO&F4VM}j@#ePW`$9!F$7qZHByoIAPlc)GX4TS2G`?h$YS0^ZD%&`EMy|CzxogK5y^HzB)WiMJY7X5N^M%Db;w3f;#{9 z-YP{E1uNZLPoqRfgTg0gD!5~2!>B9`GnoYyYts!THC zD_6;4C*5>dCq2wn%$_rtZ@(rGE`Vd=qu(=;GUt9LR#1*eeIhhp4zVX4sbi?#^!+jl9BnZ_zEJAsMjm<%FR#4fXo_8I5BaJK%}*VWkL zA0suJiTZ8gj@Ts`r=HZkb0A~>kylRF!~ECpEA^6&>jvyiN!B#-R*6K^E5s_awa_7o zNhG4<8bqP;X-gqq10wSyL?JsAq-E=6C;hpS8eVFN9@;wWlzDuT1A63g;uWM~-srj9 z{o@)ooyAs-`)aRh#wmNdr|a-O43=B$DOVI^R5!6SYu5HTrqZcs_>Hs-^XX{+%{vRX zb5gB>`lp|BM)KA?EK@B*H_IuRNxA}2W>8D+j=%d{Ms*|!RME}n-e?6mMA)Zym=J^9 z=%xsI3)qVV!44DXW@v1W!9oNgVF4WYVT`Z%i=xmdif-~x{_fM68p)#-th#Bs?EL_B zMnv3)8(Q=U^Fo=Q7Rn&u=wRYY?fO>dYmoJg{-W02?0mC!-D$?Il!~1e ze5%Ob-u@7ERVD3=iYs_WrY=#_6>}8PtSlrK@wyLN*ux%R2Hhv-8j=G(eeFJIeWhMu zJaOMtgUGANq~oAu$ni@S8`nXnxi({kQUTAC4r~W_+&C8N+z06v=XBaDUaE~|?>qbm z?8&+}Nh-KJC=w;`ye6jhRk(w?mLHt?cIE;}&-n#gdV<{w1K@7tHBut`-9YIP(aVxR zW6QU8zO@Vcn74g#`(Pc~`8uQCiu-u&1$Do?%7+w+6$mH620H#zdIIL5?F z_j}MeGnx9eYc7>S`*M7`Ca>Oehpnb>=3f+5<6rzT5@jj6 zXH%+2TBDN+CIx5ySY(R%-3TSaOlRXccs)qSEBOS9arGiIltm9&&rG}tc7E96Kifiw zov`h^b^7oRrVIQ-3|r1^7Z$&x2f+GQ%Eu(+wT?fAJDO7LA08@6+?GH2=J2@_s#$b}b5@Px2M7;{?gW*stW1L-lcS1|2L!Dh8(#8qVtt zQD*oGL^aWYfjE7xm@>r}DwnGeH+Qh4l5u|o&Ei|Br4;_(@4w4|dG~>fm-^YHP@lnn Q{|b|mlslCyu6O1C04M|j*#H0l literal 0 HcmV?d00001 diff --git a/workflows/SDXL_pixelart_preserve_aspect_ratio.png b/workflows/SDXL_pixelart_preserve_aspect_ratio.png new file mode 100644 index 0000000000000000000000000000000000000000..35603681315443a66ea40d39285bf3ffcfbfdc3e GIT binary patch literal 22137 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